/* # moon-draw.js To use this code, paste it into your console. Then start writing some Processing-like code: ```js begin() translate(width / 2, height / 2) for(var i = 0; i < 11; i++) { rotate(radians(33)); triangle(10, 10, 200); rect(20, 30, 40, 50); } end() ``` # Functions - random, clamp, radians - begin, moveTo, end - translate, rotate, scale - pushMatrix popMatrix - ellipse, spiral, rectangle, triangle */ var width = 450, height = 450; var state; var stateStack = []; begin(); function random(a, b) { if(typeof b !== 'undefined') { return Math.random() * (b - a) + a; } else { return Math.random() * a; } } function clamp(x, low, high) { return x > high ? high : x < low ? low : x; } // convert degrees to radians function radians(angle) { return 2 * Math.PI * angle / 360; } function mouse(event, x, y) { var canvas = document.getElementById('defaultCanvas'); canvas.dispatchEvent(new MouseEvent(event, { 'view': window, 'bubbles': true, 'cancelable': true, 'clientX': canvas.getBoundingClientRect().left + x, 'clientY': canvas.getBoundingClientRect().top + y })); state.prev.x = x; state.prev.y = y; } // call begin() before creating a new drawing function begin() { state = { start: false, prev: {x: 0, y:0}, translation: {x: 0, y: 0}, scaling: {x: 1, y: 1}, rotation: 0 }; } // moveTo simulates mouse movement one point at a time // your drawing will start at your first moveTo point function moveTo(x, y) { var s = Math.sin(state.rotation); var c = Math.cos(state.rotation); var sx = x * c - y * s; var sy = x * s + y * c; sx *= state.scaling.x; sy *= state.scaling.y; sx += state.translation.x; sy += state.translation.y; sx = clamp(sx, 1, 450); sy = clamp(sy, 1, 450); if(!state.start) { mouse('mousedown', sx, sy); state.start = true; } mouse('mousemove', sx, sy); } // call end() when you are done placing points function end() { mouse('mouseup', state.prev.x, state.prev.y); } function pushMatrix() { stateStack.push({ translation: { x: state.translation.x, y: state.translation.y }, scaling: { x: state.scaling.x, y: state.scaling.y }, rotation: state.rotation, }); } function popMatrix() { var pop = stateStack.pop(); state.translation = { x: pop.translation.x, y: pop.translation.y }; state.scaling = { x: pop.scaling.x, y: pop.scaling.y }; state.rotation = pop.rotation; } function translate(x, y) { var s = Math.sin(state.rotation); var c = Math.cos(state.rotation); var sx = x * c - y * s; var sy = x * s + y * c; sx *= state.scaling.x; sy *= state.scaling.y; state.translation.x += sx; state.translation.y += sy; } function scale(x, y) { state.scaling.x *= x; state.scaling.y *= y; } // rotate() using radians function rotate(angle) { state.rotation += angle; } function ellipse(x, y, w, h, steps) { steps = typeof steps !== 'undefined' ? steps : 24; for(var i = 0; i < steps; i++) { var theta = 2 * Math.PI * i / (steps - 1); var cx = x + Math.sin(theta) * w / 2; var cy = y + Math.cos(theta) * h / 2; moveTo(cx, cy); } } function spiral(x, y, outerRadius, innerRadius, rotations, steps) { innerRadius = typeof innerRadius !== 'undefined' ? innerRadius : 0; rotations = typeof rotations !== 'undefined' ? rotations : 8; steps = typeof steps !== 'undefined' ? steps : 24; for(var i = 0; i < steps; i++) { var t = i / (steps - 1); var theta = rotations * 2 * Math.PI * t; var cr = t * (outerRadius - innerRadius) + innerRadius; var cx = x + Math.sin(theta) * cr; var cy = y + Math.cos(theta) * cr; moveTo(cx, cy); } } function rect(x, y, w, h) { h = typeof h !== 'undefined' ? h : w; moveTo(x, y); moveTo(x + w, y); moveTo(x + w, y + h); moveTo(x, y + h); moveTo(x, y); } function triangle(x, y, w, h) { h = typeof h !== 'undefined' ? h : w * Math.sqrt(3) / 2; moveTo(x, y); moveTo(x + w / 2, y + h); moveTo(x - w / 2, y + h); moveTo(x, y); }