UNPKG

domahaflip

Version:

A lightweight and responsive JavaScript library for creating 3D page-flipping effects.

2 lines (1 loc) 4.09 kB
var DomahaFlip=(()=>{var e=class{constructor(t,i,s={}){this.container=t,this.pagesData=i,this.options={width:800,height:500,pageBackgroundColor:"white",flipDuration:800,loop:!1,...s},this.pages=[],this.currentPageIndex=0,this.isFlipping=!1,this.touchStartX=0,this.touchMoveX=0,this.isSwiping=!1,this.init()}init(){let t=this.options.width/this.options.height;this.container.style.setProperty("--aspect-ratio",t),this.container.style.setProperty("--max-width",`${this.options.width}px`),this.container.classList.add("domahaflip-container"),this.container.style.setProperty("--flip-duration",`${this.options.flipDuration}ms`),this.renderPages(),this.renderNavigation(),this.setupNavigation(),this.updatePages(),this.loadPage(0),this.loadPage(1)}renderPages(){this.container.innerHTML="",this.pagesData.forEach(t=>{let i=document.createElement("div");if(i.classList.add("domahaflip-page"),i.style.backgroundColor=this.options.pageBackgroundColor,t.html)i.innerHTML=t.html;else if(t.src||t["data-src"]){let s=document.createElement("img");t["data-src"]&&(s.setAttribute("data-src",t["data-src"]),i.classList.add("loading")),t.src&&(s.src=t.src),t.alt&&(s.alt=t.alt),i.appendChild(s)}this.container.appendChild(i),this.pages.push(i)})}loadPage(t){if(t<0||t>=this.pages.length)return;let i=this.pages[t];if(!i||i.dataset.loaded==="true")return;let s=i.querySelector("img");if(s&&s.hasAttribute("data-src")){i.dataset.loaded="loading";let n=s.getAttribute("data-src");s.src=n,s.onload=()=>{i.classList.remove("loading"),i.dataset.loaded="true",s.removeAttribute("data-src")}}else i.dataset.loaded="true"}renderNavigation(){let t=document.createElement("button");t.classList.add("domahaflip-nav-button","domahaflip-nav-next"),t.innerHTML="&#9654;",t.addEventListener("click",s=>{s.stopPropagation(),this.flipNext()});let i=document.createElement("button");i.classList.add("domahaflip-nav-button","domahaflip-nav-prev"),i.innerHTML="&#9664;",i.addEventListener("click",s=>{s.stopPropagation(),this.flipPrev()}),this.container.appendChild(t),this.container.appendChild(i)}setupNavigation(){this.container.addEventListener("click",t=>{if(this.isFlipping||this.isSwiping||t.target.classList.contains("domahaflip-nav-button"))return;let s=this.container.offsetWidth;t.clientX-this.container.getBoundingClientRect().left>s/2?this.flipNext():this.flipPrev()}),document.addEventListener("keydown",t=>{this.isFlipping||(t.key==="ArrowRight"&&this.flipNext(),t.key==="ArrowLeft"&&this.flipPrev())}),this.container.addEventListener("touchstart",t=>this.handleTouchStart(t)),this.container.addEventListener("touchmove",t=>this.handleTouchMove(t)),this.container.addEventListener("touchend",t=>this.handleTouchEnd(t))}handleTouchStart(t){this.isFlipping||(this.isSwiping=!1,this.touchStartX=t.touches[0].clientX)}handleTouchMove(t){this.isFlipping||(this.touchMoveX=t.touches[0].clientX,Math.abs(this.touchMoveX-this.touchStartX)>10&&(this.isSwiping=!0))}handleTouchEnd(t){if(this.isFlipping||!this.isSwiping)return;let i=50,s=this.touchStartX-this.touchMoveX;s>i?this.flipNext():s<-i&&this.flipPrev(),this.touchStartX=0,this.touchMoveX=0,this.isSwiping=!1}flipNext(){this.isFlipping||(this.currentPageIndex<this.pages.length?this.goToPage(this.currentPageIndex+1):this.options.loop&&(this.container.classList.add("no-transition"),this.goToPage(0),setTimeout(()=>{this.container.classList.remove("no-transition")},50)))}flipPrev(){this.isFlipping||(this.currentPageIndex>0?this.goToPage(this.currentPageIndex-1):this.options.loop&&(this.container.classList.add("no-transition"),this.goToPage(this.pages.length),setTimeout(()=>{this.container.classList.remove("no-transition")},50)))}goToPage(t){t>this.pages.length||t<0||(this.isFlipping=!0,this.currentPageIndex=t,this.updatePages(),this.loadPage(t-1),this.loadPage(t),this.loadPage(t+1))}updatePages(){this.pages.forEach((t,i)=>{t.style.zIndex=this.pages.length-i,i<this.currentPageIndex?t.classList.add("flipped"):t.classList.remove("flipped")}),setTimeout(()=>{this.isFlipping=!1},this.options.flipDuration)}};typeof window<"u"&&(window.DomahaFlip=e);})();