@an1r0ny/skyline-swiper
Version:
微信小程序轮播组件 - 支持Skyline渲染模式
2 lines (1 loc) • 6.9 kB
JavaScript
const{shared:a,runOnJS:f,runOnUI:R,spring:_,timing:z,derived:T}=wx.worklet;Component({properties:{current:{type:Number,value:0},bounce:{type:Boolean,value:!0},vertical:{type:Boolean,value:!1},withAnimation:{type:Boolean,value:!1},cacheExtent:{type:Number,value:4},damping:{type:Number,value:20},mass:{type:Number,value:2},restDisplacementThreshold:{type:Number,value:.01},restSpeedThreshold:{type:Number,value:2},disabled:{type:Boolean,value:!1},circular:{type:Boolean,value:!1},minCircularSlides:{type:Number,value:4}},relations:{"./sky-swiper-slide":{type:"child",linked(e){const i=this.getRelationNodes("./sky-swiper-slide"),{cacheExtent:h}=this.data;i.forEach((s,t)=>{s.setData({index:t,cacheExtent:h})}),this._listLength.value=i.length,this._nodes=i,i.forEach(s=>{s._circular=this._circular,s._listLength=this._listLength,s._minCircularSlides=this._minCircularSlides,s._pxPerRpx=this._pxPerRpx})}}},data:{},observers:{current(e){this._listLength.value!==0&&(e<0||e>=this._listLength.value?console.warn("The target slide doesn't exist!"):this._width.value&&this._height.value&&this.setProgress({withAnimation:this.data.withAnimation}))},bounce(e){this._overshootClamping&&(this._overshootClamping.value=!e)},vertical(e){this._vertical&&(this._vertical.value=e)},damping(e){this._damping&&(this._damping.value=e)},mass(e){this._mass&&(this._mass.value=e)},restDisplacementThreshold(e){this._restDisplacementThreshold&&(this._restDisplacementThreshold.value=e)},restSpeedThreshold(e){this._restSpeedThreshold&&(this._restSpeedThreshold.value=e)},disabled(e){this._disabled&&(this._disabled.value=e)},circular(e){this._circular&&(this._circular.value=e)},minCircularSlides(e){this._minCircularSlides&&(this._minCircularSlides.value=e)}},lifetimes:{created(){this.initData()},attached(){},moved(){},detached(){},ready(){this.initSize()}},methods:{setSlideTransform(e){this._slideTransform=e},clearSlideTransform(){this._slideTransform=null},initData(){const e=wx.getWindowInfo(),{screenWidth:i}=e,{bounce:h,circular:s,minCircularSlides:t}=this.data,l=a(!1),n=a(1),r=a(1),d=a(750/i),o=a(0),b=a(20),y=a(2),C=a(h),x=a(.01),D=a(2),v=a(0),k=a(!1),w=a(s),S=a(t),L=c=>{this.triggerEvent("change",{current:c}),this._nodes.forEach(u=>{u.setData({current:c})})},g=a(0),P=T(()=>{"worklet";let c=Math.round(o.value/(l.value?r.value:n.value)),u=c;if(w.value&&v.value>=S.value){const m=l.value?r.value:n.value,p=v.value*m;if(o.value<0){const N=o.value%p;o.value=p+N,c=Math.round(o.value/m)}else o.value>=p&&(o.value=o.value%p,c=Math.round(o.value/m));u=(c%v.value+v.value)%v.value}else u<0?u=0:u>=v.value&&(u=v.value-1);return u!==g.value&&(g.value=u,u>=0&&u<v.value&&f(L)(u)),u}),E=T(()=>{"worklet";return Math.floor(o.value/(l.value?r.value:n.value))});this._vertical=l,this._width=n,this._height=r,this._pxPerRpx=d,this._progress=o,this._damping=b,this._mass=y,this._overshootClamping=C,this._restDisplacementThreshold=x,this._restSpeedThreshold=D,this._listLength=v,this._disabled=k,this._circular=w,this._minCircularSlides=S,this._index=g,this._curNum=P,this._current=E},async initSize(){const e=this.createSelectorQuery(),{width:i,height:h}=await new Promise(s=>{e.select(".skyline-swiper").fields({size:!0}).exec(t=>{s(t[0])})});this._width.value=i,this._height.value=h,this.setProgress()},setProgress({index:e,withAnimation:i}={}){const{current:h}=this.data;if(!i)this._progress.value=(this._vertical.value?this._height.value:this._width.value)*(e||h);else{const s={damping:this._damping.value,mass:this._mass.value,overshootClamping:this._overshootClamping.value,restSpeedThreshold:this._restSpeedThreshold.value,restDisplacementThreshold:this._restDisplacementThreshold.value};this._progress.value=_((this._vertical.value?this._height.value:this._width.value)*(e||h),s)}},onHDrag(e){"worklet";if(this._vertical.value)return;const{deltaX:i,state:h,velocityX:s}=e;if(h===2){if(this._progress.value-=i,this._circular.value&&this._listLength.value>=this._minCircularSlides.value){const t=this._listLength.value*this._width.value;if(this._progress.value<0){const l=this._progress.value%t;this._progress.value=t+l}else this._progress.value>=t&&(this._progress.value=this._progress.value%t)}}else if(h===3){const t=this.onTransitionEnd.bind(this),l=d=>{"worklet";f(t)(d)},n={velocity:-s/2,damping:this._damping.value,mass:this._mass.value,overshootClamping:this._overshootClamping.value,restSpeedThreshold:this._restSpeedThreshold.value,restDisplacementThreshold:this._restDisplacementThreshold.value};let r;if(s<-200?r=(this._current.value+1)*this._width.value:s>200?r=this._current.value*this._width.value:this._progress.value/this._width.value-this._current.value>.5?r=(this._current.value+1)*this._width.value:r=this._current.value*this._width.value,!this._circular.value||this._listLength.value<this._minCircularSlides.value){if(this._progress.value<0){this._progress.value=_(0,n,l);return}else if(this._progress.value>(this._listLength.value-1)*this._width.value){this._progress.value=_((this._listLength.value-1)*this._width.value,n,l);return}}this._progress.value=_(r,n,l)}},onVDrag(e){"worklet";if(!this._vertical.value)return;const{deltaY:i,state:h,velocityY:s}=e;if(h===2){if(this._progress.value-=i,this._circular.value&&this._listLength.value>=this._minCircularSlides.value){const t=this._listLength.value*this._height.value;if(this._progress.value<0){const l=this._progress.value%t;this._progress.value=t+l}else this._progress.value>=t&&(this._progress.value=this._progress.value%t)}}else if(h===3){const t=this.onTransitionEnd.bind(this),l=d=>{"worklet";f(t)(d)},n={velocity:-s/2,damping:this._damping.value,mass:this._mass.value,overshootClamping:this._overshootClamping.value,restSpeedThreshold:this._restSpeedThreshold.value,restDisplacementThreshold:this._restDisplacementThreshold.value};let r;if(s<-200?r=(this._current.value+1)*this._height.value:s>200?r=this._current.value*this._height.value:this._progress.value/this._height.value-this._current.value>.5?r=(this._current.value+1)*this._height.value:r=this._current.value*this._height.value,!this._circular.value||this._listLength.value<this._minCircularSlides.value){if(this._progress.value<0){this._progress.value=_(0,n,l);return}else if(this._progress.value>(this._listLength.value-1)*this._height.value){this._progress.value=_((this._listLength.value-1)*this._height.value,n,l);return}}this._progress.value=_(r,n,l)}},onTransitionEnd(e){if(!e)return;const i=Math.round(this._progress.value/(this._vertical.value?this._height.value:this._width.value));this.triggerEvent("transitionend",{current:i})},shouldHResponse(){"worklet";return!this._vertical.value&&!this._disabled.value},shouldHAcceptGesture(){"worklet";return!this._vertical.value&&!this._disabled.value},shouldVResponse(){"worklet";return this._vertical.value&&!this._disabled.value},shouldVAcceptGesture(){"worklet";return this._vertical.value&&!this._disabled.value}}});