97 lines
2.2 KiB
JavaScript
97 lines
2.2 KiB
JavaScript
'use strict';
|
|
|
|
import { html } from 'the-dom';
|
|
import { getColor } from './utils';
|
|
import { createRegularVertices, scaleVertices, applyChaos } from './chaos';
|
|
|
|
const { body } = html(document);
|
|
|
|
const content = body.find('#content');
|
|
const verticesRange = body.find('#vertices');
|
|
const fractionRange = body.find('#fraction');
|
|
|
|
const plotting = body.find('#plotting').node;
|
|
const ctx = plotting.getContext('2d');
|
|
|
|
const padding = 40; // padding between the canvas edges and the points
|
|
let width, height, vertices;
|
|
|
|
/**
|
|
* Re-render the scene from scratch
|
|
*
|
|
* @return {null}
|
|
*/
|
|
const render = () => {
|
|
const fraction = 1 / parseFloat(fractionRange.node.value);
|
|
const scaledVerts = scaleVertices(width, height, vertices);
|
|
|
|
plotting.width = width + 2 * padding;
|
|
plotting.height = height + 2 * padding;
|
|
|
|
// do not plot (very) small sizes
|
|
if (width < 1) {
|
|
return;
|
|
}
|
|
|
|
// draw the polygon
|
|
ctx.strokeStyle = '#aaa';
|
|
ctx.lineWidth = 1;
|
|
|
|
ctx.beginPath();
|
|
|
|
for (let i = 0; i < vertices.length; i += 1) {
|
|
ctx.lineTo(scaledVerts[i][0] + padding, scaledVerts[i][1] + padding);
|
|
}
|
|
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
|
|
// draw the vertices
|
|
for (let i = 0; i < vertices.length; i += 1) {
|
|
ctx.beginPath();
|
|
ctx.fillStyle = 'rgb(' + getColor(i).join(', ') + ')';
|
|
|
|
ctx.arc(
|
|
scaledVerts[i][0] + padding, scaledVerts[i][1] + padding,
|
|
4, 0, Math.PI * 2
|
|
);
|
|
|
|
ctx.fill();
|
|
}
|
|
|
|
// do the chaos game
|
|
const image = ctx.getImageData(padding, padding, width, height);
|
|
|
|
applyChaos(image, fraction, scaledVerts);
|
|
ctx.putImageData(image, padding, padding);
|
|
};
|
|
|
|
/**
|
|
* Update the scene when the window has been resized
|
|
*
|
|
* @return {null}
|
|
*/
|
|
const resize = () => {
|
|
width = content.node.clientWidth - 2 * padding;
|
|
height = content.node.clientHeight - 2 * padding;
|
|
|
|
render();
|
|
};
|
|
|
|
/**
|
|
* Create new vertices
|
|
*/
|
|
verticesRange.on('input', () => {
|
|
vertices = createRegularVertices(
|
|
parseInt(verticesRange.node.value, 10)
|
|
);
|
|
|
|
render();
|
|
});
|
|
|
|
window.onresize = resize;
|
|
fractionRange.on('input', render);
|
|
|
|
vertices = createRegularVertices(3);
|
|
resize();
|