/*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(); }());