我使用 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);
谨防丑陋、未经重构、高度未经测试、未经优化的代码。仅为娱乐而创建。如果我有时间,可能稍后会在此基础上进行构建,并包含其他鼠标交互,例如 mousedown
、mousemove
、mouseup
以及触摸交互,例如 touchstart
、touchmove
、touchend
事件。应该很有趣。现在,您可以随意使用它。
关于javascript - 自定义GSAP "hacked"鼠标滚轮滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29930061/