JSFiddle - React, Tailwind, and code Playground
by Damian Dulisz
HTML
<div id="app">
<svg width="100vw" height="100vh" @click="move">
<circle v-for="circle in circles" fill="none" stroke-width="8"
v-bind="circle" :cx="circle.cx"/>
</svg>
</div>
CSS
body {
background: #35495e;
}
.control {
position: fixed;
top: 0;
left: 0
}
circle {
stroke: rgba(65, 184, 131, 1);
mix-blend-mode: screen;
}
Babel + JSX
new Vue({
data () {
return {
circles: Array(25).fill('').map((e, i) => ({ r: 1 + (i * 5), cx: 100, cy: 150 }))
}
},
methods: {
move (e) {
stagger(this.circles.map((circle, i) => {
return animation(this.circles, i, { cx: e.x, cy: e.y }, {
duration: 750,
easing: bounce
})
}), 50)()
}
}
}).$mount('#app')
function bounce (progress) {
for(var a = 0, b = 1, result; 1; a += b, b /= 2) {
if (progress >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
}
}
}
function circ (progress) {
return 1 - Math.sin(Math.acos(progress))
}
function linear (progress) {
return progress
}
function back (x) {
return progress => Math.pow(progress, 2) * ((x + 1) * progress - x)
}
function makeEaseInOut (delta) {
return function (progress) {
if (progress < .5) {
return delta(2*progress) / 2
}
else {
return (2 - delta(2*(1-progress))) / 2
}
}
}
function makeEaseOut (delta) {
return function (progress) {
return 1 - delta(1 - progress)
}
}
const bounceEaseOut = makeEaseOut(bounce)
const backEaseOut = pushBack => makeEaseOut(back(pushBack))
const circEaseInOut = makeEaseInOut(circ)
const circEaseOut = makeEaseOut(circ)
function combineSteps (...steps) {
return function (progress) {
steps.forEach(step => step(progress))
}
}
function* toGenerator (iterable) {
yield* iterable
}
function createAnimation (obj, prop, from, to, userConfig) {
return () => animate(obj, prop, from, to, userConfig)
}
function adjustValue (from, to, abs, progress) {
return to > from
? from + (abs * progress)
: from - (abs * progress)
}
function createStep (obj, property, to) {
let from = Object.assign({}, obj[property])
function newStateBuilder () {
if (typeof to === 'object') {
const params = Object.keys(to).map(key => {
return {
key,
from: from[key],
to:...