javascript - 自定义GSAP "hacked"鼠标滚轮滚动

标签 javascript jquery scroll easing gsap

我使用 jQuery 和 GSAP 制作了一个自定义内容滚动器,目的是获得比 Chrome 基本和断断续续的滚动更好的效果。但当我用我的 Wacom 平板电脑(使用笔+水平滚动,或者我猜的任何触控板/触摸东西)测试它时,我刚刚看到(当时在 Chrome 上)滚动是滞后的并且有很多错误。

有什么想法可以通过调整来呈现更自然的滚动效果,而不是像现在这样被黑客攻击?
也许是与鼠标轮 DOMMouseScroll 事件有关,或者我的方法不好,标记/CSS 需要一些更改......?

$("section").on("mousewheel DOMMouseScroll", function (e) {
    e.preventDefault();

    var delta = e.originalEvent.wheelDelta / 120 || -e.originalEvent.detail; // Chrome || FF

    // Move thumbs
    TweenLite.to($("#photos"), 1.2, {
        scrollLeft: $("#photos").scrollLeft() - parseInt(delta * 35),
        ease: Expo.easeOut,
        overwrite: 5,
        onUpdate: move
    });
});

http://jsfiddle.net/h66tatp6/

非常感谢您的灯光!

最佳答案

煮了一些东西。不太确定它是否适合您的需求,或者它是否正是您正在寻找的东西的类型,但也许它会给您一些想法。

Codepen .

JavaScript:

