14 lines
6.7 KiB
JavaScript
14 lines
6.7 KiB
JavaScript
/**
|
|
*
|
|
* @authors yutent (yutent.io@gmail.com)
|
|
* @date 2020-11-17 09:10:37
|
|
* @version v1.0.0
|
|
*
|
|
*/
|
|
|
|
import $ from"../utils.js";const IS_FF=!!window.sidebar;export default class Scroll extends HTMLElement{static get observedAttributes(){return["thumbX","thumbY","disabled","axis","delay","distance"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{thumbX:0,thumbY:0,disabled:!1,axis:"xy",delay:1e3,distance:1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{overflow:hidden;position:relative;display:flex;width:100%}:host .container{overflow:hidden;width:100%;height:100%}.is-horizontal,.is-vertical{visibility:hidden;position:absolute;display:flex;justify-content:flex-end;z-index:10240;opacity:0;user-select:none;transition:opacity 0.3s linear, visibility 0.3s linear}.is-horizontal .thumb,.is-vertical .thumb{display:block;border-radius:5px;background:rgba(44,47,53,0.25);cursor:default;transition:width 0.1s linear, height 0.1s linear}.is-horizontal .thumb:hover,.is-vertical .thumb:hover{background:rgba(44,47,53,0.5)}.is-horizontal{flex-direction:column;left:0;bottom:1px;width:100%;height:10px}.is-horizontal .thumb{width:0;height:6px}.is-horizontal .thumb:hover{height:10px}.is-vertical{top:0;right:1px;width:10px;height:100%}.is-vertical .thumb{width:6px;height:0}.is-vertical .thumb:hover{width:10px}:host(:hover) .is-horizontal,:host(:hover) .is-vertical{visibility:visible;opacity:1}:host([axis=\'x\']) .is-vertical{display:none}:host([axis=\'y\']) .is-horizontal{display:none}</style> <div class="container"><slot /></div> <div class="is-horizontal"><span class="thumb"></span></div> <div class="is-vertical"><span class="thumb"></span></div> ',this.__BOX__=this.root.children[1],this.__X__=this.root.children[2].children[0],this.__Y__=this.root.children[3].children[0],this.__last__=0}get scrollTop(){return this.__BOX__.scrollTop}set scrollTop(t){if((t=+t)==t){var{sh:s,oh:i,yh:e}=this.props;this.__BOX__.scrollTop=t;var h=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=h,this.__Y__.style.transform=`translateY(${h}px)`}}get scrollLeft(){return this.__BOX__.scrollLeft}set scrollLeft(t){if((t=+t)==t){var{sw:s,ow:i,xw:e}=this.props;this.__BOX__.scrollLeft=t;var h=this.__BOX__.scrollLeft/(s-i)*(i-e);this.props.thumbX=h,this.__X__.style.transform=`translateX(${h}px)`}}get scrollHeight(){return this.__BOX__.scrollHeight}get scrollWidth(){return this.__BOX__.scrollWidth}get disabled(){return this.props.disabled}set disabled(t){var s=typeof t;t!==this.props.disabled&&("boolean"===s&&t||"boolean"!==s?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_fetchScrollX(t){var{sw:s,ow:i,xw:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollLeft=t/(i-e)*(s-i),this.__X__.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){var{sh:s,oh:i,yh:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollTop=t/(i-e)*(s-i),this.__Y__.style.transform=`translateY(${t}px)`,t}_fireReachEnd(t="reach-bottom"){var{sh:s,oh:i,delay:e,disabled:h}=this.props,o=this.__BOX__.scrollTop,r=Date.now();if(!h&&r-this.__last__>e){if("reach-bottom"===t){if(i+o<s)return}else if(o>0)return;this.__last__=r,this.dispatchEvent(new CustomEvent(t))}}connectedCallback(){this._initFn=$.bind(this.__BOX__,"mouseenter",t=>{if(!this.disabled){var s=this.__BOX__.offsetWidth,i=this.__BOX__.scrollWidth,e=this.__BOX__.offsetHeight,h=this.__BOX__.scrollHeight,o=e*e/h>>0,r=s*s/i>>0;o<50&&(o=50),r<50&&(r=50),r===s&&(r=0),o===e&&(o=0),this.props.oh=e,this.props.sh=h,this.props.ow=s,this.props.sw=i,this.props.yh=o,this.props.xw=r,this.__X__.style.width=r+"px",this.__Y__.style.height=o+"px"}}),this._inactiveFn=$.bind(this.__BOX__,"mouseleave",t=>{delete this._active}),this._wheelFn=$.bind(this.__BOX__,"wheel",t=>{if(!this.disabled){var{sh:s,oh:i,yh:e,sw:h,ow:o,xw:r}=this.props;if(r||e){var a,l,_=Date.now();if((!this.stamp||_-this.stamp>800)&&(this.stamp=_,this.times=1),IS_FF)a=t.deltaMode?10*t.deltaX:t.deltaX,l=t.deltaMode?10*t.deltaY:t.deltaY;else{var n=Math.abs(t.wheelDelta);n<120?(a=t.deltaX,l=t.deltaY):(a=t.deltaX/(n/120),l=t.deltaY/(n/120))}if(_-this.stamp<20&&(this.times+=.05,this.times>3&&(this.times=3)),a*=this.times,l*=this.times,"x"!==this.props.axis&&(this.__BOX__.scrollTop+=l,e)){var p=this.__BOX__.scrollTop/(s-i)*(i-e);if((0===(p>>=0)||i-e===p)&&p===this.props.thumbY)return;t.preventDefault(),t.stopPropagation(),this.props.thumbY=p,this.__Y__.style.transform=`translateY(${p}px)`,Math.abs(l)>this.props.distance&&this._fireReachEnd(l>0?"reach-bottom":"reach-top")}if("y"!==this.props.axis&&(this.__BOX__.scrollLeft+=a,r)){var d=this.__BOX__.scrollLeft/(h-o)*(o-r);if((0===(d>>=0)||o-r===d)&&d===this.props.thumbX)return;t.preventDefault(),t.stopPropagation(),this.props.thumbX=d,this.__X__.style.transform=`translateX(${d}px)`}this._active=!0,this.stamp=_,this.dispatchEvent(new CustomEvent("scroll",{detail:{x:this.props.thumbX,y:this.props.thumbY}}))}}});var t,s,i,e,h=h=>{var{thumbY:o,thumbX:r}=this.props;null!==t&&(i=this._fetchScrollX(r+h.pageX-t)),null!==s&&(this._active=!0,e=this._fetchScrollY(o+h.pageY-s))},o=r=>{Math.abs(r.pageY-s)>this.props.distance&&this._fireReachEnd(r.pageY>s?"reach-bottom":"reach-top"),t=null,s=null,this.props.thumbX=i,this.props.thumbY=e,$.unbind(document,"mousemove",h),$.unbind(document,"mouseup",o)};$.bind(this.__Y__,"mousedown",t=>{s=t.pageY,this.props.thumbY||(this.props.thumbY=0),this.disabled||($.bind(document,"mousemove",h),$.bind(document,"mouseup",o))}),$.bind(this.__X__,"mousedown",s=>{t=s.pageX,this.props.thumbX||(this.props.thumbX=0),this.disabled||($.bind(document,"mousemove",h),$.bind(document,"mouseup",o))}),$.catch(document,"keydown",t=>{if(this._active){var{oh:s,sh:i}=this.props,e=!1;switch(t.keyCode){case 33:e=!0,this.scrollTop-=s;break;case 34:e=!0,this.scrollTop+=s;break;case 35:e=!0,this.scrollTop=i;break;case 36:e=!0,this.scrollTop=0}e&&t.preventDefault()}}),this.__observer=new MutationObserver(this._initFn),this.__observer.observe(this,{childList:!0,subtree:!0,characterData:!0})}disconnectedCallback(){this.__observer.disconnect(),$.unbind(this.__BOX__,"mouseenter",this._initFn),$.unbind(this.__BOX__,"mouseleave",this._inactiveFn),$.unbind(this.__BOX__,"wheel",this._wheelFn)}attributeChangedCallback(t,s,i){if(null!==i&&s!==i)switch(t){case"axis":this.props.axis=i;break;case"disabled":this[t]=!0;break;case"delay":this.props.delay=+i||1e3;break;case"distance":this.props.distance=+i||1}}}
|
|
|
|
if(!customElements.get('wc-scroll')){
|
|
customElements.define('wc-scroll', Scroll)
|
|
}
|
JavaScript
60.1%
SCSS
19.2%
HTML
16.9%
CSS
3.8%