|
function test(canvas){ |
|
// Setup |
|
|
|
var width = canvas.width, |
|
height = canvas.height; |
|
|
|
var ctx = canvas.getContext('2d'); |
|
|
|
var timeStart = Date.now(), |
|
secondsElapsed = 0; |
|
|
|
// Draw internal |
|
|
|
const s_kappa = .5522848; |
|
|
|
var s_x,s_y, |
|
s_sx,s_sy, |
|
s_sx_05, s_sy_05; |
|
|
|
var s_ox, s_oy; |
|
var s_xe, s_ye, s_xm, s_ym; |
|
|
|
var s_cp1x_0,s_cp1y_0,s_cp2x_0,s_cp2y_0,s_x_0,s_y_0, |
|
s_cp1x_1,s_cp1y_1,s_cp2x_1,s_cp2y_1,s_x_1,s_y_1, |
|
s_cp1x_2,s_cp1y_2,s_cp2x_2,s_cp2y_2,s_x_2,s_y_2, |
|
s_cp1x_3,s_cp1y_3,s_cp2x_3,s_cp2y_3,s_x_3,s_y_3; |
|
|
|
const scaleThreshold = 0.05; |
|
|
|
var numEllipsesDrawn; |
|
|
|
function ellipse_internal(x,y,sx,sy) { |
|
if(sx < scaleThreshold || sy < scaleThreshold){ |
|
return; |
|
} else if (!(x == s_x && y == s_y && sx == s_sx && sy == s_sy)) { |
|
|
|
if (sx != s_sx) { |
|
s_sx = sx; |
|
s_sx_05 = s_sx * 0.5; |
|
s_ox = s_sx_05 * s_kappa; |
|
} |
|
|
|
if (sy != s_sy) { |
|
s_sy = sy; |
|
s_sy_05 = s_sy * 0.5; |
|
s_oy = s_sy_05 * s_kappa; |
|
} |
|
|
|
s_cp1x_0 = s_cp2x_3 = s_x_3 = s_x = x - s_sx_05; |
|
s_cp2y_0 = s_y_0 = s_cp1y_1 = s_y = y - s_sy_05; |
|
|
|
s_cp2x_1 = s_x_1 = s_cp1x_2 = s_xe = s_x + s_sx; |
|
s_cp2y_2 = s_y_2 = s_cp1y_3 = s_ye = s_y + s_sy; |
|
s_x_0 = s_x_2 = s_xm = s_x + s_sx_05; |
|
s_y_1 = s_y_3 = s_ym = s_y + s_sy_05; |
|
|
|
s_cp1y_0 = s_cp2y_1 = s_ym - s_oy; |
|
s_cp2x_0 = s_cp1x_3 = s_xm - s_ox; |
|
s_cp1y_2 = s_cp2y_3 = s_ym + s_oy; |
|
s_cp1x_1 = s_cp2x_2 = s_xm + s_ox; |
|
|
|
} |
|
|
|
ctx.moveTo(s_x, s_ym); |
|
ctx.bezierCurveTo(s_cp1x_0, s_cp1y_0, s_cp2x_0, s_cp2y_0, s_x_0, s_y_0); |
|
ctx.bezierCurveTo(s_cp1x_1, s_cp1y_1, s_cp2x_1, s_cp2y_1, s_x_1, s_y_1); |
|
ctx.bezierCurveTo(s_cp1x_2, s_cp1y_2, s_cp2x_2, s_cp2y_2, s_x_2, s_y_2); |
|
ctx.bezierCurveTo(s_cp1x_3, s_cp1y_3, s_cp2x_3, s_cp2y_3, s_x_3, s_y_3); |
|
|
|
numEllipsesDrawn++; |
|
} |
|
|
|
var prevR,prevG,prevB,prevA; |
|
|
|
function fillFlush(r,g,b,a){ |
|
ctx.fill(); |
|
if(r == prevR && g == prevG && b == prevB && a == prevA){ |
|
return; |
|
} |
|
ctx.fillStyle = 'rgba(' + r + ',' + (g || 0) + ',' + (b || 0) + ',' + (a === undefined ? 1.0 : a) + ')'; |
|
ctx.beginPath(); |
|
|
|
prevR = r; |
|
prevG = g; |
|
prevB = b; |
|
prevA = a; |
|
} |
|
|
|
function fillDirect(r,g,b,a){ |
|
if(r == prevR && g == prevG && b == prevB && a == prevA){ |
|
return; |
|
} |
|
ctx.fillStyle = 'rgba(' + r + ',' + (g || 0) + ',' + (b || 0) + ',' + (a === undefined ? 1.0 : a)+ ')'; |
|
prevR = r; |
|
prevG = g; |
|
prevB = b; |
|
prevA = a; |
|
} |
|
|
|
function ellipseDirect(x,y,sx,sy){ |
|
ctx.beginPath(); |
|
ellipse_internal(x,y,sx,sy); |
|
ctx.fill(); |
|
} |
|
|
|
function ellipseFlush(x,y,sx,sy){ |
|
ellipse_internal(x,y,sx,sy); |
|
} |
|
|
|
const PI = Math.PI, |
|
HALF_PI = PI * 0.5, |
|
QUARTER_PI = PI * 0.25, |
|
TWO_PI = PI * 2; |
|
|
|
var fill,ellipse; |
|
|
|
function draw(){ |
|
ctx.clearRect(0,0,width,height); |
|
ctx.fillStyle = 'rgb(0,0,255)'; |
|
ctx.fillRect(0,0,width,height); |
|
|
|
|
|
if(RENDER_MODE == 0){ |
|
fill = fillDirect; |
|
ellipse = ellipseDirect; |
|
|
|
} else { |
|
fill = fillFlush; |
|
ellipse = ellipseFlush; |
|
} |
|
|
|
var i,j; |
|
var a, b, c, d, e, f; |
|
|
|
var width_05 = width * 0.5; |
|
|
|
|
|
i = -1; |
|
a = 40; |
|
b = 1 / (a-1); |
|
while(++i < a){ |
|
c = i * b; |
|
j = -1; |
|
while(++j < a){ |
|
d = j * b; |
|
e = (0.5 + Math.cos(c * PI * 10 + secondsElapsed) * Math.sin(d * PI * 4 + secondsElapsed) * 0.5) * 50; |
|
fill(~~(c*255),0,~~(d*255)); |
|
ellipse(c * width_05,d * 175,e,e); |
|
} |
|
} |
|
|
|
a = ~~(secondsElapsed * 2) % 2 == 0 ? 255 : 0; |
|
|
|
fill(a,a,a); |
|
ellipse(100,150,50,50); |
|
ellipse(350,150,50,50); |
|
|
|
a = 1/9; |
|
i = -1; |
|
while(++i < 10){ |
|
b = i * a * PI; |
|
c = Math.sin(b + secondsElapsed * 4)* 40; |
|
ellipse(225 + Math.cos(b) * 125,250 + Math.sin(b) * 125,c,c); |
|
} |
|
|
|
ctx.save(); |
|
ctx.translate(width_05,0); |
|
a = 50; |
|
b = 1 / (a-1); |
|
|
|
i = -1; |
|
while(++i < a){ |
|
c = i * b; |
|
j = -1; |
|
while(++j < a){ |
|
d = j * b; |
|
e = (0.5 + Math.cos(c * PI * 10 + secondsElapsed) * Math.sin(d * PI * 2 + secondsElapsed) * 0.5) * 10; |
|
ellipse(c * width_05,d * height,e,e); |
|
} |
|
} |
|
|
|
|
|
ctx.translate(150,150); |
|
a = 1/499; |
|
|
|
i = -1; |
|
while(++i < 500){ |
|
b = i * a; |
|
c = QUARTER_PI * 1.25 + i * a * (PI + QUARTER_PI * 1.5); |
|
d = (0.5 + Math.sin(b * PI * 6 + secondsElapsed * 8) * Math.sin(b * PI * 4 + secondsElapsed )) * 50; |
|
e = 100 + Math.cos(c) * 150; |
|
f = 100 + Math.sin(c) * 150; |
|
|
|
fill(0,0,0); |
|
ellipse(e,f,d,d); |
|
fill(255,255,255); |
|
ellipse(e-3,f+1,d,d); |
|
fill(255,0,0); |
|
ellipse(e-2,f-2,d,d); |
|
} |
|
ctx.restore(); |
|
} |
|
|
|
|
|
function drawLoop(){ |
|
stats.begin(); |
|
|
|
ctx.save(); |
|
draw(); |
|
if(RENDER_MODE == 1){ |
|
ctx.fill(); |
|
} |
|
ctx.restore(); |
|
|
|
numEllipsesDisplay.innerHTML = 'Num ellipses displayed: ' + numEllipsesDrawn; |
|
numEllipsesDrawn = 0; |
|
|
|
prevR = prevG = prevB = prevA = null; |
|
|
|
secondsElapsed = (Date.now() - timeStart) / 1000; |
|
|
|
stats.end(); |
|
requestAnimationFrame(drawLoop,null); |
|
} |
|
drawLoop(); |
|
} |
|
|
|
window.addEventListener('load',function(){ |
|
test(document.getElementsByTagName('canvas')[0]); |
|
}); |
|
|
|
|