Skip to content

Instantly share code, notes, and snippets.

@atk
Forked from 140bytes/LICENSE.txt
Created July 15, 2011 11:15
Show Gist options
  • Save atk/1084501 to your computer and use it in GitHub Desktop.
Save atk/1084501 to your computer and use it in GitHub Desktop.
canvas tool

canvas tool

Will iterate a command array to run each command on an canvas 2d context.

Usage

fn(canvas node, commands, commandmap)

commandmap = 'beginPath0closePath0moveTo0lineTo0quadraticCurveTo0bezierCurveTo0arcTo0rect0arc0fill0fillRect0stroke0clip0fillText0strokeText0measureText0drawImage0createImageData'.split(0);

Commands can be issued either as long or short commands. Long commands are strings to be evaluated within the Canvas 2d context's scope, while short commands are arrays with the command number and the other arguments in order.

Short Command numbers:

  • 0 = beginPath
  • 1 = closePath
  • 2 = moveTo
  • 3 = lineTo
  • 4 = quadraticCurveTo
  • 5 = bezierCurveTo
  • 6 = arcTo
  • 7 = rect
  • 8 = arc
  • 9 = fill
  • 10 = fillRect
  • 11 = stroke
  • 12 = clip
  • 13 = fillText
  • 14 = strokeText
  • 15 = measureText
  • 16 = drawImage
  • 17 = createImageData

This was done so we could render the logo of the 140byt.es homepage in canvas with a script that's smaller than 140bytes :)

Nevertheless, since we wanted to use as few external data as possible, we reduced this to a tool that only executed strings in the Canvas 2d-context and rendered bezierCurves:

function(a,b,c,d){a=a.getContext('2d');for(c in b)d=b[c],eval('with(a){'+(''+d!==d?((d[2]?'bezierCurveTo(':'moveTo(')+d+')'):d)+'}')}

function(
a, // canvas node
b, // commands array
c, // command map
d, // placeholder
e // counter
){
for(
// get 2d canvas context, initialize counter
a=a.getContext('2d'), e=0;
// get next command
d=b[e++];
)
// long (string) or short (array) command?
'' + d === d ?
// string = evaluate long command in the scope of the context
eval('with(a){' + d + '}') :
// array = apply arguments to short command (get name from command map)
a[c[d[0]]].apply(a, d.slice(1))
}
function(a,b,c,d,e){for(a=a.getContext('2d'),e=0;d=b[e++];)''+d===d?eval('with(a){'+d+'}'):a[c[d[0]]].apply(a,d.slice(1))}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Alex Kloss <alexthkloss@web.de>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "canvasTool",
"description": "Tool to do about everything that's possible in canvas using a small data format",
"keywords": [
"html5",
"canvas",
"2d",
"drawing"
]
}
<!DOCTYPE html>
<title>Foo</title>
<canvas id="ret"></canvas>
<div>Expected result: a red triangle</div>
<script>
// write a small example that shows off the API for your example
// and tests it in one fell swoop.
var myFunction = function(a,b,c,d,e){for(a=a.getContext('2d'),e=0;d=b[e++];)''+d===d?eval('with(a){'+d+'}'):a[c[d[0]]].apply(a,d.slice(1))},
commandmap = 'beginPath0closePath0moveTo0lineTo0quadraticCurveTo0bezierCurveTo0arcTo0rect0arc0fill0fillRect0stroke0clip0fillText0strokeText0measureText0drawImage0createImageData'.split(0),
testdata = ['canvas.width=canvas.height=150;fillStyle="#f00"',[0],[3,100,10],[3,0,100],[3,15,15],[1],[9]];
myFunction(document.getElementById('test'), testdata, commandmap);
</script>
<div>Expected Result: white on black 140byt.es logo</div>
<canvas id="logocanvas"></canvas>
<script>
var Canvas = document.getElementById('logocanvas'),
logo=['canvas.width=200;canvas.height=32',[6,10],[8,10,11,10,11,16],[11,18,11,19,11,20],[23,10],[23,10.6,23,11.4,23,12],[23,18,33,18,33,12],[33,10],[33,12,33,18,33,20],[50,10],[43.6,10,43.6,20,50,20],[56.4,20,56.4,10,50,10],[67,6],[67,8,67,12,67,15],[67,22,77,22,77,15],[77,12,74,10,72,10],[69,10,68,10,67,10],[89,10],[89,11,89,12,89,13],[89,23,101,23,101,13],[101,13,101,12,101,10],[95,21],[95,22,95,23,95,26],[113,6],[113,8,113,10,113,12],[112.8,19.6,115,20.4,120,20],[115,10],[116,10,118,10,120,10],[132,20],[132,20,132,20,132,20],[154,14],[153,8,145,8,144,14],[144,21,150,20.2,154,20],[176,9],[165.8,8.6,166.6,12,166,12],[166,20],[176.2,20.6,175.4,18,176,18],'lineCap="round";strokeStyle="#000";lineWidth=11;stroke();strokeStyle="#fff";lineWidth=4.2;stroke()'],
logoFunc = function(a,b,c,d){a=a.getContext('2d');for(c in b)d=b[c],''+d===d?eval('with(a){'+d+'}'):a[d[2]?'bezierCurveTo':'moveTo'].apply(a,d)};
logoFunc(Canvas, logo);
</script>
@Revlin
Copy link

Revlin commented Oct 2, 2013

Cool, but no red triangle. Firefox 24 says:

"TypeError: a is null"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment