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:...