JSFiddle - React, Tailwind, and code Playground

by Julien Etienne

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/snap.svg/0.2.0/snap.svg-min.js"></script>
<svg id="s" width="100%"></svg>

CSS

html {
    background: #222;
}
body {
}
svg {
    height: 100vh;
}

JavaScript

// Easiest thing I could think of to animate, 

var s = Snap('#s'),

    // Styles
    ballStyle = {
        fill: s.gradient("r(0.57, 0.4, 0.5)#fff-#cc0000")
    },
    strStyle = {
        stroke: 'red'
    };

// Models 
function ballModel(x) {
    return s.circle(x, 400, 50).attr(ballStyle);
}

function strModel(x) {
    return s.path('M' + x + ' -300, v650').attr(strStyle);
}

// The objects
var ball = [],
    str = [];
for (var i = 2; i < 7; i++) {
    ball.push(ballModel(i * 100));
    str.push(strModel(i * 100));
}

// Groups
var grpA = s.g(),
    grpE = s.g();

// Add to groups    
grpA.add(ball[0]).add(str[0]);
grpE.add(ball[4]).add(str[4]);

// The Loop
function leftOut() {
    grpA.animate({
        transform: 'r60, 200, -300'
    }, 600, mina.backout, function () {
        leftIn();
    });
}

function leftIn() {
    grpA.animate({
        transform: 'r0, 200, -300'
    }, 500, mina.backin, function () {
        rightOut();
    });
}

function rightOut() {
    grpE.animate({
        transform: 'r-60, 600, -300'
    }, 600, mina.backout, function () {
        rightIn();
    });
}

function rightIn() {
    grpE.animate({
        transform: 'r0, 600, -300'
    }, 500, mina.backin, function () {
        leftOut();
    });
}

// Init
leftOut();