/*global TweenMax,Power2,Power4*/
var initIntervalID=null,initInterval=10;
var scrollBar=document.querySelector('.scrollbar');
var scrollBarHandle=document.querySelector('.scrollbar__handle');
var scrollBarBg=document.querySelector('.scrollbar__bg');
var container=document.querySelector('.container');
var images=document.querySelector('.images');
var thumbs=document.querySelectorAll('.thumb');
var numThumbs=thumbs.length;
var resizeID=null,resizeTimeout=400,resizeDuration=.4,resizeEase=Power2.easeOut;
var initDuration=.4,initEase=Power2.easeOut,initStagger=.1;
var duration=.4,ease=Power2.easeOut;
var force3D=true;
var windowWidth=window.innerWidth;
var windowHeight=window.innerHeight;
var thumbWidth=200,thumbHeight=200,thumbGutter=20;
var scrollBarBgHeight=10,scrollBarBgWidth=thumbWidth,scrollBarHandleWidth=20,scrollBarGutter=10;
var imagesPositions=[],iterator=0,percentages=[],scrollBarHandlePositions=[];
function init(){
    initImages();
    initScrollbar();
    initPositions();
    assignListeners();
}
function onMouseWheel(event){
    var e=window.event||event;
    var delta=Math.max(-1,Math.min(1,(e.wheelDelta|| -e.detail)));
    if(delta>0){
        iterator-=1;
        if(iterator<0){
            iterator=0;
            TweenMax.to(images,duration*2,{bezier:{type:'thru',values:[{x:imagesPositions[iterator]+(thumbWidth+thumbGutter)*.1},{x:imagesPositions[iterator]}]},ease:ease});
            TweenMax.killTweensOf(scrollBar);
            TweenMax.to(scrollBar,duration,{autoAlpha:1,ease:ease});
            TweenMax.to(scrollBarHandle,duration*2,{
                transformOrigin:'left',
                bezier:{type:'thru',values:[{scaleX:.2},{scaleX:1}]},
                ease:ease,
                onComplete:function(){ TweenMax.to(scrollBar,duration,{autoAlpha:0,ease:ease}); }
            });
        }else{
            TweenMax.to(images,duration,{x:imagesPositions[iterator],ease:ease});
            TweenMax.killTweensOf(scrollBar);
            TweenMax.to(scrollBar,duration,{autoAlpha:1,ease:ease});
            TweenMax.to(scrollBarHandle,duration,{
                x:scrollBarHandlePositions[iterator],
                ease:ease,
                onComplete:function(){ TweenMax.to(scrollBar,duration,{autoAlpha:0,ease:ease}); }
            });
        }
    }else{
        iterator+=1;
        if(iterator>numThumbs-1){
            iterator=numThumbs-1;
            TweenMax.to(images,duration*2,{bezier:{type:'thru',values:[{x:imagesPositions[iterator]-(thumbWidth+thumbGutter)*.1},{x:imagesPositions[iterator]}]},ease:ease});
            TweenMax.killTweensOf(scrollBar);
            TweenMax.to(scrollBar,duration,{autoAlpha:1,ease:ease});
            TweenMax.to(scrollBarHandle,duration*2,{
                transformOrigin:'right',
                bezier:{type:'thru',values:[{scaleX:.2},{scaleX:1}]},
                ease:ease,
                onComplete:function(){ TweenMax.to(scrollBar,duration,{autoAlpha:0,ease:ease}); }
            });
        }else{
            TweenMax.to(images,duration,{x:imagesPositions[iterator],ease:ease});
            TweenMax.killTweensOf(scrollBar);
            TweenMax.to(scrollBar,duration,{autoAlpha:1,ease:ease});
            TweenMax.to(scrollBarHandle,duration,{
                x:scrollBarHandlePositions[iterator],
                ease:ease,
                onComplete:function(){ TweenMax.to(scrollBar,duration,{autoAlpha:0,ease:ease}); }
            });
        }
    }
    return false;
}
function listenToMouseWheel(){
    if(container.addEventListener){
        container.addEventListener('mousewheel',onMouseWheel,false);
        container.addEventListener('DOMMouseScroll',onMouseWheel,false);
    }else{
        container.attachEvent('onmousewheel',onMouseWheel);
    }
}
function adjustContainerOnResize(){
    windowWidth=window.innerWidth;
    windowHeight=window.innerHeight;
    TweenMax.to(container,resizeDuration,{
        x:windowWidth*.5-thumbWidth*.5,
        y:windowHeight*.5-thumbHeight*.5,
        ease:resizeEase,
        force3D:force3D
    });
}
function onResize(){
    clearTimeout(resizeID);
    resizeID=setTimeout(adjustContainerOnResize,resizeTimeout);
}
function listenToResize(){
    (window.addEventListener)?window.addEventListener('resize',onResize,false):window.attachEvent('onresize',onResize);
}
function assignListeners(){
    listenToResize();
    listenToMouseWheel();
}
function initPositions(){
    for(var i=0; i<numThumbs; i+=1){
        imagesPositions[i]=-i*(thumbWidth+thumbGutter);
        percentages[i]=i*(100/numThumbs);
        if(i===0){
            scrollBarHandlePositions[i]=0;
        }else if(i===numThumbs-1){
            scrollBarHandlePositions[i]=scrollBarBgWidth-scrollBarHandleWidth;
        }else{
            scrollBarHandlePositions[i]=i*(scrollBarBgWidth/(numThumbs-1))-scrollBarHandleWidth*.5;
        }
    }
}
function initScrollbar(){
    TweenMax.set(scrollBar,{
        y:scrollBarGutter,
        width:scrollBarBgWidth,
        height:scrollBarBgHeight,
        force3D:force3D
    });
    TweenMax.set(scrollBarHandle,{y:0,force3D:force3D});
    TweenMax.to(scrollBar,initDuration,{delay:initStagger,opacity:1,ease:initEase});
}
function initImages(){
    for(var i=0; i<numThumbs; i+=1){
        TweenMax.set(thumbs[i],{x:i*(thumbWidth+thumbGutter),force3D:force3D});
    }
    var width=numThumbs*(thumbWidth+thumbGutter)-thumbGutter;
    TweenMax.set(container,{y:windowHeight*.5-thumbHeight*.5,x:windowWidth*.5-thumbWidth*.5,height:thumbHeight+scrollBarGutter+scrollBarBgHeight,width:thumbWidth,force3D:force3D});
    TweenMax.set(images,{height:thumbHeight,width:width,force3D:force3D});
    TweenMax.staggerTo(thumbs,initDuration,{opacity:1,ease:initEase},initStagger);
}
initIntervalID=setInterval(function(){
    if(document.readyState==="complete"){
        clearInterval(initIntervalID);
        init();
    }
},initInterval);

谨防丑陋、未经重构、高度未经测试、未经优化的代码。仅为娱乐而创建。如果我有时间,可能稍后会在此基础上进行构建,并包含其他鼠标交互,例如 mousedownmousemovemouseup 以及触摸交互,例如 touchstarttouchmovetouchend 事件。应该很有趣。现在,您可以随意使用它。

关于javascript - 自定义GSAP "hacked"鼠标滚轮滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29930061/

相关文章:

jQuery.validate.js 和 asp.net 母版页

jquery - 如何使用等列脚本重新计算高度

scroll - 垂直滚动不适用于 ionic 中的水平滚动列表

android - ListView 和可变高度项目导致滚动问题

java - 滚动RecyclerView时Cardview的数据发生变化

javascript - 当当前时间戳大于现有列中的固定时间戳值时删除记录

javascript - 单击div时缓慢出现

javascript - mongodb从facet返回对象

jquery - 在 DropDown/HTML 选择 Show Modal PopUp

javascript - 用于仅匹配和替换 excel 公式字符串中的列号数字的正则表达式