JSFiddle - React, Tailwind, and code Playground

HTML

<div class='example'>
    <div class='spritespin'></div>
    <div class='hotspot spot1'>Spot 1</div>
    <div class='hotspot spot2'>Spot 2</div>
</div>

JavaScript

// manifest for spot 1
var manifestSpot1 = {
    frame_0: {  x: 0,   y: 150, size: 20 },
    frame_9: {  x: 200, y: 200, size: 30 },
    frame_19: { x: 400, y: 150, size: 20 },
    frame_29: { x: 200, y: 100, size: 10 }
}

// manifest for spot 2
var manifestSpot2 = {
    frame_0: {  x: 200, y:   0, size: 20 },
    frame_19: { x: 200, y: 200, size: 20 }
}

// interpolation function
function linearInterpolation(a, b, t){
    return a * (1 - t) + t * b; 
}

// interpolation logic
function interpolate(manifest, frame, totalFrames, key){
    // get the item at current frame
    var item = manifest["frame_" + String(frame)];
    if (item){
        // we have something defined for this frame. No interpolation needed
        return item[key];
    }
    
    var loFrame = frame, upFrame = frame, lower, upper, d1 = 0, d2 = 0;
    
    // find definition for the next lower framr
    while(!lower){
        d1 += 1; // accumulate total distance
        d2 += 1; // accumulate distance to lower frame
        loFrame -= 1;
        loFrame = loFrame < 0 ? totalFrames - 1 : loFrame;
        lower = manifest["frame_" + String(loFrame)];
    }
    // find definition for the next upper frame
    while(!upper){
        d1 += 1; // accumulate total distance
        upFrame += 1;
        upFrame = upFrame >= totalFrames ? 0 : upFrame;
        upper = manifest["frame_" + String(upFrame)];
    }

    // interpolation parameter in range [0:1]
    var t = d2 / d1;
    
    return linearInterpolation(lower[key], upper[key], t);
}

// preparation code
function prepareHotspots(){
    // this step can also be done with CSS only
    
    // apply relative position to the example element
    $('.example').css({
        position: "relative"
    });
    
    // apply absolute position attribute on all hotspot elements and hide them
    $('.hotspot').css({
        position: "absolute",
        background: "red",
        padding: "5px"
    }).hide();
}

// update function that updates a single...