JSFiddle - React, Tailwind, and code Playground

HTML

<html>
<head>
<title>jQuery.crSpline</title>
</head>
    
<body bgcolor="#333333">

<div id="settings">
<div class="option"><input type="checkbox" id="show-waypoints" checked="checked"> Show Waypoints</div>
<div class="option"><input type="checkbox" id="show-trail" checked="checked"> Show Trail</div>
</div>
    
</body>
</html>

CSS

.waypoint {
    position: absolute;
    z-index: 4;
    width: 20px;
    height: 20px;
    text-align: center;
    background-color: #7f9f7f;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
}

.path-dot {
    position: absolute;
    z-index: 1;
    width: 4px;
    height: 4px;
    font: 0px;
    background-color: #dca3a3;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
}

#mover {
    position: absolute;
    z-index: 5;
    width: 20px;
    height: 20px;
    background-color: #4f4faf;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
}

#snippet {
    float: left;
    clear: both;
    z-index: 0;
    color: #dcdccc;
    font-family: "Lucida Console", "Monaco", "Arial", "Verdana"
}

#snippet pre {
    font-family: "Lucida Console", "Monaco", "Arial", "Verdana"
}

#snippet a {
    /*color: #4f4faf;*/
    color: #5fbf5f;
    text-decoration: none;
}

#snippet a:hover {
    text-decoration: underline;
    color: #4fff4f;
}

#settings {
    float: left;
    clear: both;
    color: #dcdccc;
}

.option {
    clear: both;
}

* {
    border: 0;
    font-family: "Lucida Console", "Monaco", "Arial", "Verdana";
}

JavaScript

/**
 * jQuery.crSpline v0.0.2
 * http://github.com/MmmCurry/jquery.crSpline
 *
 * Supports animation along Catmull-Rom splines based on a series of waypoints.
 * Usage: See demo.js, demo.html
 * 
 * Copyright 2010, M. Ian Graham
 * MIT License
 *
 */

(function($){

        $.crSpline = {};

        // Catmull-Rom interpolation between p0 and p1 for previous point p_1 and later point p2
        // http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline
        var interpolate = function (t, p_1, p0, p1, p2) {
                return Math.floor((t * ((2 - t) * t - 1) * p_1 +
                        (t * t * (3 * t - 5) + 2) * p0 +
                        t * ((4 - 3 * t) * t + 1) * p1 +
                        (t - 1) * t * t * p2
                        ) / 2);
        };

        // Extend this p1,p2 sequence linearly to a new p3
        var generateExtension = function (p1, p2) {
                return [
                        p2[0] + (p2[0] - p1[0]),
                        p2[1] + (p2[1] - p1[1])
                        ];

        };

        // Return an animation object based on a sequence of points
        // pointList must be an array of [x,y] pairs
        $.crSpline.buildSequence = function(pointList) {
                var res = {};
                var seq = [];
                var numSegments;

                if (pointList.length < 2) {
                        throw "crSpline.buildSequence requires at least two points";
                }

                // Generate the first p_1 so the caller doesn't need to provide it
                seq.push(generateExtension(pointList[1], pointList[0]));

                // Throw provided points on the list
                for (var i = 0; i < pointList.length; i++) {
                        seq.push(pointList[i]);
                }

                // Generate the last p2 so the caller doesn't need to provide it
                seq.push(generateExtension(seq[seq.length-2],...