Created
January 27, 2011 05:17
-
-
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 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
/* | |
* 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