New Document @import url(https://fonts.googleAPIs.com/css?family=Poiret+One); html { overflow: hidden; touch-action: none; content-zooming: none; } body { position: absolute; margin: 0; padding: 0; background: #111; width: 100%; height: 100%; } #canvas { width: 100%; height: 100%; background: #fff; position: absolute; } #text { position:absolute; left:0; bottom:10px; width:100%; pointer-events: none; } #text div { position:absolute; color:#888; left:0; width:100%; text-align:center; top:-32px; font-family: 'Poiret One', cursive; font-size:32px; }! function () { "use strict"; // branch constructor function Branch (parent, level, x, y) { this.parent = parent; this.branches = []; this.p0 = parent ? parent.p1 : new Point(x, y); this.p1 = new Point(x, y); this.level = level; this.life = 20; this.angle = 0; this.vx = 0; this.vy = 0; } // grow branch Branch.prototype.grow = function () { // recursively grow children branches for (var i = 0; i 1) { this.p1.x += this.vx; this.p1.y += this.vy; ctx.beginPath(); ctx.lineCap = "round"; if (this.level) { // draw branch ctx.lineWidth = this.level * 6 - 5; ctx.strokeStyle = "#000"; if (this.parent) { ctx.moveTo(this.parent.p0.x, this.parent.p0.y); ctx.quadraticCurveTo(this.p0.x, this.p0.y, this.p1.x, this.p1.y); } ctx.stroke(); } else { // draw leaf ctx.lineWidth = 10; ctx.strokeStyle = "#f40"; ctx.moveTo(this.p0.x, this.p0.y); ctx.lineTo(this.p1.x, this.p1.y); ctx.stroke(); } } // create sub branches if (this.life === 1 && this.level > 0 && this.level 0.8) || pointer.moveDistance > 20) { pointer.moveDistance = 0; var branch = new Branch (current, current.level, current.p1.x, current.p1.y); current.branches.push(branch); if (Math.random() > 0.8) current.branches.push(newBranch(current)); current = branch; nBranches++; } // cut the tree if (nBranches > maxBranches) { root = root.branches[0]; nBranches--; } } // prepare the canvas var canvas = { elem: document.getElementById('canvas'), width: 0, height: 0, resize: function () { this.width = this.elem.width = this.elem.offsetWidth; this.height = this.elem.height = this.elem.offsetHeight; } } var ctx = canvas.elem.getContext("2d"); canvas.elem.oNSElectstart = function() { return false; } canvas.elem.ondragstart = function() { return false; } window.addeventlistener('resize', canvas.resize.bind(canvas), false); canvas.resize(); // pointer events var pointer = { x: canvas.width * 0.5, y: canvas.height * 0.5, px: 0, py: 0, moveDistance: 0, move: function (e) { e.preventDefault(); var pointer = e.targetTouches ? e.targetTouches[0] : e; this.x = pointer.clientX; this.y = pointer.clientY; var dx = this.x - this.px; var dy = this.y - this.py; this.moveDistance += Math.sqrt(dx * dx + dy * dy); // speed limit if (this.moveDistance > 40) { this.x = this.px + dx * 0.1; this.y = this.py + dy * 0.1; } // cancel autorun if (autorun) { this.x = pointer.clientX; this.y = pointer.clientY; root = new Branch (false, maxLevels, this.x, this.y); current = root; autorun = false; document.getElementById("clic").innerHTML = ""; } this.px = this.x; this.py = this.y; } } window.addEventListener("mousemove", pointer.move.bind(pointer), false ); canvas.elem.addEventListener("touchmove", pointer.move.bind(pointer), false ); // variables var maxLevels = 7; var nBranches = 0; var maxBranches = 200; var autorun = true; var frame = 0; var root = new Branch (false, maxLevels, pointer.x, pointer.y); var current = root; // start run(); }();this pen is mouse/touch interactive