JSFiddle - React, Tailwind, and code Playground

by mrmartineau

HTML

<div id='obj1'>Scroll Slow</div>
<div id='obj2'>Scroll Fast</div>
<div id='obj3'>Scroll Down</div>
<div id='obj4'>Scroll Up</div>
<div id='test'></div>
<div id='instructions'>
    <p>
    Hold the mouse down and move it left or right to "scroll".
    </p>
    <p>
        Moving left to right will advance everything
    </p>
    <p>
       Moving right to left will reverse
    </p>
</div>

CSS

body{
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0px;
    left: 0px;
    background-color: #ddd;
}

div {
    position: absolute;
}

#instructions{
    top: 200px;           
}

#test{
   top: 300px;   
}

JavaScript

var Parallax = function(objs){
    this.mouse = new this.mouse();
    
    this.pos = 0;
    this.dist = 0;
    this.queue = [];
    this.objs = objs;
    this.max = 0;
    this.speed = 200;
    this.width = document.body.offsetWidth;
    this.height = document.body.offsetHeight;
    
    for (var i=0; i<this.objs.length; i++){
        if (this.objs[i].start + this.objs[i].duration > this.max){ 
            this.max = this.objs[i].start + this.objs[i].duration;
        }
    }
}

Parallax.prototype.scroll = function(dist){
    this.dist += dist;
    var self = this;
    
    var t = setInterval(function(){
        if (self.dist < 0 && self.pos > 0){
            self.advanceFrame();
            self.dist++;
            self.pos--;
        } else if (self.dist > 0 && self.pos < self.max) {
            self.advanceFrame();
            self.dist--;
            self.pos++;
        } else {
            self.dist = 0;
            clearInterval(t);
        }
    }, this.speed)
}

//This is where the majig happens
Parallax.prototype.advanceFrame = function(){
    //reset the queue, then add any current objs to it and hide non-current
    this.queue = [];
    for (var i=0; i<this.objs.length; i++){
        if (
            this.objs[i].start <= this.pos && 
            (this.objs[i].start + this.objs[i].duration) >= this.pos
        ){
            this.queue.push(this.objs[i]);
        } else {
            document.getElementById(this.objs[i].id).style.display = 'none';
        }
    }
    
    //now for everything in the queue position it where it should be
        
    for (var i=0; i<this.queue.length; i++){
        var obj = this.queue[i],
            element = document.getElementById(obj.id),
            frame =(this.pos - obj.start) / obj.duration,
            left = (obj.startLeft+((obj.endLeft - obj.startLeft)*frame)) | 0,
            top = (obj.startTop+((obj.endTop - obj.startTop)*frame)) | 0;
        
        element.style.display = 'block';
       ...