JSFiddle - React, Tailwind, and code Playground

HTML

<div id="dot">:D</div><div id="centerline"></div>
<div id="commands">
    <button id="start" value="start">start</button>
    <button id="step" value="step">step</button>
    
    Vertical:
    <select id="vertical">
        <option value="sin">Sine</option>
        <option value="line">Linear</option>
        <option value="none">None</option>
    </select>
    Horizontal:
    <select id="horizontal">
        <option value="sin">Sine* (start at max)</option>
        <option value="line">Timeline</option>
        <option value="none" selected="selected">None</option>
    </select>
    <a href="#" id="showstatus">Stats</a>
    
    <div id="status" style="display: none;"></div>
</div>

CSS

body {
    font-family: Arial;
    font-size: 0.8em;
    width: 480px;
    overflow: hidden;
}

#commands {
    background: #fafafa;
    padding: 5px;
}

#dot {
    position: absolute;
    background: #FFFAAE;
    padding: 0.25em;
    top: 100;
    left: 100;
    width: 15px;
    border: 1px solid #333;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    z-index: 99;
}
#centerline {
    width: 450px;
    height: 1px;
    position: absolute;
    top: 109px;
    border-top: 1px solid #999;   
}

JavaScript

var horizontal = "none";
var vertical = "sin";

$('#showstatus').click(function(){
   $('#status').show(); 
});

$("#vertical").change(function() {
    vertical = $(this).val();
    render();
});

$("#horizontal").change(function() {
    horizontal = $(this).val();
    render();
});

isRunning = false;
$('#start').click(function() {

    if ($(this).text() == 'start') {
        isRunning = true;
        $(this).text('stop');
        $('#step').hide();
    }
    else {
        isRunning = false;
        $(this).text('start');
        $('#step').show();
    }
});

$('#step').click(function() {
    advance();
});

i = 0;
var step = 3;
delay = 50;
var topstart = 100;
var leftstart = 100;
var size = 50;

function advance() {
    i += step;
    i %= 360;
}

function render() {
    $el = $('#dot');

    var left;
    var top;

    switch (vertical) {
    case 'sin':
        top = topstart - Math.round(Math.sin(i * Math.PI / 180) * size);
        break;
    case 'line':
        var max = size;
        var height = 0;
        var offset = Math.round((i % 90) / 90 * size);
        if (i < 90) {
            height = offset;
        }
        else if (i < 180) {
            height = max - offset;
        }
        else if (i < 270) {
            height = -offset;
        }
        else {
            height = -(max - offset);
        }

        top = topstart - height;
        break;
    default:
        top = topstart;
    }

    switch (horizontal) {
    case 'sin':
        left = leftstart + Math.round(Math.sin((i + 90) * Math.PI / 180) * size);
        break;
    case 'line':
        left = leftstart + i;
        break;
    case 'none':
        break;
    default:
    }

    $el.css('top', top);
    $el.css('left', left);
}

function update() {
    render();

    var top = topstart - parseInt($('#dot').css('top'));
    var percent = Math.round((i) / 360.0 * 100.0);
    text = "";
    text += "Total cycle: " + percent + "%";
    var updown = percent * 4 % 100;
    text +=...