{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE JavaScriptFFI #-}
{-# LANGUAGE InterruptibleFFI #-}
{-# LANGUAGE DeriveDataTypeable #-}
module JavaScript.Web.AnimationFrame
( waitForAnimationFrame
, inAnimationFrame
, cancelAnimationFrame
, AnimationFrameHandle
) where
import GHCJS.Foreign.Callback
import GHCJS.Marshal.Pure
import GHCJS.Types
import Control.Exception (onException)
import Data.Typeable
newtype AnimationFrameHandle = AnimationFrameHandle JSVal
deriving (Typeable)
waitForAnimationFrame :: IO Double
waitForAnimationFrame = do
h <- js_makeAnimationFrameHandle
js_waitForAnimationFrame h `onException` js_cancelAnimationFrame h
inAnimationFrame :: OnBlocked
-> (Double -> IO ())
-> IO AnimationFrameHandle
inAnimationFrame onBlocked x = do
cb <- syncCallback1 onBlocked (x . pFromJSVal)
h <- js_makeAnimationFrameHandleCallback (jsval cb)
js_requestAnimationFrame h
return h
cancelAnimationFrame :: AnimationFrameHandle -> IO ()
cancelAnimationFrame h = js_cancelAnimationFrame h
{-# INLINE cancelAnimationFrame #-}
foreign import javascript unsafe "{ handle: null, callback: null }"
js_makeAnimationFrameHandle :: IO AnimationFrameHandle
foreign import javascript unsafe "{ handle: null, callback: $1 }"
js_makeAnimationFrameHandleCallback :: JSVal -> IO AnimationFrameHandle
foreign import javascript unsafe "h$animationFrameCancel"
js_cancelAnimationFrame :: AnimationFrameHandle -> IO ()
foreign import javascript interruptible
"$1.handle = window.requestAnimationFrame($c);"
js_waitForAnimationFrame :: AnimationFrameHandle -> IO Double
foreign import javascript unsafe "h$animationFrameRequest"
js_requestAnimationFrame :: AnimationFrameHandle -> IO ()