実装する必要があったので、一定時間特定の要素にマウスホバーするとイベントをトリガする処理をLaminarで実装してみた。思っていたよりも直感的に書けた。
LaminarとはScalaJSのフロントエンドライブラリ。かなりざっくり言うとReactやVueの仲間といったところ。
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をひっつけていくだけで処理が書ける。