@imengyu/vue-scroll-rect
Version:
A scroll rect component for Vue3
3 lines (2 loc) • 8.46 kB
JavaScript
(function(i,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],o):(i=typeof globalThis<"u"?globalThis:i||self,o(i["vue-scroll-rect"]={},i.Vue))})(this,function(i,o){"use strict";var ie=Object.defineProperty;var ce=(i,o,g)=>o in i?ie(i,o,{enumerable:!0,configurable:!0,writable:!0,value:g}):i[o]=g;var H=(i,o,g)=>ce(i,typeof o!="symbol"?o+"":o,g);class g{constructor(c,r){H(this,"x",0);H(this,"y",0);this.x=c||0,this.y=r||0}set(c,r){this.x=c,this.y=r}substract(c){this.x-=c.x,this.y-=c.y}}function B(t){const{onDown:c,onMove:r,onUp:s}=t,a=new g,e=new g;let m;function v(f){f.stopPropagation(),e.set(f.x,f.y),e.substract(a),r(a,e,f,m)}function p(f){s(f,m),a.set(0,0),document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",p)}return(f,T)=>c(f,T)?(m=T,a.set(f.x,f.y),document.addEventListener("mousemove",v),document.addEventListener("mouseup",p),f.stopPropagation(),!0):!1}function F(t){const{onDown:c,onUp:r}=t;function s(a){r(a),document.removeEventListener("mouseup",s)}return a=>c(a)?(document.addEventListener("mouseup",s),a.preventDefault(),a.stopPropagation(),!0):!1}function G(t,c){let r=0;return{start(){r>0&&clearTimeout(r),r=setTimeout(()=>{r=0,c()},t)},stop(){r>0&&(clearTimeout(r),r=0)}}}function C(t,c){let r=0;return{start(){r>0&&clearInterval(r),r=setInterval(()=>{r=0,c()},t)},stop(){r>0&&(clearInterval(r),r=0)}}}const S=[],D=C(100,()=>{for(const t of S)t()});function R(t,c,r,s){let a=0,e=0;function m(){t.value&&(c&&a!==t.value.offsetWidth&&c(t.value.offsetWidth),r&&e!==t.value.offsetHeight&&r(t.value.offsetHeight),s&&(a!==t.value.offsetWidth||e!==t.value.offsetHeight)&&s(t.value.offsetWidth,t.value.offsetHeight),a=t.value.offsetWidth,e=t.value.offsetHeight)}return{startResizeChecker(){D.start(),S.push(m)},stopResizeChecker(){const v=S.indexOf(m);v>=0&&S.splice(v,1),S.length===0&&D.stop()}}}const Y=140,J=70,x=o.defineComponent({__name:"ScrollRect",props:{scroll:{type:String,default:"both"},scrollBarAlwaysShow:{type:Boolean,default:!1},scrollBarBackgroundClickable:{type:Boolean,default:!1},height:{type:Number,default:void 0},width:{type:Number,default:void 0},maxHeight:{type:Number,default:void 0},maxWidth:{type:Number,default:void 0},containerClass:{type:String,default:""},containerStyle:{type:null},scrollToStartThreshold:{type:Number,default:50},scrollToEndThreshold:{type:Number,default:50}},emits:["scroll","resized","scrollToStart","scrollToEnd"],setup(t,{expose:c,emit:r}){const s=t,a=r,e=o.ref(),m=o.ref(),v=o.ref(),p=o.ref(),f=o.ref(),T=o.ref(),y=o.ref(!1),Q=o.computed(()=>s.scroll==="horizontal"||s.scroll==="both"),L=o.computed(()=>s.scroll==="vertical"||s.scroll==="both"),h=o.reactive({show:!1,size:0,sizeRaw:0,pos:0}),d=o.reactive({show:!1,size:0,sizeRaw:0,pos:0});let k=0,W=0,E=0,M=0,b=null;const Z={attributes:!0,childList:!0};function P(){if(e.value){if(h.show){const l=e.value.offsetWidth/e.value.scrollWidth;h.sizeRaw=l*e.value.offsetWidth,h.size=l*100,h.pos=e.value.scrollLeft/(e.value.scrollWidth-e.value.offsetWidth)*(100-h.size),l>=1&&(h.show=!1)}if(d.show){const l=e.value.offsetHeight/e.value.scrollHeight;d.sizeRaw=l*e.value.offsetHeight,d.size=l*100,d.pos=e.value.scrollTop/(e.value.scrollHeight-e.value.offsetHeight)*(100-d.size),l>=1&&(d.show=!1)}s.scroll==="vertical"?(s.scrollToStartThreshold&&e.value.scrollTop<=s.scrollToStartThreshold&&a("scrollToStart"),s.scrollToEndThreshold&&e.value.scrollTop>=e.value.scrollHeight-s.scrollToEndThreshold-e.value.offsetHeight&&a("scrollToEnd")):s.scroll==="horizontal"&&(s.scrollToStartThreshold&&e.value.scrollLeft<=s.scrollToStartThreshold&&a("scrollToStart"),s.scrollToEndThreshold&&e.value.scrollLeft>=e.value.scrollWidth-s.scrollToEndThreshold-e.value.offsetWidth&&a("scrollToEnd")),a("scroll",e.value.scrollLeft,e.value.scrollTop)}}function w(l=!1){if(!e.value)return;let n=Q.value,u=L.value;const ae=n&&(k!==e.value.scrollWidth||E!==e.value.offsetWidth),ne=L&&(W!==e.value.scrollHeight||M!==e.value.offsetHeight);if(!l&&!ae&&!ne)return;const z=window.getComputedStyle(e.value);(z.overflow==="hidden"||z.overflowX==="hidden")&&(n=!1),(z.overflow==="hidden"||z.overflowY==="hidden")&&(u=!1),h.show=n,d.show=u,P(),E=e.value.offsetWidth,M=e.value.offsetHeight,k=e.value.scrollWidth,W=e.value.scrollHeight,a("resized",k,W)}function _(l){var n;s.scroll=="horizontal"&&(l.deltaMode==0&&((n=e.value)==null||n.scrollTo({left:e.value.scrollLeft+(l.deltaY>0?Y:-140),behavior:"smooth"})),l.preventDefault(),l.stopPropagation())}function X(l){var n;l.deltaMode==0&&((n=e.value)==null||n.scrollTo({left:e.value.scrollLeft+(l.deltaY>0?Y:-140),behavior:"smooth"}),l.preventDefault(),l.stopPropagation())}function N(l){var n;l.deltaMode==0&&((n=e.value)==null||n.scrollTo({top:e.value.scrollTop+(l.deltaY>0?J:-70),behavior:"smooth"}),l.preventDefault(),l.stopPropagation())}let V=0,$=0,O=0,U=0;const A=B({onDown(l){return!v.value||!f.value?!1:(V=l.offsetX,$=l.x-l.offsetX-f.value.offsetLeft,l.preventDefault(),y.value=!0,!0)},onMove(l,n,u){e.value&&v.value&&(j(u.x-V-$),u.preventDefault(),u.stopPropagation())},onUp(){y.value=!1}}),I=B({onDown(l){return!p.value||!T.value?!1:(O=l.offsetY,U=l.y-l.offsetY-T.value.offsetTop,l.preventDefault(),y.value=!0,!0)},onMove(l,n,u){e.value&&p.value&&(q(u.y-O-U),u.preventDefault(),u.stopPropagation())},onUp(){y.value=!1}});function ee(l){e.value&&(e.value.scrollLeft=l/100*(e.value.scrollWidth-e.value.offsetWidth))}function le(l){e.value&&(e.value.scrollLeft=l/100*(e.value.scrollHeight-e.value.offsetHeight))}function j(l){e.value&&(e.value.scrollLeft=l/(e.value.offsetWidth-h.sizeRaw)*(e.value.scrollWidth-e.value.offsetWidth))}function q(l){e.value&&(e.value.scrollTop=l/(e.value.offsetHeight-d.sizeRaw)*(e.value.scrollHeight-e.value.offsetHeight))}function oe(l){s.scrollBarBackgroundClickable&&j(l.offsetX-h.sizeRaw/2)}function te(l){s.scrollBarBackgroundClickable&&q(l.offsetY-d.sizeRaw/2)}const{startResizeChecker:re,stopResizeChecker:se}=R(e,()=>w(),()=>w());return o.onMounted(()=>{o.nextTick(()=>{setTimeout(()=>w(!0),200),w(!0),re(),b=new MutationObserver(()=>w()),b.observe(e.value,Z)})}),o.onBeforeUnmount(()=>{se(),b&&(b.disconnect(),b=null)}),c({refreshScrollState(){w(!0)},getScrollContainer(){return e.value},scrollTo(l,n){var u;(u=e.value)==null||u.scrollTo(l,n)},scrollToTop(){var l;(l=e.value)==null||l.scrollTo(0,0)},scrollToBottom(){var l;(l=e.value)==null||l.scrollTo(e.value.scrollWidth,e.value.scrollHeight)}}),(l,n)=>(o.openBlock(),o.createElementBlock("div",{ref_key:"scrollrect",ref:m,class:o.normalizeClass(["vue-scroll-rect",t.scrollBarAlwaysShow?"always-show-scrollbar":"",t.scrollBarBackgroundClickable?"background-clickable":"",y.value?"dragging":""]),style:o.normalizeStyle({width:t.width?`${t.width}px`:void 0,height:t.height?`${t.height}px`:void 0}),onWheel:_},[o.createElementVNode("div",{ref_key:"container",ref:e,class:o.normalizeClass(["scroll-content",t.scroll,t.containerClass]),style:o.normalizeStyle({maxWidth:t.maxWidth?`${t.maxWidth}px`:void 0,maxHeight:t.maxHeight?`${t.maxHeight}px`:void 0,...t.containerStyle}),onScroll:P},[o.renderSlot(l.$slots,"default")],38),h.show?o.renderSlot(l.$slots,"scrollBarX",{key:0,scrollBarValue:h,onScroll:ee},()=>[o.createElementVNode("div",{ref_key:"scrollBarRefX",ref:v,class:"scrollbar horizontal",onClick:oe,onWheel:X},[o.createElementVNode("div",{class:"thumb",ref_key:"scrollBarThumbRefX",ref:f,style:o.normalizeStyle({left:`${h.pos}%`,width:`${h.size}%`}),onMousedown:n[0]||(n[0]=(...u)=>o.unref(A)&&o.unref(A)(...u)),onWheel:X},null,36)],544)]):o.createCommentVNode("",!0),d.show?o.renderSlot(l.$slots,"scrollBarY",{key:1,scrollBarValue:d,onScroll:le},()=>[d.show?(o.openBlock(),o.createElementBlock("div",{key:0,ref_key:"scrollBarRefY",ref:p,class:"scrollbar vertical",onClick:te,onWheel:N},[o.createElementVNode("div",{class:"thumb",ref_key:"scrollBarThumbRefY",ref:T,style:o.normalizeStyle({top:`${d.pos}%`,height:`${d.size}%`}),onMousedown:n[1]||(n[1]=(...u)=>o.unref(I)&&o.unref(I)(...u)),onWheel:N},null,36)],544)):o.createCommentVNode("",!0)]):o.createCommentVNode("",!0)],38))}}),K={install(t){t.component("scroll-rect",x)}};i.ScrollRect=x,i.createMiniTimeOut=G,i.createMiniTimer=C,i.createMouseDownAndUpHandler=F,i.createMouseDragHandler=B,i.default=K,i.useResizeChecker=R,Object.defineProperties(i,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
//# sourceMappingURL=vue-scroll-rect.umd.js.map