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';
...