scala-js/scala-js-dom

Unclear how to use FrameRequestCallback

mseddon opened this issue · 3 comments

I would like to invoke dom.requestAnimationFrame. The FrameRequestCallback is a trait that has no provided implicit conversions from a Function1 to an appropriate type.

// Attempt 1
val callback: (js.Number) => Unit = (time: js.Number) => { ... }
dom.requestAnimationFrame(callback) // fails at compile time because (js.Number) => Unit is not a FrameRequestCallback.

// Attempt 2
object callback extends FrameRequestCallback {
  override def apply(time: js.Number) { ... }
}   
dom.requestAnimationFrame(callback) // fails at runtime because the callback is not a function.

I can't find any code that uses this trait- how is it supposed to be done?

I've implemented a stupid hack that got it to work in a slightly less horrible fashion:

implicit def frameRequestCallback(fn: Function1[js.Number, Unit]): FrameRequestCallback = {
  val frc: js.Function1[js.Number, Unit] = fn
  frc.asInstanceOf[FrameRequestCallback]
}

// now we can at least conveniently call this function.
def callback(time: js.Number): Unit = { ... }
requestAnimationFrame(callback _)
sjrd commented

You did the "right" thing. FrameRequestCallback should definitely not be a trait, but an alias to js.Function1[js.Number, Unit] (probably even js.Function1[js.Number, Any]. Or, since it is used exactly once, I would even put js.Function1[js.Number, Any] directly as the type of the argument to requestAnimationFrame().

PR welcome!

sjrd commented

Fixed in #27.