script.babel

let width, height, cx, cy; const svg = document.getElementById('svg'), svgGroup = document.getElementById('svg-group'), overlay = document.getElementById('overlay'); const line = d3.line().curve(d3.curveBasis); const colors = chroma.scale(['#91B43C', '#C86B28', '#FFC501', '#CB2228']);//.mode('lch'); function init() { onResize(); window.addEventListener('resize', onResize, false); initStartAnim(); const inputHandler = new InputHandler({ elt: overlay, onInputStart(e) { this.x0 = this.x; this.y0 = this.y; this.path = new DrawPath(svgGroup, chroma.random().hex()); this.path.points = [[this.x, this.y], [this.x, this.y]]; }, onInputMove(e) { this.rad = Math.atan2(this.x0 - this.x, this.y - this.y0); const points = this.path.points; const dx = this.x - this.x0; const dy = this.y - this.y0; if (dx * dx + dy * dy > 100) { points.push([this.x0 = this.x, this.y0 = this.y]); let w = 10 + rnd(20); let h = w + rnd(w * 2); let rz = (this.rad + rnd(Math.PI / 3, true)) * 180 / Math.PI; let fill = chroma(this.path.stroke).set('hsl.l', 0.2 + rnd(0.4)).hex(); new Leaf(svgGroup, this.x, this.y, w, h, 3 + Math.round(rnd(5)), rz, this.path.stroke, fill); } else { points[points.length - 1] = [this.x, this.y]; } this.path.updatePathD(); }, onInputEnd(e) { if (this.rad) { let w = 10 + rnd(10); let h = w + rnd(w * 2); let fill = chroma(this.path.stroke).set('hsl.l', 0.2 + rnd(0.4)).hex(); new Leaf(svgGroup, this.x, this.y, w, h, 3 + Math.round(rnd(5)), this.rad * 180 / Math.PI, this.path.stroke, fill); } }, updateInputCoords(e) { this.x = this.currX - cx; this.y = this.currY - cy; }, }); } function initStartAnim() { const n = 4; r1 = 150, r2 = 30, dr = (r1 - r2) / (n - 1); createRing(0, 0, r1, 50); for (let i = 1; i < n; i++) { TweenMax.to({}, i * 0.5, { onComplete() { createRing(0, 0, r1 - i * dr, 50 - i * 6); } }); } } function createRing(rx, ry, r, n) { const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.setAttributeNS(null, 'cx', rx); circle.setAttributeNS(null, 'cy', ry); circle.setAttributeNS(null, 'r', r); let stroke = colors(rnd(1)).hex(); // chroma.random().hex(); circle.style.stroke = stroke; svgGroup.appendChild(circle); const da = 2 * Math.PI / n; let a, x, y, w, h, rz, fill; for (let i = 0; i < n; i++) { a = i * da; x = Math.cos(a) * r; y = Math.sin(a) * r; w = 10 + rnd(r / 4); h = w + rnd(w * 2); rz = a * 180 / Math.PI - 90; fill = chroma(stroke).set('hsl.l', 0.2 + rnd(0.4)).hex(); new Leaf(svgGroup, x, y, w, h, 3 + Math.round(rnd(5)), rz, stroke, fill); } } function onResize() { const r = svg.getBoundingClientRect(); width = r.width; height = r.height; cx = width / 2; cy = height / 2; svgGroup.style.transform = `translate(${cx}px, ${cy}px)`; } class DrawPath { constructor(parent, stroke) { this.parent = parent; this.points = []; this.stroke = stroke; this.create(); } create() { this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); this.path.style.stroke = this.stroke; this.parent.appendChild(this.path); } pathD() { return line(this.points); } updatePathD() { this.path.setAttributeNS(null, 'd', this.pathD()); } } function rColor(steps) { } class Leaf { constructor(elt, x, y, w, h, n, rz, stroke, fill) { this.elt = elt; this.x = x; this.y = y; this.w = w; this.h = h; this.n = n; this.rz = rz; this.stroke = stroke; this.fill = fill; this.ep = { x: rnd(w / 20, true), y: h + rnd(h / 20, true) }; this.stemH = h / 10; this.left = new Curve( { x: 0, y: this.stemH }, { x: -w / 2 + rnd(w / 5, true), y: this.stemH + rnd(h / 5, true) }, { x: -w / 2 + rnd(w / 5, true), y: this.stemH + h / 2 + rnd(h / 10, true) }, this.ep ); this.right = new Curve( { x: 0, y: this.stemH }, { x: w / 2 + rnd(w / 5, true), y: this.stemH + rnd(h / 5, true) }, { x: w / 2 + rnd(w / 5, true), y: this.stemH + h / 2 + rnd(h / 10, true) }, this.ep ); this.center = new Curve( { x: 0, y: this.stemH }, { x: rnd(w / 20, true), y: h / 3 + rnd(h / 20, true) }, { x: rnd(w / 20, true), y: 2 * h / 3 + rnd(h / 20, true) }, this.ep ); this.create(); } create() { this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g'); this.group.classList.add('leaf'); this.group.style.transform = `translate(${this.x}px, ${this.y}px)`; this.elt.appendChild(this.group); let innerGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g'); innerGroup.style.transform = `rotate3d(0, 0, 1, ${this.rz}deg)`; this.group.appendChild(innerGroup); this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); this.path.setAttributeNS(null, 'd', this.pathD()); let length = this.path.getTotalLength() / 4; // ? this.path.style.stroke = this.stroke; // this.path.style.fill = this.fill; this.path.style.strokeDasharray = length; this.path.style.strokeDashoffset = length; innerGroup.appendChild(this.path); TweenMax.to(this.path, 4 + rnd(4), { strokeDashoffset: 0, fill: this.fill }); } pathD() { let d = []; d.push(`M0,0 L0,${this.stemH}`); d.push(this.left.pathD()); d.push(this.right.pathD()); d.push(this.center.pathD()); for (let i = 0; i < this.n; i++) { let p1 = this.center.getXY(i * (0.9 / this.n)); let p2 = this.left.getXY(0.5 + i * (0.5 / this.n)); d.push(`M${p1.x},${p1.y} L${p2.x},${p2.y}`); p2 = this.right.getXY(0.5 + i * (0.5 / this.n)); d.push(`M${p1.x},${p1.y} L${p2.x},${p2.y}`); } return d.join(' '); } } class Curve { constructor(sp, cp1, cp2, ep) { this.sp = sp; this.cp1 = cp1; this.cp2 = cp2; this.ep = ep; } pathD() { let d = []; d.push(`M${this.sp.x} ${this.sp.y}`); d.push(`C${this.cp1.x},${this.cp1.y}`); d.push(`${this.cp2.x},${this.cp2.y}`); d.push(`${this.ep.x},${this.ep.y}`); return d.join(' '); } getXY(t) { return { x: Math.pow(1 - t, 3) * this.sp.x + 3 * t * Math.pow(1 - t, 2) * this.cp1.x + 3 * t * t * (1 - t) * this.cp2.x + t * t * t * this.ep.x, y: Math.pow(1 - t, 3) * this.sp.y + 3 * t * Math.pow(1 - t, 2) * this.cp1.y + 3 * t * t * (1 - t) * this.cp2.y + t * t * t * this.ep.y }; } } /** * input handler */ function InputHandler(conf) { conf.elt.addEventListener('mousedown', e => this.onMouseDown(e)); conf.elt.addEventListener('mousemove', e => this.onMouseMove(e), false); conf.elt.addEventListener('mouseup', e => this.onMouseEnd(e)); conf.elt.addEventListener('mouseleave', e => this.onMouseEnd(e)); conf.elt.addEventListener('touchstart', e => this.onTouchStart(e)); conf.elt.addEventListener('touchmove', e => this.onTouchMove(e)); conf.elt.addEventListener('touchend', e => this.onTouchEnd(e)); conf.elt.addEventListener('touchleave', e => this.onTouchEnd(e)); this.onInputStart = conf.onInputStart; this.onInputMove = conf.onInputMove; this.onInputEnd = conf.onInputEnd; this.updateInputCoords = conf.updateInputCoords; } /** * mouse events */ InputHandler.prototype.onMouseDown = function (e) { if (e.which == 1) { this.mouseDown = true; this.updateMouseCoords(e); this.onInputStart(e); } }; InputHandler.prototype.onMouseMove = function (e) { if (this.mouseDown) { this.prevX = this.currX; this.prevY = this.currY; this.updateMouseCoords(e); this.onInputMove(e); } }; InputHandler.prototype.onMouseEnd = function (e) { if (this.mouseDown) { this.mouseDown = false; this.onInputEnd(e); } }; InputHandler.prototype.updateMouseCoords = function (e) { var clientRect = e.target.getBoundingClientRect(); this.currX = e.clientX - clientRect.left; this.currY = e.clientY - clientRect.top; this.updateInputCoords(e); }; /** * touch events */ InputHandler.prototype.onTouchStart = function (e) { e.preventDefault(); this.touchDown = true; this.updateTouchCoords(e); this.onInputStart(e); }; InputHandler.prototype.onTouchMove = function (e) { if (this.touchDown) { this.prevX = this.currX; this.prevY = this.currY; this.updateTouchCoords(e); this.onInputMove(e); } }; InputHandler.prototype.onTouchEnd = function (e) { if (this.touchDown) { e.preventDefault(); this.touchDown = false; this.onInputEnd(e); } }; InputHandler.prototype.updateTouchCoords = function (e) { var clientRect = e.target.getBoundingClientRect(); this.currX = e.changedTouches[0].clientX - clientRect.left; this.currY = e.changedTouches[0].clientY - clientRect.top; this.updateInputCoords(e); }; function rnd(max, negative) { return negative ? Math.random() * 2 * max - max : Math.random() * max; } init();
Tribute to my kids (try your mouse or touch)

Be the first to comment

You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.