{
var ctx = canvas.getContext('2d'),
i = 0,
dot = {
x: 0,
y: 0,
hue: 0.001,
lightness: 0.35
};
var barnsley = [
{a: 0.00, b: 0.00, c: 0.00, d: 0.16, e: 0.00, f: 0.00, p: 0.01},
{a: 0.85, b: 0.04, c: -0.04, d: 0.85, e: 0.00, f: 1.60, p: 0.01 + 0.85},
{a: 0.20, b: -0.26, c: 0.23, d: 0.22, e: 0.00, f: 1.60, p: 0.01 + 0.85 + 0.07},
{a: -0.15, b: 0.28, c: 0.26, d: 0.24, e: 0.00, f: 0.44, p: 0.01 + 0.85 + 0.07 + 0.07}
];
function fern_step(obj) {
var p = Math.random();
var b = null;
for (i = 0; i < barnsley.length; i++) {
b = barnsley[i];
if (p < b.p) {
return Object.assign(obj, {
x: b.a * obj.x + b.b * obj.y + b.e,
y: b.c * obj.x + b.d * obj.y + b.f,
hue: p < 1e-3 ? (obj.hue > 1 ? 1e-4 : obj.hue + 1e-3) : obj.hue
});
}
}
}
var frames = 0;
function step() {
if (frames++ > 400) {
return;
}
for (var k = 0; k < 1000; k++) {
draw_circle(
ctx,
dot.x * 105 + canvas.width / 2,
dot.y * -49 + canvas.height,
0.09,
dot.hue,
dot.lightness
);
dot = fern_step(dot);
}
window.requestAnimationFrame(step);
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
window.requestAnimationFrame(step);
function draw_circle(ctx, x, y, radius, hue, lightness) {
ctx.fillRect(x, y, 1, 1);
var rgb = hslToRgb(hue, 0.75, lightness);
ctx.fillStyle = 'rgba(' +
rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',' + 0.5 +
')';
ctx.fill();
}
function hslToRgb(h, s, l){
var r, g, b;
if (s == 0) {
r = g = b = l;
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
}