JSFiddle - React, Tailwind, and code Playground

by greenhulk01

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.2/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.2/plugins/animation.gsap.min.js"></script>
<div class="container" id="js-pinned">
    <div class="cnc" id="js-animation"></div>
</div>
<div id="graphics">
    <svg xmlns="http://www.w3.org/2000/svg" width="1000" height="800">
        <path d="M100 205 l420,0
         M520,205 A200,200,460 1 1 520,610
         M520,610 A200,200,460 1 1 520,205 
         
"></path>
        <g id="duplicate"></g>
    </svg>
    <canvas width="1000" height="800"></canvas>
</div>

CSS

body {
    text-align: center;
}
.container {
    min-height: 90vh;
}
.cnc {
    margin: auto;
    width: 240px;
    height: 240px;
    background: url('http://www.collection.wealdnet.co.uk/collections/sites/all/themes/mytheme/assets/css/images/section1_sprite.png') no-repeat 0 0%;
    background-size: 100%;
}
p {
    text-align:center;
    font-style:italic;
    margin:1em;
}
path {
    fill:transparent;
    stroke:#ccc;
    stroke-width:20
}
#duplicate path {
    pointer-events:none;
    stroke:#23ccdc;
    fill:none;
}
#graphics {
    width:800px;
    height:800px;
    margin:1em auto;
    position:relative;
}
#graphics * {
    position:absolute;
    top:0;
    left:0;
    width:1000px;
    height:800px
}

JavaScript

// initialise ScrollMagic controller
var controller = new ScrollMagic.Controller();

// create Tween
var tween = TweenMax.to("#js-animation", 1.0, {
    backgroundPosition: "0 100%",
    ease: SteppedEase.config(20)
});

// build scene
var scene = new ScrollMagic.Scene({
    duration: 1500
})
    .triggerHook("onCenter")
    .setPin("#js-pinned")
    .setTween(tween)
    .addTo(controller);

var distancePerPoint = 10;
var drawFPS = 200;

var orig = document.querySelector('path'),
    points, timer,
    canvas = document.querySelector('canvas'),
    ctx = canvas.getContext('2d');

canvas.addEventListener('mouseover', startDrawingPath, false);
canvas.addEventListener('mouseout', stopDrawingPath, false);

function startDrawingPath() {
    points = [];
    ctx.lineWidth = 20;
    ctx.strokeStyle = '#23ccdc';
    timer = setInterval(buildPath, 1000 / drawFPS);
}

function buildPath() {
    var nextPoint = points.length * distancePerPoint;
    var pathLength = orig.getTotalLength();
    if (nextPoint <= pathLength) {
        points.push(orig.getPointAtLength(nextPoint));
        redrawCanvas();
    }
}

function redrawCanvas() {
    clearCanvas();
    ctx.beginPath();
    ctx.moveTo(points[0].x, points[0].y);
    for (var i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y);
    ctx.stroke();
}

function clearCanvas() {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}

function stopDrawingPath() {
    clearInterval(timer);
    clearCanvas();
}