open Webapi.Dom; open Webapi.Canvas.Canvas2d; open Webapi.Canvas.CanvasElement; type position = (float, float); type shape('s, 'a) = { state: 's, reducer: ('a, 's) => 's, render: (shape('s, 'a)) => unit }; let getPositionByCenterOfMass = (~r: float, pos: position): position => { let (x, y) = pos; (x +. r, y +. r); }; type state = { position, radius: float, }; type action = | Move(position); let makeShape = (~pos, ~r, ctx: t) => { state: { position: pos, radius: r, }, reducer: (action, state) => switch (action) { | Move(position) => ({ ...state, position }) }, render: (self) => { let (x, y) = getPositionByCenterOfMass(~r=self.state.radius, self.state.position); beginPath(ctx); arc( ~x, ~y, ~r=self.state.radius, ~startAngle=0.0, ~endAngle=Js.Math._PI *. 2.0, ~anticw=false, ctx, ); fill(ctx); } }; let main = () => { let canvas = switch (Document.getElementById("app", document)) { | Some(element) => element | None => failwith("canvas not found") }; let ctx = getContext2d(canvas); let player = makeShape(~pos=(0.0, 0.0), ~r=10.0, ctx); player.render(player); }; main();