A Pen by Lea Rosema on CodePen.
Last active
January 8, 2021 01:42
-
-
Save lostintangent/b2dc073242107cdb9c37c6989f340eb0 to your computer and use it in GitHub Desktop.
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
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js"></script> |
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment