Skip to content

Instantly share code, notes, and snippets.

@orodio
Created December 29, 2015 06:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orodio/d55fabd7eacdc5c1286f to your computer and use it in GitHub Desktop.
Save orodio/d55fabd7eacdc5c1286f to your computer and use it in GitHub Desktop.
playing around with some monads and canvas
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