javascript 露西光滑滚动
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 露西光滑滚动相关的知识,希望对你有一定的参考价值。
/**
* Written by Mineo Okuda on 01/03/18.
*
* Mineo Okuda - development + design
* https://willstyle.co.jp
* https://github.com/min30327
*
* MIT license.
*/
var defaults = {
wrapper: '#luxy',
targets : '.luxy-el',
wrapperSpeed: 0.08,
targetSpeed: 0.02,
targetPercentage: 0.1
};
var requestAnimationFrame =
window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
/**
* Merge two or more objects. Returns a new object.
* @param {Object} objects The objects to merge together
* @returns {Object} Merged values of defaults and options
*/
var extend = function () {
// Variables
var extended = {};
var deep = false;
var i = 0;
var length = arguments.length;
// Merge the object into the extended object
var merge = function (obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
extended[prop] = obj[prop];
}
}
};
// Loop through each object and conduct a merge
for ( ; i < length; i++ ) {
var obj = arguments[i];
merge(obj);
}
return extended;
};
function Luxy(){
this.Targets = [];
this.TargetsLength = 0;
this.wrapper = '';
this.windowHeight = 0;
this.wapperOffset = 0;
};
Luxy.prototype.isAnimate = false;
Luxy.prototype.isResize = false;
Luxy.prototype.scrollId = "";
Luxy.prototype.resizeId = "";
Luxy.prototype.init = function(options){
this.settings = extend(defaults, options || {});
this.wrapper = document.querySelector(this.settings.wrapper);
if(this.wrapper==="undefined"){
return false;
}
this.targets = document.querySelectorAll(this.settings.targets);
document.body.style.height = this.wrapper.clientHeight + 'px';
this.windowHeight = window.clientHeight;
this.attachEvent();
this.apply(this.targets,this.wrapper);
this.animate();
this.resize();
};
Luxy.prototype.apply = function(targets,wrapper){
this.wrapperInit();
this.targetsLength = targets.length;
for (var i = 0; i < this.targetsLength; i++) {
var attr = {
offset : targets[i].getAttribute('data-offset'),
speedX : targets[i].getAttribute('data-speed-x'),
speedY : targets[i].getAttribute('data-speed-Y'),
percentage : targets[i].getAttribute('data-percentage'),
horizontal : targets[i].getAttribute('data-horizontal')
};
this.targetsInit(targets[i],attr);
}
};
Luxy.prototype.wrapperInit = function(){
this.wrapper.style.width = '100%';
this.wrapper.style.position = 'fixed';
};
Luxy.prototype.targetsInit = function(elm,attr){
this.Targets.push({
elm : elm,
offset : attr.offset ? attr.offset : 0,
horizontal : attr.horizontal ? attr.horizontal : 0,
top : 0,
left : 0,
speedX : attr.speedX ? attr.speedX : 1,
speedY : attr.speedY ? attr.speedY : 1,
percentage :attr.percentage ? attr.percentage : 0
});
};
Luxy.prototype.scroll = function(){
var scrollTopTmp = document.documentElement.scrollTop || document.body.scrollTop;
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var offsetBottom = this.scrollTop + this.windowHeight;
this.wrapperUpdate(this.scrollTop);
for (var i = 0; i < this.Targets.length; i++) {
this.targetsUpdate(this.Targets[i]);
}
};
Luxy.prototype.animate = function(){
this.scroll();
this.scrollId = requestAnimationFrame(this.animate.bind(this));
};
Luxy.prototype.wrapperUpdate = function(){
this.wapperOffset += (this.scrollTop - this.wapperOffset) * this.settings.wrapperSpeed;
this.wrapper.style.transform = 'translate3d(' + 0 + ',' + Math.round(-this.wapperOffset* 100) / 100 + 'px ,' + 0 + ')';
};
Luxy.prototype.targetsUpdate = function(target){
target.top += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedY) - target.top) * this.settings.targetPercentage;
target.left += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedX) - target.left) * this.settings.targetPercentage;
var targetOffsetTop = ( parseInt(target.percentage) - target.top - parseInt(target.offset) );
var offsetY = Math.round(targetOffsetTop * -100) / 100;
var offsetX = 0;
if(target.horizontal){
var targetOffsetLeft = ( parseInt(target.percentage) - target.left - parseInt(target.offset) );
offsetX = Math.round(targetOffsetLeft * -100) / 100;
}
target.elm.style.transform = 'translate3d(' + offsetX + 'px ,' + offsetY + 'px ,' + 0 +')';
};
Luxy.prototype.resize = function(){
var self = this;
self.windowHeight = (window.innerHeight || document.documentElement.clientHeight || 0);
if( parseInt(self.wrapper.clientHeight) != parseInt(document.body.style.height)){
document.body.style.height = self.wrapper.clientHeight + 'px';
}
self.resizeId = requestAnimationFrame(self.resize.bind(self));
};
Luxy.prototype.attachEvent = function(){
var self = this;
window.addEventListener('resize',function(){
if(!self.isResize){
cancelAnimationFrame(self.resizeId);
cancelAnimationFrame(self.scrollId);
self.isResize = true;
setTimeout(function(){
self.isResize = false;
self.resizeId = requestAnimationFrame(self.resize.bind(self));
self.scrollId = requestAnimationFrame(self.animate.bind(self));
},200);
}
});
};
var luxy = new Luxy();
/**
* Written by Mineo Okuda on 01/03/18.
*
* Mineo Okuda - development + design
* https://willstyle.co.jp
* https://github.com/min30327
*
* MIT license.
*/
const defaults = {
wrapper: '#luxy',
targets : '.luxy-el',
wrapperSpeed: 0.08,
targetSpeed: 0.02,
targetPercentage: 0.1
};
const requestAnimationFrame =
window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
const cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
/**
* Merge two or more objects. Returns a new object.
* @param {Object} objects The objects to merge together
* @returns {Object} Merged values of defaults and options
*/
const extend = function(...args) {
// Variables
const extended = {};
const deep = false;
let i = 0;
const length = args.length;
// Merge the object into the extended object
const merge = obj => {
for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
extended[prop] = obj[prop];
}
}
};
// Loop through each object and conduct a merge
for ( ; i < length; i++ ) {
const obj = args[i];
merge(obj);
}
return extended;
};
class Luxy {
constructor() {
this.Targets = [];
this.TargetsLength = 0;
this.wrapper = '';
this.windowHeight = 0;
this.wapperOffset = 0;
}
init(options) {
this.settings = extend(defaults, options || {});
this.wrapper = document.querySelector(this.settings.wrapper);
if(this.wrapper==="undefined"){
return false;
}
this.targets = document.querySelectorAll(this.settings.targets);
document.body.style.height = `${this.wrapper.clientHeight}px`;
this.windowHeight = window.clientHeight;
this.attachEvent();
this.apply(this.targets,this.wrapper);
this.animate();
this.resize();
}
apply(targets, wrapper) {
this.wrapperInit();
this.targetsLength = targets.length;
for (let i = 0; i < this.targetsLength; i++) {
const attr = {
offset : targets[i].getAttribute('data-offset'),
speedX : targets[i].getAttribute('data-speed-x'),
speedY : targets[i].getAttribute('data-speed-Y'),
percentage : targets[i].getAttribute('data-percentage'),
horizontal : targets[i].getAttribute('data-horizontal')
};
this.targetsInit(targets[i],attr);
}
}
wrapperInit() {
this.wrapper.style.width = '100%';
this.wrapper.style.position = 'fixed';
}
targetsInit(elm, attr) {
this.Targets.push({
elm,
offset : attr.offset ? attr.offset : 0,
horizontal : attr.horizontal ? attr.horizontal : 0,
top : 0,
left : 0,
speedX : attr.speedX ? attr.speedX : 1,
speedY : attr.speedY ? attr.speedY : 1,
percentage :attr.percentage ? attr.percentage : 0
});
}
scroll() {
const scrollTopTmp = document.documentElement.scrollTop || document.body.scrollTop;
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const offsetBottom = this.scrollTop + this.windowHeight;
this.wrapperUpdate(this.scrollTop);
for (let i = 0; i < this.Targets.length; i++) {
this.targetsUpdate(this.Targets[i]);
}
}
animate() {
this.scroll();
this.scrollId = requestAnimationFrame(this.animate.bind(this));
}
wrapperUpdate() {
this.wapperOffset += (this.scrollTop - this.wapperOffset) * this.settings.wrapperSpeed;
this.wrapper.style.transform = `translate3d(${0},${Math.round(-this.wapperOffset* 100) / 100}px ,${0})`;
}
targetsUpdate(target) {
target.top += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedY) - target.top) * this.settings.targetPercentage;
target.left += (this.scrollTop * Number(this.settings.targetSpeed) * Number(target.speedX) - target.left) * this.settings.targetPercentage;
const targetOffsetTop = ( parseInt(target.percentage) - target.top - parseInt(target.offset) );
const offsetY = Math.round(targetOffsetTop * -100) / 100;
let offsetX = 0;
if(target.horizontal){
const targetOffsetLeft = ( parseInt(target.percentage) - target.left - parseInt(target.offset) );
offsetX = Math.round(targetOffsetLeft * -100) / 100;
}
target.elm.style.transform = `translate3d(${offsetX}px ,${offsetY}px ,${0})`;
}
resize() {
const self = this;
self.windowHeight = (window.innerHeight || document.documentElement.clientHeight || 0);
if( parseInt(self.wrapper.clientHeight) != parseInt(document.body.style.height)){
document.body.style.height = `${self.wrapper.clientHeight}px`;
}
self.resizeId = requestAnimationFrame(self.resize.bind(self));
}
attachEvent() {
const self = this;
window.addEventListener('resize',() => {
if(!self.isResize){
cancelAnimationFrame(self.resizeId);
cancelAnimationFrame(self.scrollId);
self.isResize = true;
setTimeout(() => {
self.isResize = false;
self.resizeId = requestAnimationFrame(self.resize.bind(self));
self.scrollId = requestAnimationFrame(self.animate.bind(self));
},200);
}
});
}
}
Luxy.prototype.isAnimate = false;
Luxy.prototype.isResize = false;
Luxy.prototype.scrollId = "";
Luxy.prototype.resizeId = "";
const luxy = new Luxy();
以上是关于javascript 露西光滑滚动的主要内容,如果未能解决你的问题,请参考以下文章