{{ message }}

Instantly share code, notes, and snippets.

# lostintangent/index.pug

Last active Jan 8, 2021
SVG Exercise 03: Morphing Generative flower
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 svg(viewBox="-50 -50 100 100")
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 const xlinkNS = 'http://www.w3.org/1999/xlink'; const svgNS = 'http://www.w3.org/2000/svg'; const \$ = document.querySelector.bind(document); const PI = Math.PI const DEG = PI / 180; const R = (a, b) => a + Math.floor(Math.random()*(b-a+1)); const pathDef = (arr, closed) => 'M' + arr.map(({x, y}) => `\${x} \${y}`).join('L') + (closed ? 'Z':''); function rotate({x, y}, a) { const { sin, cos } = Math; return { x: x * cos(a) - y * sin(a), y: x * sin(a) + y * cos(a) }; } function translate({x, y}, tx, ty) { return { x: x + tx, y: y + ty } } function scale({x,y}, sx, sy) { return { x: x * sx, y: y * sy } } function mirrorX({x,y}) { return scale({x,y}, -1, 1); } function petal(w, h, N = 4) { const p = Array(N).fill(0).map((_, i) => ({ x: (i < N-1) ? (Math.random() * (w/2)) : 0, y: (i+1)/N*h}) ); return [{x:0,y:0}, ...p, ...p.reverse().slice(1).map(mirrorX), {x:0,y:0}] } function flower(numLeafs) { const P = petal(25, 40, R(2, 16)).slice(0,-1); return [...Array(numLeafs).fill(0).map( (_, i) => P.map(point => rotate(point, i * DEG * 360 / numLeafs)) ).flat(), {x:0, y:0}]; } for (let i = 0; i < 16; i++) { const path = document.createElementNS(svgNS, 'path'); path.setAttribute('class', 'stroke'); path.setAttribute('d', pathDef(flower(R(2,8) * 3))); path.setAttribute('id', 'flower_' + (i+1)); \$('svg').appendChild(path); } const initial = document.createElementNS(svgNS, 'path'); initial.setAttribute('class', 'stroke'); initial.setAttribute('d', \$('path').getAttribute('d')); initial.setAttribute('id', 'flower_initial'); \$('svg').appendChild(initial); const tl = gsap.timeline({repeat: -1, paused: true }); for (let i = 2; i <= 16; i++) { tl.to('#flower_1', {morphSVG: '#flower_' + i}, '+=1') } tl.to('#flower_1', {morphSVG: '#flower_initial'}, '+=1') const first = \$('path'); const pathLength = first.getTotalLength(); first.style.strokeDasharray = pathLength first.style.strokeDashoffset = pathLength first.classList.add('anim') first.addEventListener('animationend', () => { first.style.strokeDasharray = 'initial'; first.style.strokeDashoffset = 'initial'; tl.resume() })
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 vendors = official body background #222 margin 0 height 100vh display flex flex-wrap wrap align-items center justify-content space-around svg width 90vmin height 90vmin .stroke stroke none fill none .stroke:first-child fill none stroke #fff stroke-width .5 stroke-linecap round stroke-linejoin round .anim animation stroke-anim linear 2s forwards @keyframes stroke-anim { to { stroke-dashoffset: 0 } }
to join this conversation on GitHub. Already have an account? Sign in to comment