Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

一定時間ホバーするとイベントがトリガーする仕組みをLaminarで実装する

実装する必要があったので、一定時間特定の要素にマウスホバーするとイベントをトリガする処理をLaminarで実装してみた。思っていたよりも直感的に書けた。

LaminarとはScalaJSのフロントエンドライブラリ。かなりざっくり言うとReactやVueの仲間といったところ。

laminar.dev

import com.raquo.laminar.api.L.{*, given}

// ステートマシンの状態
enum DelayState:
  case Initial
  case Waiting

// ステートマシン(Varは状態を持てるEventBus)
val delayStateVar: Var[DelayState] = Var(DelayState.Initial)
// マウスホバーイベントを受信するイベントバス
val enterHandler: EventBus[dom.MouseEvent] = EventBus[dom.MouseEvent]()
// ホバーした場合は1秒後にタイムアウトイベントを発出できるようにする
val enterTimeoutHandler = enterHandler.events.flatMap { _ =>
  EventStream.fromValue((), emitOnce = true).delay(1000)
}

def timeButton: HtmlElement = {
  div(
    // イベントハンドリングもここに書く
    onMouseEnter --> enterHandler,
    // マウスが出ていった場合はステートマシンをリセットする
    onMouseLeave --> { _ => delayStateVar.set(DelayState.Initial) },

    // 事前に定義したEventBusの配線もここで書ける
    // マウスがホバーした時にステートマシンをタイムアウト待ちにセットする
    enterHandler --> { _ => delayStateVar.set(DelayState.Waiting) },
    enterTimeoutHandler --> { _ =>
      if (delayStateVar.now() == DelayState.Waiting) {
        delayStateVar.set(DelayState.Initial)
        // ここに一定時間ホバーした時に起動する処理を書く
      }
    }
  )
}

Laminarがデータフロー処理のために使っているAirstreamというライブラリの便利なところがよく出ている。イベントが流れるためのEventBusにobserverをひっつけていくだけで処理が書ける。

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?