Skip to content

Instantly share code, notes, and snippets.

@caasi
Last active February 25, 2020 17:25
Show Gist options
  • Save caasi/397113dd18dd82bfe36e311b499a6828 to your computer and use it in GitHub Desktop.
Save caasi/397113dd18dd82bfe36e311b499a6828 to your computer and use it in GitHub Desktop.
Play with ReasonML
open Webapi.Dom;
open Webapi.Canvas;
open HtmlImageElement;
module MyCanvas2d = {
include Canvas2d;
[@bs.send.pipe : Canvas2d.t] external drawImage : (HtmlImageElement.t, float, float) => unit = "drawImage";
}
let useImageData = url => {
let (imageData, setImageData) = React.useState(() => Js.Nullable.undefined);
React.useEffect1(() => {
let imageData = Js.Nullable.toOption(imageData);
switch (imageData) {
| Some(_) => None;
| None => {
let img = HtmlImageElement.make();
img -> setCrossOrigin(Some("anonymous"))
img -> setSrc(url);
let rec f = (_) => {
let canvas = document |> Document.createElement("canvas");
let width = img |> width;
let height = img |> height;
canvas -> CanvasElement.setWidth(width);
canvas -> CanvasElement.setHeight(height);
let ctx = CanvasElement.getContext2d(canvas);
ctx |> MyCanvas2d.drawImage(img, 0.0, 0.0);
let imageData = ctx -> MyCanvas2d.getImageData(
~sx=0.0,
~sy=0.0,
~sw=Js.Int.toFloat(width),
~sh=Js.Int.toFloat(height)
);
setImageData((_) => Js.Nullable.return(imageData));
img |> removeLoadEventListener(f);
}
img |> addLoadEventListener(f);
Some(() => {
img |> removeLoadEventListener(f);
});
}
}
}, [|url|]);
imageData;
};
[@react.component]
let make = () => {
let imageData = useImageData("https://farm8.staticflickr.com/7166/6595168855_5566d615d9_b.jpg");
let style = ReactDOMRe.Style.make(~width="100%", ());
<ImageDataCanvas style imageData />
};
open Webapi.Dom;
open Webapi.Canvas;
[@react.component]
let make = (~style, ~imageData: Js.Nullable.t(Image.t)) => {
let imageData = Js.Nullable.toOption(imageData);
let width = switch (imageData) {
| Some(imageData) => imageData |> Image.width;
| None => 0.0;
}
let height = switch (imageData) {
| Some(imageData) => imageData |> Image.height;
| None => 0.0;
}
let ref = React.useCallback1(
(node: Js.Nullable.t(Dom.element)) => {
let node = Js.Nullable.toOption(node);
switch (node, imageData) {
| (Some(node), Some(imageData)) => {
let ctx = CanvasElement.getContext2d(node);
ctx -> Canvas2d.putImageData(
~imageData=imageData,
~dx=0.0,
~dy=0.0,
~dirtyX=0.0,
~dirtyY=0.0,
~dirtyWidth=width,
~dirtyHeight=height,
(),
);
}
| (_, _) => ()
};
},
[|imageData|],
);
<canvas
style
ref={ReactDOMRe.Ref.callbackDomRef(ref)}
role="img"
width={Js.Float.toString(width)}
height={Js.Float.toString(height)}
/>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment