Skip to content

Instantly share code, notes, and snippets.

@octaflop
Created January 27, 2011 05:17
Show Gist options
  • Save octaflop/798103 to your computer and use it in GitHub Desktop.
Save octaflop/798103 to your computer and use it in GitHub Desktop.
Richwchan.com's page-drawing source. From: http://richwchan.com/js/html5_logo_canvas_demo.js
/*
* This work is licensed under the Creative Commons Attribution-NonCommercial
* 3.0 Unported License. To view a copy of this license, visit
* http://creativecommons.org/licenses/by-nc/3.0/ or send a letter to Creative
* Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
*/
var interval = 10;
var layer1Sloppiness = [1, 2];
var layer2Sloppiness = [1, 2];
var layer3Sloppiness = [1, 2];
var layer4Sloppiness = [1, 2];
var running = true;
/* return a random integer bounded by max */
function randInt(max)
{
return Math.floor(Math.random() * max);
}
/* prepare the style of the stroke */
function prepareStroke(ctx, radius, color)
{
ctx.strokeStyle = color;
ctx.lineWidth = radius;
ctx.lineCap = ctx.lineJoin = 'round';
}
function sloppyLine($, ctx, startX, startY, endX, endY, radius, color,
sloppiness, sloppinessIndex, sloppyInterval)
{
sloppiness = sloppiness || [];
sloppinessIndex = sloppinessIndex || 0;
sloppyInterval = sloppyInterval || 20; // distance per interval
return function()
{
// vars for the queue
var that = $(this);
var q = $({});
var dx = endX - startX;
var dy = endY - startY;
var distSq = dx * dx + dy * dy;
var numIntervals = Math.sqrt(distSq) / sloppyInterval;
dx /= numIntervals;
dy /= numIntervals;
for (var i = numIntervals - 2; i >= 0; i--)
{
var x2 = startX + dx/2; // control point 1
var y2 = startY + dy/2;
// apply random offsets
x2 += randInt(sloppiness[sloppinessIndex]*2) - sloppiness[sloppinessIndex];
y2 += randInt(sloppiness[sloppinessIndex]*2) - sloppiness[sloppinessIndex];
var x3 = x2 + dx/2; // control point 2
var y3 = y2 + dy/2;
// apply random offsets
x3 += randInt(sloppiness[sloppinessIndex]*2) - sloppiness[sloppinessIndex];
y3 += randInt(sloppiness[sloppinessIndex]*2) - sloppiness[sloppinessIndex];
// note: ugly closure trick, should fix later
q.queue(function(startX, startY, x2, y2, x3, y3, i){return function()
{
// draw
prepareStroke(ctx, radius, color);
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.quadraticCurveTo(x2, y2, x3, y3);
ctx.stroke();
window.setTimeout(function() {
if (running)
q.dequeue();
else
q.stop();
}, interval); // delay
}}(startX, startY, x2, y2, x3, y3, i));
// next
startX = x3;
startY = y3;
// fix dx and dy because of random offset
dx = (endX - startX) / (1+i);
dy = (endY - startY) / (1+i);
}
// last stroke
q.queue(function()
{
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
window.setTimeout(function() {
if (running)
{
q.dequeue();
that.dequeue();
}
else
q.stop();
}, interval);
});
}
}
var scale = 0.8;
function drawPath($, ctx, q, path, radius, color, sloppiness, sloppinessIndex, sloppyInterval)
{
// hack: sigh.. should've used better coordinate in the beginning
var origin_offset = -20;
for (var i = 2; i < path.length; i += 2)
{
q.queue(sloppyLine($, ctx,
origin_offset + path[i-2] * scale, origin_offset + path[i-1] * scale,
origin_offset + path[i] * scale, origin_offset + path[i+1] * scale,
radius * scale, color, sloppiness, sloppinessIndex, sloppyInterval));
}
}
/* the actual work */
function work($, ctx)
{
ctx.clearRect(0, 0, 540, 540);
var q = $({}); // queue object
// background
var level1 = [
71, 119,
173, 74,
75, 164,
224, 68,
98, 199,
276, 73,
119, 239,
344, 65,
78, 232,
411, 75,
132, 287,
436, 88,
99, 276,
489, 89,
119, 343,
548, 64,
126, 384,
587, 92,
412, 259,
599, 153,
601, 126,
351, 272,
600, 197,
335, 310,
597, 244,
327, 341,
592, 282,
324, 384,
583, 322,
323, 421,
591, 367,
333, 464,
581, 410,
346, 495,
585, 455,
354, 536,
569, 499,
367, 574,
558, 542,
387, 608,
333, 263,
354, 632,
308, 292,
309, 624,
374, 656,
585, 569,
291, 303,
124, 421,
293, 359,
134, 462,
292, 413,
182, 487,
300, 460,
119, 499,
301, 505,
114, 541,
290, 556,
118, 568,
310, 611,
];
// dark orange border
var level2 = [
171, 561,
131, 100,
582, 100,
541, 561,
356, 612,
171, 561
];
// dark orange fill
var level3 = [
198, 545,
366, 589,
531, 546,
217, 532,
391, 570,
529, 510,
205, 502,
540, 478,
187, 465,
184, 435,
543, 451,
179, 405,
535, 415,
172, 374,
539, 381,
168, 337,
548, 356,
555, 320,
293, 329,
558, 292,
287, 300,
554, 266,
295, 269,
557, 228,
308, 237,
547, 200,
311, 207,
565, 165,
306, 177,
570, 133,
310, 147,
566, 121,
160, 128,
153, 124,
300, 169,
155, 159,
306, 153,
274, 319,
268, 185,
251, 327,
241, 180,
221, 325,
209, 179,
193, 320,
177, 173,
153, 148,
179, 379,
212, 507,
190, 557,
533, 544,
565, 158,
192, 546,
173, 363,
318, 135,
222, 138,
216, 478,
321, 514,
348, 529,
260, 529
];
// light orange border
var level4 = [
356, 573,
505, 531,
541, 138,
356, 138,
356, 573
];
// light orange fill
var level5 =
[
378, 161,
526, 159,
371, 195,
520, 193,
370, 230,
514, 229,
371, 267,
509, 267,
364, 305,
510, 300,
366, 339,
509, 334,
363, 377,
505, 369,
365, 414,
504, 408,
364, 454,
495, 447,
366, 492,
500, 485,
372, 528,
491, 521,
370, 557,
367, 533,
374, 160,
498, 509,
519, 174
];
// dark white border top
var level6 =
[
356, 309,
281, 309,
276, 251,
356, 251,
356, 194,
214, 194,
230, 365,
356, 365,
356, 309
];
// dark white border bottom
var level7 =
[
356, 455,
293, 438,
289, 393,
232, 393,
240, 482,
356, 514,
356, 455
];
// light white border bottom
var level8 =
[
356, 309,
356, 369,
425, 369,
419, 439,
356, 459,
356, 519,
473, 489,
487, 309,
356, 309
];
// light white border top
var level9 =
[
356, 194,
356, 251,
492, 251,
498, 194,
356, 194
];
// dark white fill top
var level10 =
[
230-5, 212-5,
354-5, 211-5,
230-5, 231-5,
352-5, 237-5,
231-5, 254-5,
274-5, 274-5,
233-5, 279-5,
233-5, 246-5,
245-5, 362-5,
354-5, 355-5,
252-5, 345-5,
352-5, 340-5,
252-5, 320-5,
350-5, 329-5,
260-5, 319-5,
256-5, 275-5,
279-5, 316-5,
253, 332,
277, 306,
264, 244,
349, 246,
343, 214,
313, 233
];
// dark white fill bottom
var level11 =
[
285, 409,
247, 432,
246, 422,
286, 435,
253, 456,
348, 470,
252, 474,
348, 500,
325, 475,
250, 447,
329, 463,
256, 471,
247, 409,
281, 409,
246, 401,
286, 406,
294, 445,
350, 465,
353, 494,
250, 470,
249, 456
];
// light white fill top
var level12 =
[
371, 212,
491, 211,
369, 233,
490, 236,
367, 200,
488, 206,
484, 235,
369, 229,
364, 224,
366, 243,
474, 241
];
var level13 =
[
371, 330,
481, 324,
377, 323,
369, 353,
477, 348,
395, 345,
473, 375,
466, 484,
447, 364,
445, 486,
439, 379,
432, 494,
370, 501,
421, 473,
374, 485,
431, 453,
368, 473,
368, 505,
468, 477,
368, 472,
436, 436,
434, 435,
437, 365,
470, 398,
468, 343,
369, 362,
370, 323,
366, 320,
392, 353,
469, 337,
];
// drawPath($, ctx, q, level1, 50, '#31a7de', 5, 20);
drawPath($, ctx, q, level2, 20, '#e44d26', layer1Sloppiness);
drawPath($, ctx, q, level3, 35, '#e44d26', layer1Sloppiness, 1);
drawPath($, ctx, q, level4, 20, '#f16529', layer2Sloppiness);
drawPath($, ctx, q, level5, 35, '#f16529', layer2Sloppiness, 1);
drawPath($, ctx, q, level6, 10, '#ebebeb', layer3Sloppiness);
drawPath($, ctx, q, level7, 10, '#ebebeb', layer3Sloppiness);
drawPath($, ctx, q, level10, 20, '#ebebeb', layer3Sloppiness, 1);
drawPath($, ctx, q, level11, 20, '#ebebeb', layer3Sloppiness, 1);
drawPath($, ctx, q, level8, 10, '#ffffff', layer4Sloppiness);
drawPath($, ctx, q, level9, 10, '#ffffff', layer4Sloppiness);
drawPath($, ctx, q, level12, 20, '#ffffff', layer4Sloppiness, 1);
drawPath($, ctx, q, level13, 20, '#ffffff', layer4Sloppiness, 1);
q.queue(function(){
running = false;
$('#redraw_button').button({label: (running ? 'Stop' : 'Redraw!')});
// $('.slider_container').slider('enable');
});
}
/* main handler */
function main($)
{
var div = $('#the_div');
var canvas = $('#the_canvas')
.css('background', '#eee')
.css('border-bottom-left-radius', '24px')
.css('border-bottom-right-radius', '24px')
.css('border-top-left-radius', '24px')
.css('border-top-right-radius', '24px');
var canvasEl = canvas.get(0);
if (canvasEl.getContext)
{
var ctx = canvasEl.getContext('2d');
work($, ctx);
// ui
$('#speed').slider({value: 10, min: 0, max: 100, step: 1,
slide: function(e, ui) {
interval = ui.value;
$('#speed_out').html('interval (speed): <b>' + ui.value + 'ms</b>');
}});
$('#speed_out').html('interval (speed): <b>' + interval + 'ms</b>');
$('#layer1').slider({value: 1, min: 0, max: 20, step: 0.25,
slide: function(e, ui) {
layer1Sloppiness[0] = ui.value;
layer1Sloppiness[1] = ui.value * 2.0;
$('#layer1_out').html('layer 1 sloppiness: <b>' + ui.value + '</b>');
}});
$('#layer1_out').html('layer 1 sloppiness: <b>' + layer1Sloppiness[0] + '</b>');
$('#layer2').slider({value: 1, min: 0, max: 20, step: 0.25,
slide: function(e, ui) {
layer2Sloppiness[0] = ui.value;
layer2Sloppiness[1] = ui.value * 2.0;
$('#layer2_out').html('layer 2 sloppiness: <b>' + ui.value + '</b>');
}});
$('#layer2_out').html('layer 2 sloppiness: <b>' + layer2Sloppiness[0] + '</b>');
$('#layer3').slider({value: 1, min: 0, max: 20, step: 0.25,
slide: function(e, ui) {
layer3Sloppiness[0] = ui.value;
layer3Sloppiness[1] = ui.value * 2.0;
$('#layer3_out').html('layer 3 sloppiness: <b>' + ui.value + '</b>');
}});
$('#layer3_out').html('layer 3 sloppiness: <b>' + layer3Sloppiness[0] + '</b>');
$('#layer4').slider({value: 1, min: 0, max: 20, step: 0.25,
slide: function(e, ui) {
layer4Sloppiness[0] = ui.value;
layer4Sloppiness[1] = ui.value * 2.0;
$('#layer4_out').html('layer 4 sloppiness: <b>' + ui.value + '</b>');
}});
$('#layer4_out').html('layer 4 sloppiness: <b>' + layer4Sloppiness[0] + '</b>');
$('#redraw_button').button({label: "Stop"});
$('#redraw_button').click(function(e) {
running = !running;
$('#redraw_button').button({label: (running ? 'Stop' : 'Redraw!')});
if (running)
work($, ctx);
// $('.slider_container').slider('disable');
});
// $('.slider_container').slider('disable');
}
else
{
div.html('This demo requires a HTML5 compliant browser!');
}
}
jQuery(document).ready(main);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment