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 露西光滑滚动的主要内容,如果未能解决你的问题,请参考以下文章

javascript 锚标签链接光滑滚动

text 光滑滚动jquery

javascript 更好的光滑箭头光滑禁用

javascript 调整引导选项卡内的光滑

javascript 光滑去滑块

javascript 光滑滑块3d