Created
December 29, 2015 06:44
-
-
Save orodio/d55fabd7eacdc5c1286f to your computer and use it in GitHub Desktop.
playing around with some monads and canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var $ = document.querySelector.bind(document) | |
var createRenderer = register => data => data.reduce((acc, datum) => { | |
var { type } = datum | |
if (type == null || register[type] == null) return acc | |
return [ ...acc, register[type](datum) ] | |
}, []) | |
function Just (value) { | |
if (!isJust(this)) return new Just(value) | |
this.value = value | |
} | |
function Nope (value, code, description) { | |
if (!isNope(this)) return new Nope(value, code, description) | |
console.error(`Error: [${ code }] ${ description }`) | |
this.value = value | |
this.code = code | |
this.description = description | |
} | |
var isJust = thing => thing instanceof Just | |
var isNope = thing => thing instanceof Nope | |
var isMaybe = thing => isNope(thing) || isJust(thing) | |
var pipe = (seed, ...fns) => { | |
if (fns == null || !fns.length) return seed | |
if (seed instanceof Nope) return seed | |
if (seed instanceof Just) seed = seed.value | |
var [ fn, ...fns ] = fns; | |
return pipe(fn(seed, seed), ...fns) | |
} | |
var initCanvas = (selector, zoom=1) => { | |
var node, ctx, _width, _height | |
node = $(selector) | |
if (node == null) return Nope( | |
{ node, ctx, zoom, _width, _height }, | |
"NO_NODE", | |
`No node found with a selector of \`${ selector }\`` | |
) | |
ctx = node.getContext("2d") | |
if (ctx == null) return Nope( | |
{ node, ctx, zoom, _width, _height }, | |
"NO_CONTEXT", | |
`Browser probably doesnt support canvas stuff` | |
) | |
_width = node.width | |
_height = node.height | |
return Just({ ctx, node, zoom, _width, _height }) | |
} | |
var defaults = (seed, { ctx, zoom }) => { | |
ctx.lineCap = "round" | |
ctx.lineJoin = "round" | |
ctx.lineWidth = (1 * zoom) | |
ctx.strokeStyle = "black" | |
return Just({ ...seed, ctx }) | |
} | |
var setZoom = zoom => seed => ({...seed, zoom }) | |
var drawLine = data => (seed, { ctx, zoom }) => { | |
var { x1, y1, x2, y2, thickness, color } = data; | |
if (x1 == null) return Nope(seed, "NO_X1", "no x1 was passed in to our line") | |
ctx.save() | |
ctx.beginPath() | |
if (color) ctx.strokeStyle = color | |
if (thickness) ctx.lineWidth = (thickness * zoom) | |
ctx.moveTo( (x1*zoom), (y1*zoom) ) | |
ctx.lineTo( (x2*zoom), (y2*zoom) ) | |
ctx.stroke() | |
ctx.restore() | |
return Just({ ...seed, ctx }) | |
} | |
var render = createRenderer({ | |
"line": drawLine | |
}) | |
var renderCanvas = (selector, data, zoom=1) => { | |
pipe( | |
initCanvas(selector), | |
defaults, | |
setZoom(zoom), | |
...render(data) | |
) | |
} | |
var data = [ | |
{ type: "line", x1:45, y1:45, x2:95, y2:95, color:"tomato", thickness:5 }, | |
{ type: "line", x1:95, y1:95, x2:140, y2:45, color:"purple", thickness:15 } | |
] | |
renderCanvas("#bob", data, zoom=1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment