UNPKG

@vanillawc/wc-carousel-lite

Version:

A web component that wraps HTML elements and forms a horizontal carousel slider out of them.

1 lines 6.96 kB
export class Customcarousel extends HTMLElement{constructor(){super(),this.item="item",this.initItem=0,this.transitionDuration=0,this.transitionType="ease",this.interval=1e3,this.direction="left",this.touchVelocityLimit=1.5,this.mouseVelocityLimit=3,this.t=30,this.i=null,this.s=null,this.h=[]}static get observedAttributes(){return["infinite","init-item","center-between","autoplay","interval","direction","transition-duration","transition-type","item","no-touch"]}disconnectedCallback(){for(;this.l.firstChild;)this.l.firstChild.remove();for(let t=0;t<this.o.length;t++)this.appendChild(this.o[t].cloneNode(!0));this.o=[],this.u=null,this.stop(this.autoplay),this.connected=!1}attributeChangedCallback(t,i,s){"infinite"===t?this.infinite=!0:"init-item"===t?this.initItem=parseInt(s):"center-between"===t?this.centerBetween=!0:"transition-duration"===t?this.transitionDuration=parseInt(s):"transition-type"===t?this.transitionType=s:"autoplay"===t?this.autoplay=!0:"interval"===t?this.interval=parseInt(s):"direction"===t?this.direction=s:"item"===t?this.item=s:"no-touch"===t&&(this.noTouch=!0)}connectedCallback(){setTimeout(()=>{this.m()},0),this.connected=!0}next(t=1){if(0===t&&(t=1),!this.infinite)return(!this.centerBetween&&this.p+(t-1)<this.g-1||this.centerBetween&&this.p<this.g-3)&&this.I(),t=this.v("l",t),void this._(this.p+t);parseInt(getComputedStyle(this.l).left)<0&&(this.I(),this.C(t),this._(this.p+t),this.F(t))}prev(t=1){if(0===t&&(t=1),!this.infinite)return this.p<0&&this.I(),t=this.v("r",t),void this._(this.p-t);this.l.offsetWidth+parseInt(getComputedStyle(this.l).left)>this.offsetWidth&&(this.I(),this.M(t),this._(this.p-t),this.F(-t))}I(){this.l.style.left=getComputedStyle(this.l).left}_(t){let i=this.offsetWidth/2,s=this.l.querySelectorAll("."+this.item);if(this.centerBetween&&t===s.length-1||!s[t])return;let h,e,r,l,n=0;for(h=0;h<t;h++)r=getComputedStyle(s[h]),l=parseFloat(r.marginLeft)+parseFloat(r.marginRight),n+=s[h].offsetWidth+l;e=parseFloat(getComputedStyle(s[h]).marginRight);let a=i-(n+parseFloat(getComputedStyle(s[0]).marginLeft)+(this.centerBetween?s[t].offsetWidth+e:s[t].offsetWidth/2));this.l.style.transition="left "+this.transitionDuration+"ms",this.l.style.transitionTimingFunction=this.transitionType,this.l.style.left=a+"px",this.p=t}goto(t){if(t>this.o.length-1)return;if(!this.infinite)return void this._(t);let i,s;i=t-this.S,s=t>this.S?t-this.S-this.o.length:t-this.S+this.o.length;let h=Math.abs(i)<=Math.abs(s)?i:s;h<0?this.M(Math.abs(h)):h>0&&this.C(Math.abs(h)),this._(this.p+h),this.F(h)}k(t){this.l.style.left=parseInt(this.l.style.left)+t+"px"}H(t){for(;this.l.firstChild;)this.l.firstChild.remove();let i=this.querySelectorAll("."+this.item);if(i.length>0){for(let t=0;t<i.length;t++)this.l.appendChild(i[t]);t--}for(let i=0;i<t;i++)for(let t=0;t<this.o.length;t++)this.l.appendChild(this.o[t].cloneNode(!0));this.g=this.l.querySelectorAll("."+this.item).length}L(t){let i,s;return i=getComputedStyle(t),s=parseFloat(i.marginLeft)+parseFloat(i.marginRight),t.offsetWidth+s}C(t=1){for(let i=0;i<t;i++){this.l.style.transition="";let t=this.l.querySelectorAll("."+this.item)[0];this.k(this.L(t)),this.l.appendChild(this.l.removeChild(t)),this.p--}}M(t=1){for(let i=0;i<t;i++){this.l.style.transition="";let t=[...this.l.querySelectorAll("."+this.item)].pop();this.k(-this.L(t)),this.l.insertAdjacentElement("afterbegin",this.l.removeChild(t)),this.p++}}T(){if(!this.connected)return;if(!this.infinite)return void this._(this.p);let t=parseInt(2.75*this.offsetWidth/this.A);if(this.o.length<3&&(t+=3),0===t&&t++,t%2&&t++,t!==this.u){let i;this.H(t),i=this.p?this.S:this.initItem,this._(this.o.length*(t/2)+i),this.R(),this.u=t,this.S=i}else this.goto(this.S)}R(){let t=this.g/2-this.p;0!==t&&(t<0?this.C():t>0&&this.M(),this.R())}F(t){for(let i=0;i<Math.abs(t);i++)t>0&&(this.S+1===this.o.length?this.S=0:this.S++),t<0&&(0===this.S?this.S=this.o.length-1:this.S--)}D(){this.infinite||(this.centerBetween&&this.p>=this.g-2||this.p>=this.g-1?this.direction="right":0===this.p&&(this.direction="left")),"right"===this.direction?this.prev():this.next()}stop(t=!1){clearInterval(this.i),this.i=null,this.autoplay=t}play(){null===this.i&&(this.D(),this.i=setInterval(()=>{this.D()},this.interval),this.autoplay=!0)}v(t,i){let s;return s="l"===t?this.o.length-(this.centerBetween?2:1)-this.p:this.p,s<i?s:i}B(t){if(!t)return null;let i=0;for(;null!==(t=t.previousSibling);)i++;return i}N(t){let i=t.target.closest("."+this.item);this.O=this.B(i),t.preventDefault(),t.pageX?(this.x=t.pageX,this.y=t.pageY):t.targetTouches[0].pageX&&(this.x=t.targetTouches[0].pageX,this.y=t.targetTouches[0].pageY),this.startTime=(new Date).getTime()}W(t){let i;i=t.changedTouches?document.elementFromPoint(t.changedTouches[0].clientX,t.changedTouches[0].clientY):t.target;let s,h=i.closest("."+this.item),e=this.B(h);s=Number.isInteger(this.O)&&Number.isInteger(e)?Math.abs(this.O-e):1;let r=(t.pageX?t.pageX:t.changedTouches[0].pageX)-this.x,l=(t.pageY?t.pageY:t.changedTouches[0].pageY)-this.y,n=(new Date).getTime()-this.startTime,a=Math.abs(r/n);(a>this.touchVelocityLimit&&t.changedTouches||a>this.mouseVelocityLimit)&&s++,Math.abs(r)>this.t&&Math.abs(r)>Math.abs(l)&&(t.preventDefault(),this.j=!0,r<-this.t?this.next(s):r>this.t&&this.prev(s))}q(t){this.j&&t.preventDefault(),this.j=!1,this.focus()}G(t){"ArrowRight"===t.key?this.prev():"ArrowLeft"===t.key&&this.next()}J(){if(this.h.every(t=>!0===t.complete))return clearInterval(this.s),this.K(),!0}K(){let t,i;this.A=0;for(let s=0;s<this.o.length;s++)t=getComputedStyle(this.o[s]),i=parseFloat(t.marginLeft)+parseFloat(t.marginRight),this.A+=this.o[s].offsetWidth+i;this.infinite?this.T():(this.H(1),this._(this.initItem)),this.autoplay&&this.play()}m(){if(this.P||(this.U=this.appendChild(document.createElement("div")),this.U.style.display="flex",this.U.style.overflow="hidden",this.U.style.width="100%",this.l=this.U.appendChild(document.createElement("div")),this.l.style.display="flex",this.l.style.position="relative"),this.h=Array.from(this.querySelectorAll("img")),this.o=this.querySelectorAll("."+this.item),0===this.o.length)throw"couldn't find any children with "+this.item+" class";this.initItem+1>this.o.length&&(this.initItem=0);let t,i=!0;for(let s=0;s<this.o.length;s++)if(t=getComputedStyle(this.o[s]),0===parseFloat(t.width)){i=!1;break}i?this.K():this.J()||(this.s=setInterval(()=>{this.J()},100)),this.P||(this.tabIndex=0,this.noTouch||(this.ontouchstart=this.N,this.ontouchstart=this.ontouchstart.bind(this),this.ontouchend=this.W,this.ontouchend=this.ontouchend.bind(this)),this.onmousedown=this.N,this.onmousedown=this.onmousedown.bind(this),this.onmouseup=this.W,this.onmouseup=this.onmouseup.bind(this),this.onclick=this.q,this.onclick=this.onclick.bind(this),this.onkeydown=this.G,this.onkeydown=this.onkeydown.bind(this),window.addEventListener("resize",()=>this.T())),this.P=!0}}customElements.define("wc-carousel-lite",Customcarousel);