type document // abstract type for a document object type rect = { x: int, y: int, left: int, right: int, top: int, bottom: int, width: int, height: int, } type context = { mutable lineCap: [#butt | #round | #square], mutable lineJoin: [#bevel | #round | #miter], mutable direction: [#ltr | #rtl | #inherit], mutable textAlign: string, /* "left" | "right" | "center" | "start" | "end" */ mutable globalCompositeOperation: string, // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation // source-over ; source-in ; source-out ; source-atop ; destination-over ; // destination-in ; destination-out ; destination-atop ; lighter ; copy ; // xor ; multiply ; screen ; overlay ; darken ; lighten ; color-dodge ; // color-burn ; hard-light ; soft-light ; difference ; exclusion ; hue ; // saturation ; color ; luminosity } @val external doc: document = "document" @val external window: Dom.element = "window" @send external getElementById: (document, string) => Dom.element = "getElementById" @send external getContext: (Dom.element, string) => context = "getContext" @send external createElement: (document, string) => Dom.element = "createElement" @send external querySelector: (document, string) => Dom.element = "querySelector" @send external getAttribute: (Dom.element, string) => string = "getAttribute" @send external getBoundingClientRect: Dom.element => rect = "getBoundingClientRect" @send external beginPath: context => unit = "beginPath" @send external closePath: context => unit = "closePath" @send external fill: context => unit = "fill" @send external stroke: context => unit = "stroke" @send external clip: context => unit = "clip" @send external fillRect: (context, int, int, int, int) => unit = "fillRect" @send external strokeRect: (context, int, int, int, int) => unit = "strokeRect" @send external rect: (context, int, int, int, int) => unit = "rect" @send external arc: (context, float, float, float, float, float, bool) => unit = "arc" @send external arcTo: (context, float, float, float, float, float) => unit = "arcTo" @send external fillText: (context, string, int, int) => unit = "fillText" @send external quadraticCurveTo: (context, int, int, int, int) => unit = "quadraticCurveTo" @send external ellipse: (context, int, int, int, int, float, float, float) => unit = "ellipse" @send external moveTo: (context, int, int) => unit = "moveTo" @send external lineTo: (context, int, int) => unit = "lineTo" @send external translate: (context, int, int) => unit = "translate" @send external rotate: (context, float) => unit = "rotate" @send external scale: (context, float, float) => unit = "scale" @send external setTransform: (context, float, float, float, float, float, float) => unit = "setTransform" @send external setLineDash: (context, array) => unit = "setLineDash" @send external restore: context => unit = "restore" @send external save: context => unit = "save" @get external width: Dom.element => int = "width" @get external height: Dom.element => int = "height" @set external setWidth: (Dom.element, int) => unit = "width" @set external setHeight: (Dom.element, int) => unit = "height" // context styles @set external fillStyle: (context, string) => unit = "fillStyle" @set external strokeStyle: (context, string) => unit = "strokeStyle" @set external lineWidth: (context, int) => unit = "lineWidth" @set external lineDashOffset: (context, float) => unit = "lineDashOffset" @set external font: (context, string) => unit = "font" @set external filter: (context, string) => unit = "filter" @set external globalAlpha: (context, float) => unit = "globalAlpha" @set external shadowColor: (context, string) => unit = "shadowColor" @set external shadowBlur: (context, float) => unit = "shadowBlur" @set external shadowOffsetX: (context, int) => unit = "shadowOffsetX" @set external shadowOffsetY: (context, int) => unit = "shadowOffsetY" @set external imageSmoothingEnabled: (context, bool) => unit = "imageSmoothingEnabled" @set external textBaseline: (context, string) => unit = "textBaseline" /* "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" */ // window @get external innerHeight: Dom.element => int = "innerHeight" @get external innerWidth: Dom.element => int = "innerWidth" @get external scrollY: Dom.element => int = "scrollY" // Reset transformation matrix //let loadIdentity = (ctx) => { setTransform(ctx, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0) } @send external toDataURL: Dom.element => string = "toDataURL" /* Events */ type event type key_event = { keyCode: int, key: string, } /* module Mouse = { type event = { clientX: int, clientY: int, offsetX: int, offsetY: int, } } module Touch = { type event = { //identifier //target screenX: int, screenY: int, clientX: int, clientY: int, pageX: int, pageY: int, } } @send external addMouseEventListener: (Dom.element, string, Mouse.event => unit, bool) => unit = "addEventListener" @send external addTouchEventListener: (Dom.element, string, Touch.event => unit, bool) => unit = "addEventListener" */ type mouse_event = { clientX: int, clientY: int, offsetX: int, offsetY: int, } type touch_event = { //identifier //target touch_clientX: int, touch_clientY: int, screenX: int, screenY: int, pageX: int, pageY: int, } /* type event_kind = string let click : event_kind = "click" let dblclick : event_kind = "dblclick" let keydown : event_kind = "keydown" let keyup : event_kind = "keyup" let mousedown : event_kind = "mousedown" let mouseup : event_kind = "mouseup" let mousemove : event_kind = "mousemove" let touchstart : event_kind = "touchstart" let touchmove : event_kind = "touchmove" let touchend : event_kind = "touchend" let touchcancel : event_kind = "touchcancel" let resize : event_kind = "resize" let scroll : event_kind = "scroll" let load : event_kind = "load" */ /* module Event = { type t = string let click : t = "click" let dblclick : t = "dblclick" let keydown : t = "keydown" let keyup : t = "keyup" let mousedown : t = "mousedown" let mouseup : t = "mouseup" let mousemove : t = "mousemove" let touchstart : t = "touchstart" let touchmove : t = "touchmove" let touchend : t = "touchend" let touchcancel : t = "touchcancel" // https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event let resize : t = "resize" // window.innerHeight; window.innerWidth; let scroll : t = "scroll" // window.scrollY let load : t = "load" // https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API let gamepadconnected : t = "gamepadconnected" let gamepaddisconnected : t = "gamepaddisconnected" //https://github.com/chrisdavidmills/gamepad-buttons/blob/master/index.html //https://chrisdavidmills.github.io/gamepad-buttons/ // https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event } */ /* document.addEventListener("visibilitychange", function() { if (document.visibilityState === 'visible') { // 'hidden' music.play(); } else { music.pause(); } }); */ @send external addEventListener: (Dom.element, string, event => unit, bool) => unit = "addEventListener" @send external addKeyEventListener: (Dom.element, string, key_event => unit, bool) => unit = "addEventListener" @send external addMouseEventListener: (Dom.element, string, mouse_event => unit, bool) => unit = "addEventListener" @send external addTouchEventListener: (Dom.element, string, touch_event => unit, bool) => unit = "addEventListener" // https://mobiforge.com/design-development/html5-mobile-web-touch-events // https://bencentra.com/code/2014/12/05/html5-canvas-touch-events.html type request_id = int type anim_callback = unit => unit @send external requestAnimationFrame: (Dom.element, anim_callback) => request_id = "requestAnimationFrame" @send external cancelAnimationFrame: (Dom.element, request_id) => unit = "cancelAnimationFrame" /* %%raw(` var requestAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; `) %%raw(` var cancelAnimFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame; `) */ @val external requestAnimFrame: anim_callback => request_id = "requestAnimFrame" @val external cancelAnimFrame: request_id => unit = "cancelAnimFrame" type intervalID @val external setInterval: (unit => unit, int) => intervalID = "setInterval" @val external clearInterval: intervalID => unit = "clearInterval" type timeoutID type timeout_callback = unit => unit type timeout_callback_arg<'a> = 'a => unit @val external setTimeout: (timeout_callback, int) => timeoutID = "setTimeout" @val external setTimeoutArg: (timeout_callback_arg<'a>, int, 'a) => timeoutID = "setTimeout" @val external clearTimeout: timeoutID => unit = "clearTimeout" type gradient @send external createLinearGradient: (context, int, int, int, int) => gradient = "createLinearGradient" @send external createRadialGradient: (context, int, int, int, int, int, int) => gradient = "createRadialGradient" @send external addColorStop: (gradient, float, string) => unit = "addColorStop" external gradToString: gradient => string = "%identity" /* let setGradient = (ctx, gradient) => { ctx.fillStyle = gradToString(gradient) } */ type image @send external drawImage2: (context, image, int, int) => unit = "drawImage" @send external drawImage4: (context, image, int, int, int, int) => unit = "drawImage" @send external drawImage8: (context, image, int, int, int, int, int, int, int, int) => unit = "drawImage" @send external drawImage: (context, Dom.element, int, int) => unit = "drawImage" @new external newImage: unit => image = "Image" @set external setImgSrc: (image, string) => unit = "src" @set external imgOnload: (image, unit => unit) => unit = "onload" @set external window_onload: (Dom.element, unit => unit) => unit = "onload" type imgPromise = Js.Promise.t @val external createImageBitmap: (image, int, int, int, int) => imgPromise = "createImageBitmap" /* Path2D */ type path2d @new external newPath2D: string => path2d = "Path2D" @send external fillPath2D: (context, path2d) => unit = "fill" @send external strokePath2D: (context, path2d) => unit = "stroke" /* ImageData */ type imageData = { data: array, width: int, height: int, } @send external createImageData: (context, int, int) => imageData = "createImageData" @send external getImageData: (context, int, int, int, int) => imageData = "getImageData" @send external putImageData: (context, imageData, int, int) => unit = "putImageData" @send external putImageDataRect: (context, imageData, int, int, int, int, int, int) => unit = "putImageData" /* Custom */ @val external set_bg_color: string => unit = "set_bg_color"