smooothy
Version:
**Tiny real smooth fast cool all events _bring your own tooling slider._ Framework agnostic but it's a you problem.**
4 lines (2 loc) • 18.4 kB
JavaScript
var B=Object.create;var{getPrototypeOf:G,defineProperty:O,getOwnPropertyNames:U}=Object;var A=Object.prototype.hasOwnProperty;var N=(o,u,h)=>{h=o!=null?B(G(o)):{};let b=u||!o||!o.__esModule?O(h,"default",{value:o,enumerable:!0}):h;for(let _ of U(o))if(!A.call(b,_))O(b,_,{get:()=>o[_],enumerable:!0});return b};var i=(o,u)=>()=>(u||o((u={exports:{}}).exports,u),u.exports);var L=i((Q,Z)=>{(function(o,u){typeof Q=="object"&&typeof Z!="undefined"?Z.exports=u():typeof define=="function"&&define.amd?define(u):(o||self).virtualScroll=u()})(Q,function(){var o=0;function u(K){return"__private_"+o+++"_"+K}function h(K,j){if(!Object.prototype.hasOwnProperty.call(K,j))throw new TypeError("attempted to use private field on non-instance");return K}function b(){}b.prototype={on:function(K,j,n){var y=this.e||(this.e={});return(y[K]||(y[K]=[])).push({fn:j,ctx:n}),this},once:function(K,j,n){var y=this;function c(){y.off(K,c),j.apply(n,arguments)}return c._=j,this.on(K,c,n)},emit:function(K){for(var j=[].slice.call(arguments,1),n=((this.e||(this.e={}))[K]||[]).slice(),y=0,c=n.length;y<c;y++)n[y].fn.apply(n[y].ctx,j);return this},off:function(K,j){var n=this.e||(this.e={}),y=n[K],c=[];if(y&&j)for(var X=0,P=y.length;X<P;X++)y[X].fn!==j&&y[X].fn._!==j&&c.push(y[X]);return c.length?n[K]=c:delete n[K],this}};var _=b;_.TinyEmitter=b;var f,E="virtualscroll",Y=u("options"),s=u("el"),M=u("emitter"),v=u("event"),k=u("touchStart"),l=u("bodyTouchAction");return function(){function K(n){var y=this;Object.defineProperty(this,Y,{writable:!0,value:void 0}),Object.defineProperty(this,s,{writable:!0,value:void 0}),Object.defineProperty(this,M,{writable:!0,value:void 0}),Object.defineProperty(this,v,{writable:!0,value:void 0}),Object.defineProperty(this,k,{writable:!0,value:void 0}),Object.defineProperty(this,l,{writable:!0,value:void 0}),this._onWheel=function(c){var X=h(y,Y)[Y],P=h(y,v)[v];P.deltaX=c.wheelDeltaX||-1*c.deltaX,P.deltaY=c.wheelDeltaY||-1*c.deltaY,f.isFirefox&&c.deltaMode===1&&(P.deltaX*=X.firefoxMultiplier,P.deltaY*=X.firefoxMultiplier),P.deltaX*=X.mouseMultiplier,P.deltaY*=X.mouseMultiplier,y._notify(c)},this._onMouseWheel=function(c){var X=h(y,v)[v];X.deltaX=c.wheelDeltaX?c.wheelDeltaX:0,X.deltaY=c.wheelDeltaY?c.wheelDeltaY:c.wheelDelta,y._notify(c)},this._onTouchStart=function(c){var X=c.targetTouches?c.targetTouches[0]:c;h(y,k)[k].x=X.pageX,h(y,k)[k].y=X.pageY},this._onTouchMove=function(c){var X=h(y,Y)[Y];X.preventTouch&&!c.target.classList.contains(X.unpreventTouchClass)&&c.preventDefault();var P=h(y,v)[v],q=c.targetTouches?c.targetTouches[0]:c;P.deltaX=(q.pageX-h(y,k)[k].x)*X.touchMultiplier,P.deltaY=(q.pageY-h(y,k)[k].y)*X.touchMultiplier,h(y,k)[k].x=q.pageX,h(y,k)[k].y=q.pageY,y._notify(c)},this._onKeyDown=function(c){var X=h(y,v)[v];X.deltaX=X.deltaY=0;var P=window.innerHeight-40;switch(c.keyCode){case 37:case 38:X.deltaY=h(y,Y)[Y].keyStep;break;case 39:case 40:X.deltaY=-h(y,Y)[Y].keyStep;break;case 32:X.deltaY=P*(c.shiftKey?1:-1);break;default:return}y._notify(c)},h(this,s)[s]=window,n&&n.el&&(h(this,s)[s]=n.el,delete n.el),f||(f={hasWheelEvent:"onwheel"in document,hasMouseWheelEvent:"onmousewheel"in document,hasTouch:"ontouchstart"in document,hasTouchWin:navigator.msMaxTouchPoints&&navigator.msMaxTouchPoints>1,hasPointer:!!window.navigator.msPointerEnabled,hasKeyDown:"onkeydown"in document,isFirefox:navigator.userAgent.indexOf("Firefox")>-1}),h(this,Y)[Y]=Object.assign({mouseMultiplier:1,touchMultiplier:2,firefoxMultiplier:15,keyStep:120,preventTouch:!1,unpreventTouchClass:"vs-touchmove-allowed",useKeyboard:!0,useTouch:!0},n),h(this,M)[M]=new _,h(this,v)[v]={y:0,x:0,deltaX:0,deltaY:0},h(this,k)[k]={x:null,y:null},h(this,l)[l]=null,h(this,Y)[Y].passive!==void 0&&(this.listenerOptions={passive:h(this,Y)[Y].passive})}var j=K.prototype;return j._notify=function(n){var y=h(this,v)[v];y.x+=y.deltaX,y.y+=y.deltaY,h(this,M)[M].emit(E,{x:y.x,y:y.y,deltaX:y.deltaX,deltaY:y.deltaY,originalEvent:n})},j._bind=function(){f.hasWheelEvent&&h(this,s)[s].addEventListener("wheel",this._onWheel,this.listenerOptions),f.hasMouseWheelEvent&&h(this,s)[s].addEventListener("mousewheel",this._onMouseWheel,this.listenerOptions),f.hasTouch&&h(this,Y)[Y].useTouch&&(h(this,s)[s].addEventListener("touchstart",this._onTouchStart,this.listenerOptions),h(this,s)[s].addEventListener("touchmove",this._onTouchMove,this.listenerOptions)),f.hasPointer&&f.hasTouchWin&&(h(this,l)[l]=document.body.style.msTouchAction,document.body.style.msTouchAction="none",h(this,s)[s].addEventListener("MSPointerDown",this._onTouchStart,!0),h(this,s)[s].addEventListener("MSPointerMove",this._onTouchMove,!0)),f.hasKeyDown&&h(this,Y)[Y].useKeyboard&&document.addEventListener("keydown",this._onKeyDown)},j._unbind=function(){f.hasWheelEvent&&h(this,s)[s].removeEventListener("wheel",this._onWheel),f.hasMouseWheelEvent&&h(this,s)[s].removeEventListener("mousewheel",this._onMouseWheel),f.hasTouch&&(h(this,s)[s].removeEventListener("touchstart",this._onTouchStart),h(this,s)[s].removeEventListener("touchmove",this._onTouchMove)),f.hasPointer&&f.hasTouchWin&&(document.body.style.msTouchAction=h(this,l)[l],h(this,s)[s].removeEventListener("MSPointerDown",this._onTouchStart,!0),h(this,s)[s].removeEventListener("MSPointerMove",this._onTouchMove,!0)),f.hasKeyDown&&h(this,Y)[Y].useKeyboard&&document.removeEventListener("keydown",this._onKeyDown)},j.on=function(n,y){h(this,M)[M].on(E,n,y);var c=h(this,M)[M].e;c&&c[E]&&c[E].length===1&&this._bind()},j.off=function(n,y){h(this,M)[M].off(E,n,y);var c=h(this,M)[M].e;(!c[E]||c[E].length<=0)&&this._unbind()},j.destroy=function(){h(this,M)[M].off(),this._unbind()},K}()})});var w=N(L(),1);function D(o,u,h){return o*(1-h)+u*h}function J(o,u,h,b){let _=1-Math.exp(-h*b);return o+(u-o)*_}function W(o,u){let h=o%u;if(Math.abs(h)>u/2)h=h>0?h-u:h+u;return h}var m={infinite:!0,snap:!0,variableWidth:!1,vertical:!1,dragSensitivity:0.005,lerpFactor:0.3,scrollSensitivity:1,snapStrength:0.1,speedDecay:0.85,bounceLimit:1,virtualScroll:{mouseMultiplier:0.5,touchMultiplier:2,firefoxMultiplier:30,useKeyboard:!1,passive:!0},setOffset:({itemWidth:o,wrapperWidth:u,itemHeight:h,wrapperHeight:b,vertical:_})=>_?h:o,scrollInput:!1};class ${speed=0;#M=0;#y=0;#Y=0;deltaTime=0;#h=!0;#o=!1;#u=0;#X=0;config;wrapper;items;viewport;itemWidths=[];itemOffsets=[];itemHeights=[];itemHeightOffsets=[];isDragging=!1;isTouching=!1;dragStart=0;dragStartTarget=0;isVisible=!1;current=0;target=0;maxScroll=0;resizeTimeout;virtualScroll;observer;touchStartY;touchStartX;touchPreviousX;touchPreviousY;scrollDirection;parallaxValues;webglValue=0;onSlideChange;onResize;onUpdate;constructor(o,u={}){if(this.config={...m,...u},u.onSlideChange)this.onSlideChange=u.onSlideChange;if(u.onResize)this.onResize=u.onResize;if(u.onUpdate)this.onUpdate=u.onUpdate;if(delete this.config.onSlideChange,delete this.config.onResize,delete this.config.onUpdate,this.wrapper=o,this.items=[...o.children],this.current=0,this.target=0,this.isDragging=!1,this.isTouching=!1,this.dragStart=0,this.dragStartTarget=0,this.isVisible=!1,this.#u=0,this.#X=0,this.#n(),this.#l(),this.#W(),this.wrapper.style.cursor="grab",this.#n(),this.#q(),this.config.variableWidth&&!this.config.infinite&&this.items.length>0){let h=this.#s(0);this.target=h,this.current=h,this.#P()}}#l(){let o={root:null,rootMargin:"50px",threshold:0};this.observer=new IntersectionObserver((u)=>{u.forEach((h)=>{this.isVisible=h.isIntersecting})},o),this.observer.observe(this.wrapper)}#n(){let o=this.items.map((s)=>s.getBoundingClientRect().width),u=this.items.map((s)=>s.getBoundingClientRect().height),h=this.wrapper.clientWidth,b=this.wrapper.clientHeight,_=o.reduce((s,M)=>s+M,0),f=u.reduce((s,M)=>s+M,0),E=0;this.itemOffsets=o.map((s)=>{let M=E;return E+=s,M}),this.itemWidths=o;let Y=0;if(this.itemHeightOffsets=u.map((s)=>{let M=Y;return Y+=s,M}),this.itemHeights=u,this.viewport={itemWidth:o[0]??0,wrapperWidth:h,totalWidth:_,itemHeight:u[0]??0,wrapperHeight:b,totalHeight:f,vertical:this.config.vertical},this.#y=this.config.setOffset(this.viewport),this.config.variableWidth)if(this.config.vertical)this.maxScroll=-(this.viewport.totalHeight-this.#y);else this.maxScroll=-(this.viewport.totalWidth-this.#y);else{let s=this.config.vertical?this.viewport.itemHeight||1:this.viewport.itemWidth||1,M=this.config.vertical?this.viewport.totalHeight:this.viewport.totalWidth;this.maxScroll=-(M-this.#y)/s}queueMicrotask(()=>{this.onResize?.(this)})}#W(){let o=(s)=>this.#c(s),u=(s)=>this.#b(s),h=()=>this.#_();this.wrapper.addEventListener("mousedown",o),window.addEventListener("mousemove",u),window.addEventListener("mouseup",h);let b=5,_=(s)=>{let M=s.touches[0];this.touchStartY=M.clientY,this.touchStartX=M.clientX,this.touchPreviousX=M.clientX,this.touchPreviousY=M.clientY,this.scrollDirection=void 0,this.isTouching=!0,this.#c(M)},f=(s)=>{if(!this.isTouching||this.#o)return;let M=s.touches[0],v=Math.abs(M.clientY-this.touchStartY),k=Math.abs(M.clientX-this.touchStartX);if(!this.scrollDirection&&(k>b||v>b))this.scrollDirection=k>v?"horizontal":"vertical";if(this.config.vertical?this.scrollDirection==="vertical":this.scrollDirection==="horizontal")if(s.preventDefault(),this.#b(M),this.config.vertical)this.touchPreviousY=M.clientY;else this.touchPreviousX=M.clientX},E=()=>{this.isTouching=!1,this.scrollDirection=void 0,this.touchPreviousX=void 0,this.touchPreviousY=void 0,this.#_()};this.wrapper.addEventListener("touchstart",_),window.addEventListener("touchmove",f,{passive:!1}),window.addEventListener("touchend",E),new ResizeObserver(()=>{if(this.resizeTimeout)clearTimeout(this.resizeTimeout);this.resizeTimeout=setTimeout(()=>this.resize(),10)}).observe(this.wrapper)}#j(o){if(!this.config.infinite){let u=this.config.vertical?this.viewport.itemHeight:this.viewport.itemWidth,h=this.config.variableWidth&&u?this.config.bounceLimit*u:this.config.bounceLimit;if(o>h)return h;else if(o<this.maxScroll-h)return this.maxScroll-h}return o}#q(){this.virtualScroll=new w.default({...this.config.virtualScroll,el:this.wrapper});let o=5;this.virtualScroll.on((u)=>{if(!this.isDragging&&!this.#o){if(u.touchDevice){let E=Math.abs(u.deltaY),Y=Math.abs(u.deltaX);if(E<o&&Y<o)return;if(this.config.vertical){if(Y>E)return}else if(E>Y)return}let h=this.config.vertical?!this.config.scrollInput?u.deltaY:Math.abs(u.deltaY)>Math.abs(u.deltaX)?u.deltaY:u.deltaX:!this.config.scrollInput?u.deltaX:Math.abs(u.deltaX)>Math.abs(u.deltaY)?u.deltaX:u.deltaY,b=this.config.variableWidth?this.config.scrollSensitivity:this.config.scrollSensitivity*0.001,_=h*b,f=this.target+_;if(!this.config.infinite){if(f>0)f=0;else if(f<this.maxScroll)f=this.maxScroll}this.target=this.#j(f),this.speed=-_*(this.config.variableWidth?0.1:10)}})}#c(o){if(this.#o)return;this.isDragging=!0,this.dragStart=this.config.vertical?o.clientY:o.clientX,this.dragStartTarget=this.target,this.wrapper.style.cursor="grabbing"}#b(o){if(!this.isDragging||this.#o)return;let u=this.config.vertical?o.clientY-this.dragStart:o.clientX-this.dragStart,h=this.config.variableWidth?1:this.config.dragSensitivity,b=this.dragStartTarget+u*h;if(this.target=this.#j(b),"movementX"in o){let _=this.config.vertical?o.movementY:o.movementX;this.speed+=_*0.01}else{let _=this.config.vertical?o.clientY:o.clientX,f=this.config.vertical?this.touchPreviousY||_:this.touchPreviousX||_,E=_-f;this.speed+=E*0.01}}#_(){if(this.isDragging=!1,this.wrapper.style.cursor="grab",this.config.variableWidth){if(!this.config.infinite){if(this.target>0)this.target=0;else if(this.target<this.maxScroll)this.target=this.maxScroll}if(this.config.snap)this.target=this.#v(this.target)}else if(!this.config.infinite){if(this.target>0)this.target=0;else if(this.target<this.maxScroll)this.target=this.maxScroll;else if(this.config.snap){let o=Math.round(this.target);this.target=Math.min(0,Math.max(this.maxScroll,o))}}else if(this.config.snap)this.target=Math.round(this.target)}update(){if(!this.isVisible||!this.#h)return;let o=performance.now();if(this.deltaTime=(o-this.#Y)/1000,this.#Y=o,this.config.snap&&!this.isDragging)if(this.config.variableWidth){let h=this.#v(this.target)-this.target;this.target+=h*this.config.snapStrength}else{let h=Math.round(this.target)-this.target;this.target+=h*this.config.snapStrength}if(this.current=J(this.current,this.target,1/this.config.lerpFactor,this.deltaTime),this.config.infinite)if(this.config.variableWidth){let u=this.config.vertical?this.viewport.wrapperHeight/2:this.viewport.wrapperWidth/2,h=this.#E(-this.current+u),b=this.#K(h);this.#f(b),this.#Z()}else{let u=Math.round(-this.current),h=this.items.length,b=(u%h+h)%h;this.#f(b),this.#Q()}else if(this.config.variableWidth){let u=this.config.vertical?this.viewport.wrapperHeight/2:this.viewport.wrapperWidth/2,h=this.config.vertical?this.viewport.totalHeight:this.viewport.totalWidth,b=Math.max(0,Math.min(-this.current+u,h));this.#f(this.#K(b)),this.#P()}else this.#f(Math.round(Math.abs(this.current))),this.#J();this.#$(),this.onUpdate?.(this)}#J(){this.parallaxValues=this.items.map((o,u)=>{let h=this.config.vertical?this.current*this.viewport.itemHeight:this.current*this.viewport.itemWidth,b=this.config.vertical?`translateY(${h}px)`:`translateX(${h}px)`;return o.style.transform=b,h})}#Q(){this.parallaxValues=this.items.map((o,u)=>{let h=this.current+u,b=W(h,this.items.length)-u,_=this.config.vertical?this.viewport.itemHeight:this.viewport.itemWidth,f=b*_,E=this.config.vertical?`translateY(${f}px)`:`translateX(${f}px)`;return o.style.transform=E,W(h,this.items.length)})}#k(o){if(this.config.vertical){let u=this.itemHeights[o]??this.viewport.itemHeight??0;return(this.itemHeightOffsets[o]??0)+u/2}else{let u=this.itemWidths[o]??this.viewport.itemWidth??0;return(this.itemOffsets[o]??0)+u/2}}#s(o){let u=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1,h=this.config.vertical?this.viewport.wrapperHeight/2:this.viewport.wrapperWidth/2,_=-(this.#k(o)-h);if(this.config.infinite){let f=Math.round((this.target-_)/u);_+=f*u}else _=Math.min(0,Math.max(this.maxScroll,_));return _}#E(o){let u=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1;return(o%u+u)%u}#K(o){let u=this.config.vertical?this.itemHeightOffsets:this.itemOffsets;if(!u.length)return 0;let h=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1,b=this.config.infinite?this.#E(o):Math.max(0,Math.min(o,h)),_=0,f=Number.POSITIVE_INFINITY;return u.forEach((E,Y)=>{let s=this.#k(Y),M=Math.abs(b-s);if(M<f)f=M,_=Y}),_}#v(o){if(!(this.config.vertical?this.itemHeightOffsets:this.itemOffsets).length)return o;let h=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1,b=this.config.vertical?this.viewport.wrapperHeight/2:this.viewport.wrapperWidth/2,_=this.config.infinite?this.#E(-o+b):Math.max(0,Math.min(-o+b,h)),f=this.#K(_);return this.#s(f)}#P(){this.parallaxValues=this.items.map((o,u)=>{let h=this.current,b=this.config.vertical?this.itemHeightOffsets:this.itemOffsets,_=this.config.vertical?`translateY(${h}px)`:`translateX(${h}px)`;return o.style.transform=_,h+b[u]})}#Z(){let o=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1;this.parallaxValues=this.items.map((u,h)=>{let _=(this.config.vertical?this.itemHeightOffsets:this.itemOffsets)[h]??0,f=W(this.current+_,o)-_,E=this.config.vertical?`translateY(${f}px)`:`translateX(${f}px)`;return u.style.transform=E,W(this.current+_,o)})}#$(){this.#M=J(this.#M,this.speed,1/this.config.lerpFactor,this.deltaTime),this.speed*=this.config.speedDecay}goToNext(){if(this.config.variableWidth){let o=this.config.infinite?(this.currentSlide+1)%this.items.length:Math.min(this.currentSlide+1,this.items.length-1);this.target=this.#s(o)}else if(!this.config.infinite)this.target=Math.max(this.maxScroll,Math.round(this.target-1));else this.target=Math.round(this.target-1)}goToPrev(){if(this.config.variableWidth){let o=this.config.infinite?(this.currentSlide-1+this.items.length)%this.items.length:Math.max(this.currentSlide-1,0);this.target=this.#s(o)}else if(!this.config.infinite)this.target=Math.min(0,Math.round(this.target+1));else this.target=Math.round(this.target+1)}goToIndex(o){if(this.config.variableWidth){let u=this.config.infinite?(o%this.items.length+this.items.length)%this.items.length:Math.min(Math.max(o,0),this.items.length-1);this.target=this.#s(u)}else this.target=-o}set snap(o){this.config.snap=o}getProgress(){if(this.config.variableWidth){let h=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1;return(-this.current%h+h)%h/h}let o=this.items.length;return Math.abs(this.current)%o/o}destroy(){if(this.kill(),window.removeEventListener("mousemove",(o)=>this.#b(o)),window.removeEventListener("mouseup",()=>this.#_()),window.removeEventListener("touchmove",(o)=>{let u=o.touches[0];this.#b(u)}),window.removeEventListener("touchend",()=>this.#_()),this.wrapper.removeEventListener("mousedown",(o)=>this.#c(o)),this.wrapper.removeEventListener("touchstart",(o)=>{let u=o.touches[0];this.#c(u)}),this.resizeTimeout)clearTimeout(this.resizeTimeout);if(this.virtualScroll&&this.config.scrollInput)this.virtualScroll.destroy();if(this.observer)this.observer.disconnect()}get currentSlide(){return this.#u}#f(o){if(this.#u!==o)this.#X=this.#u,this.#u=o,this.onSlideChange?.(this.#u,this.#X)}kill(){this.#h=!1,this.items.forEach((o)=>{o.style.transform=""}),this.current=0,this.target=0,this.speed=0,this.#M=0,this.touchPreviousX=void 0,this.touchPreviousY=void 0,this.isTouching=!1}init(){this.#h=!0,this.#Y=performance.now()}set paused(o){this.#o=o}get paused(){return this.#o}get progress(){if(this.config.variableWidth){let o=this.config.vertical?this.viewport.totalHeight||1:this.viewport.totalWidth||1,u=-this.target;if(this.config.infinite)return(u%o+o)%o/o;else return Math.max(0,Math.min(u,o))/o}else if(this.config.infinite){let o=-this.target,u=this.items.length;return(o%u+u)%u/(u-1)}else{let o=Math.abs(this.current),u=Math.abs(this.maxScroll);return Math.max(0,Math.min(1,o/u))}}resize(){if(this.#n(),this.config.variableWidth&&!this.config.infinite&&this.items.length>0){let h=this.currentSlide,b=this.#s(h);if(this.target=b,Math.abs(this.current-this.target)<1)this.current=b}let o=this.#h,u=this.isVisible;this.#h=!0,this.isVisible=!0,this.update(),this.#h=o,this.isVisible=u}}var x=$;export{W as symmetricMod,D as lerp,x as default,J as damp};
//# debugId=3B8E3AAB506C28C164756E2164756E21