212 lines
5.2 KiB
JavaScript
212 lines
5.2 KiB
JavaScript
|
/*jslint browser:true, nomen:true, plusplus:true, devel:true */
|
||
|
/*globals $, utils */
|
||
|
|
||
|
(function () {
|
||
|
'use strict';
|
||
|
|
||
|
var jCanvas = $('#canvas'), canvas = jCanvas[0], context = canvas.getContext('2d'),
|
||
|
chaos = new window.Worker('js/chaos.js'), button = $('#pt-gen'), count = $('#pt-num'),
|
||
|
size_input = $('#pt-size'), render = $('#pt-render'), render_link = render.find('a'),
|
||
|
vertices_count = $('#pt-vertices'), factor_top = $('#pt-frac-top'), factor_bottom = $('#pt-frac-bottom'),
|
||
|
form_inputs = $('#parameters form p :input'), padding = 10, verticesColors = [],
|
||
|
zoom = 1, zoom_out = $('#zoom-out'), zoom_in = $('#zoom-in');
|
||
|
|
||
|
// presets
|
||
|
$('.setting').click(function (e) {
|
||
|
var id = parseInt($(this).attr('data-setting-id'), 10);
|
||
|
|
||
|
if ($('#parameters form').prop('disabled')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
switch (id) {
|
||
|
case 1:
|
||
|
vertices_count.val(3);
|
||
|
factor_top.val(1);
|
||
|
factor_bottom.val(2);
|
||
|
break;
|
||
|
case 2:
|
||
|
vertices_count.val(5);
|
||
|
factor_top.val(3);
|
||
|
factor_bottom.val(8);
|
||
|
break;
|
||
|
case 3:
|
||
|
vertices_count.val(6);
|
||
|
factor_top.val(1);
|
||
|
factor_bottom.val(3);
|
||
|
break;
|
||
|
case 4:
|
||
|
vertices_count.val(5);
|
||
|
factor_top.val(1);
|
||
|
factor_bottom.val(3);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
button.click();
|
||
|
});
|
||
|
|
||
|
// zoom level
|
||
|
function updateZoomLevel() {
|
||
|
jCanvas.css({
|
||
|
width: canvas.width * zoom,
|
||
|
height: canvas.height * zoom
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function setZoomLevel(level) {
|
||
|
zoom = level;
|
||
|
|
||
|
updateZoomLevel();
|
||
|
}
|
||
|
|
||
|
zoom_in.click(function () {
|
||
|
if (zoom < 2) {
|
||
|
setZoomLevel(zoom + 0.1);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
zoom_out.click(function () {
|
||
|
if (zoom > 0.1) {
|
||
|
setZoomLevel(zoom - 0.1);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// returns the position of the vertices of a regular polygon with n angles
|
||
|
// the width and height parameter specifies the radius of the inscripting circle
|
||
|
function getRegularVertices(width, height, vertices) {
|
||
|
var i = 0, shapeVerts = [], angle, x = width / 2, y = height / 2,
|
||
|
rx = width / 2 - padding, ry = height / 2 - padding,
|
||
|
frac = Math.PI * 2 / vertices;
|
||
|
|
||
|
for (i = 0; i < vertices; i++) {
|
||
|
angle = frac * i + Math.PI / 2;
|
||
|
shapeVerts.push([
|
||
|
Math.cos(angle) * rx + x,
|
||
|
Math.sin(angle) * ry + y
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
return shapeVerts;
|
||
|
}
|
||
|
|
||
|
// updates rendering button which allows to download the image
|
||
|
function updateRender() {
|
||
|
render_link.attr('href', canvas.toDataURL());
|
||
|
}
|
||
|
|
||
|
// draw the vertices of the current polygon - wth the lines
|
||
|
function canvasDrawVertices() {
|
||
|
var width = canvas.width, height = canvas.height,
|
||
|
vertices = getRegularVertices(width, height, parseInt(vertices_count.val(), 10)),
|
||
|
vertices_num = vertices.length, i, vertex,
|
||
|
lastVertex = vertices[vertices_num - 1];
|
||
|
|
||
|
context.clearRect(0, 0, width, height);
|
||
|
|
||
|
// one color per vertex
|
||
|
verticesColors = [];
|
||
|
|
||
|
for (i = 0; i < vertices_num; i++) {
|
||
|
verticesColors.push(utils.getRandomColor());
|
||
|
}
|
||
|
|
||
|
// draw lines
|
||
|
context.beginPath();
|
||
|
context.moveTo(lastVertex[0], height - lastVertex[1]);
|
||
|
|
||
|
for (i = 0; i < vertices_num; i++) {
|
||
|
vertex = vertices[i];
|
||
|
context.lineTo(vertex[0], height - vertex[1]);
|
||
|
}
|
||
|
|
||
|
context.stroke();
|
||
|
|
||
|
// draw vertices
|
||
|
for (i = 0; i < vertices_num; i++) {
|
||
|
vertex = vertices[i];
|
||
|
context.fillStyle = utils.rgbToHex(verticesColors[i]);
|
||
|
|
||
|
context.beginPath();
|
||
|
context.arc(vertex[0], height - vertex[1], 3, 0, Math.PI * 2, true);
|
||
|
context.fill();
|
||
|
}
|
||
|
|
||
|
updateRender();
|
||
|
}
|
||
|
|
||
|
function enableForm(enabled) {
|
||
|
form_inputs.prop('disabled', !enabled);
|
||
|
$('#parameters form').prop('disabled', !enabled);
|
||
|
}
|
||
|
|
||
|
// on generate response from the worker
|
||
|
$(chaos).on('message', function (e) {
|
||
|
var points = e.originalEvent.data, length = points.length, i,
|
||
|
data, pdata, point, index, width = canvas.width,
|
||
|
vertexColor, height = canvas.height,
|
||
|
vertices = parseInt(vertices_count.val(), 10);
|
||
|
|
||
|
if (!Array.isArray(points[0])) {
|
||
|
console.error('Error: ' + points);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// about the fastest way to draw points array on a canvas:
|
||
|
// http://jsperf.com/filling-a-bunch-of-points-in-canvas
|
||
|
data = context.getImageData(0, 0, width, height);
|
||
|
|
||
|
for (i = 0; i < length; i++) {
|
||
|
point = points[i];
|
||
|
pdata = point[0];
|
||
|
vertexColor = verticesColors[point[1]];
|
||
|
|
||
|
index = (parseInt(pdata[0], 10) + (height - parseInt(pdata[1], 10)) * width) * 4;
|
||
|
|
||
|
data.data[index] = vertexColor[0];
|
||
|
data.data[index + 1] = vertexColor[1];
|
||
|
data.data[index + 2] = vertexColor[2];
|
||
|
data.data[index + 3] = 255;
|
||
|
}
|
||
|
|
||
|
context.putImageData(data, 0, 0);
|
||
|
enableForm(true);
|
||
|
updateRender();
|
||
|
});
|
||
|
|
||
|
// set input size
|
||
|
size_input.change(function () {
|
||
|
var size = parseInt($(this).val(), 10);
|
||
|
|
||
|
canvas.width = size + 2 * padding;
|
||
|
canvas.height = size + 2 * padding;
|
||
|
|
||
|
canvasDrawVertices();
|
||
|
updateZoomLevel();
|
||
|
});
|
||
|
|
||
|
// generate
|
||
|
button.click(function (e) {
|
||
|
var width = canvas.width, height = canvas.height, shape,
|
||
|
vertices = parseInt(vertices_count.val(), 10),
|
||
|
frac = parseInt(factor_top.val(), 10) / parseInt(factor_bottom.val(), 10);
|
||
|
|
||
|
// reset environment
|
||
|
enableForm(false);
|
||
|
canvasDrawVertices();
|
||
|
|
||
|
// regular polygon
|
||
|
shape = getRegularVertices(width, height, vertices);
|
||
|
|
||
|
chaos.postMessage([
|
||
|
parseInt(count.val(), 10) * width,
|
||
|
[width, height],
|
||
|
shape,
|
||
|
frac
|
||
|
]);
|
||
|
|
||
|
e.preventDefault();
|
||
|
});
|
||
|
|
||
|
vertices_count.change(canvasDrawVertices);
|
||
|
canvasDrawVertices();
|
||
|
}());
|