UNPKG

flipbook-vue

Version:

3D page flip effect for Vue.js

1,331 lines (1,276 loc) 44.4 kB
/*! * @license * flipbook-vue v1.0.0-beta.4 * Copyright © 2023 Takeshi Sone. * Released under the MIT License. */ 'use strict'; var rematrix = require('rematrix'); var vue = require('vue'); var Matrix = /*@__PURE__*/(function () { function Matrix(arg) { if (arg) { if (arg.m) { this.m = [].concat( arg.m ); } else { this.m = [].concat( arg ); } } else { this.m = rematrix.identity(); } } Matrix.prototype.clone = function clone () { return new Matrix(this); }; Matrix.prototype.multiply = function multiply$1 (m) { return this.m = rematrix.multiply(this.m, m); }; Matrix.prototype.perspective = function perspective$1 (d) { return this.multiply(rematrix.perspective(d)); }; Matrix.prototype.transformX = function transformX (x) { return (x * this.m[0] + this.m[12]) / (x * this.m[3] + this.m[15]); }; Matrix.prototype.translate = function translate$1 (x, y) { return this.multiply(rematrix.translate(x, y)); }; Matrix.prototype.translate3d = function translate3d$1 (x, y, z) { return this.multiply(rematrix.translate3d(x, y, z)); }; Matrix.prototype.rotateY = function rotateY$1 (deg) { return this.multiply(rematrix.rotateY(deg)); }; Matrix.prototype.toString = function toString$1 () { return rematrix.toString(this.m); }; return Matrix; }()); var spinner = "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22500%22%20height%3D%22500%22%20viewBox%3D%220%200%20500%20500%22%20fill%3D%22transparent%22%20style%3D%22background-color%3A%20%23fff%22%3E%20%20%3Ccircle%20%20%20%20cx%3D%22250%22%20%20%20%20cy%3D%22250%22%20%20%20%20r%3D%2248%22%20%20%20%20stroke%3D%22%23333%22%20%20%20%20stroke-width%3D%222%22%20%20%20%20stroke-dasharray%3D%22271%2030%22%20%20%3E%20%20%20%20%3CanimateTransform%20%20%20%20%20%20attributeName%3D%22transform%22%20%20%20%20%20%20attributeType%3D%22XML%22%20%20%20%20%20%20type%3D%22rotate%22%20%20%20%20%20%20from%3D%220%20250%20250%22%20%20%20%20%20%20to%3D%22360%20250%20250%22%20%20%20%20%20%20dur%3D%221s%22%20%20%20%20%20%20repeatCount%3D%22indefinite%22%20%20%20%20%2F%3E%20%20%3C%2Fcircle%3E%3C%2Fsvg%3E"; var easeIn, easeInOut, easeOut; easeIn = function(x) { return Math.pow(x, 2); }; easeOut = function(x) { return 1 - easeIn(1 - x); }; easeInOut = function(x) { if (x < 0.5) { return easeIn(x * 2) / 2; } else { return 0.5 + easeOut((x - 0.5) * 2) / 2; } }; var script = { props: { pages: { type: Array, required: true }, pagesHiRes: { type: Array, default: function() { return []; } }, flipDuration: { type: Number, default: 1000 }, zoomDuration: { type: Number, default: 500 }, zooms: { type: Array, default: function() { return [1, 2, 4]; } }, perspective: { type: Number, default: 2400 }, nPolygons: { type: Number, default: 10 }, ambient: { type: Number, default: 0.4 }, gloss: { type: Number, default: 0.6 }, swipeMin: { type: Number, default: 3 }, singlePage: { type: Boolean, default: false }, forwardDirection: { validator: function(val) { return val === 'right' || val === 'left'; }, default: 'right' }, centering: { type: Boolean, default: true }, startPage: { type: Number, default: null }, loadingImage: { type: String, default: spinner }, clickToZoom: { type: Boolean, default: true }, dragToFlip: { type: Boolean, default: true }, wheel: { type: String, default: 'scroll' } }, data: function() { return { viewWidth: 0, viewHeight: 0, imageWidth: null, imageHeight: null, displayedPages: 1, nImageLoad: 0, nImageLoadTrigger: 0, imageLoadCallback: null, currentPage: 0, firstPage: 0, secondPage: 1, zoomIndex: 0, zoom: 1, zooming: false, touchStartX: null, touchStartY: null, maxMove: 0, activeCursor: null, hasTouchEvents: false, hasPointerEvents: false, minX: 2e308, maxX: -2e308, preloadedImages: {}, flip: { progress: 0, direction: null, frontImage: null, backImage: null, auto: false, opacity: 1 }, currentCenterOffset: null, animatingCenter: false, startScrollLeft: 0, startScrollTop: 0, scrollLeft: 0, scrollTop: 0, loadedImages: {} }; }, computed: { IE: function() { return typeof navigator !== 'undefined' && /Trident/.test(navigator.userAgent); }, canFlipLeft: function() { if (this.forwardDirection === 'left') { return this.canGoForward; } else { return this.canGoBack; } }, canFlipRight: function() { if (this.forwardDirection === 'right') { return this.canGoForward; } else { return this.canGoBack; } }, canZoomIn: function() { return !this.zooming && this.zoomIndex < this.zooms_.length - 1; }, canZoomOut: function() { return !this.zooming && this.zoomIndex > 0; }, numPages: function() { if (this.pages[0] === null) { return this.pages.length - 1; } else { return this.pages.length; } }, page: function() { if (this.pages[0] !== null) { return this.currentPage + 1; } else { return Math.max(1, this.currentPage); } }, zooms_: function() { return this.zooms || [1]; }, canGoForward: function() { return !this.flip.direction && this.currentPage < this.pages.length - this.displayedPages; }, canGoBack: function() { return !this.flip.direction && this.currentPage >= this.displayedPages && !(this.displayedPages === 1 && !this.pageUrl(this.firstPage - 1)); }, leftPage: function() { if (this.forwardDirection === 'right' || this.displayedPages === 1) { return this.firstPage; } else { return this.secondPage; } }, rightPage: function() { if (this.forwardDirection === 'left') { return this.firstPage; } else { return this.secondPage; } }, showLeftPage: function() { return this.pageUrl(this.leftPage); }, showRightPage: function() { return this.pageUrl(this.rightPage) && this.displayedPages === 2; }, cursor: function() { if (this.activeCursor) { return this.activeCursor; } else if (this.IE) { return 'auto'; } else if (this.clickToZoom && this.canZoomIn) { return 'zoom-in'; } else if (this.clickToZoom && this.canZoomOut) { return 'zoom-out'; } else if (this.dragToFlip) { return 'grab'; } else { return 'auto'; } }, pageScale: function() { var scale, vw, xScale, yScale; vw = this.viewWidth / this.displayedPages; xScale = vw / this.imageWidth; yScale = this.viewHeight / this.imageHeight; scale = xScale < yScale ? xScale : yScale; if (scale < 1) { return scale; } else { return 1; } }, pageWidth: function() { return Math.round(this.imageWidth * this.pageScale); }, pageHeight: function() { return Math.round(this.imageHeight * this.pageScale); }, xMargin: function() { return (this.viewWidth - this.pageWidth * this.displayedPages) / 2; }, yMargin: function() { return (this.viewHeight - this.pageHeight) / 2; }, polygonWidth: function() { var w; w = this.pageWidth / this.nPolygons; w = Math.ceil(w + 1 / this.zoom); return w + 'px'; }, polygonHeight: function() { return this.pageHeight + 'px'; }, polygonBgSize: function() { return ((this.pageWidth) + "px " + (this.pageHeight) + "px"); }, polygonArray: function() { return this.makePolygonArray('front').concat(this.makePolygonArray('back')); }, boundingLeft: function() { var x; if (this.displayedPages === 1) { return this.xMargin; } else { x = this.pageUrl(this.leftPage) ? this.xMargin : this.viewWidth / 2; if (x < this.minX) { return x; } else { return this.minX; } } }, boundingRight: function() { var x; if (this.displayedPages === 1) { return this.viewWidth - this.xMargin; } else { x = this.pageUrl(this.rightPage) ? this.viewWidth - this.xMargin : this.viewWidth / 2; if (x > this.maxX) { return x; } else { return this.maxX; } } }, centerOffset: function() { var retval; retval = this.centering ? Math.round(this.viewWidth / 2 - (this.boundingLeft + this.boundingRight) / 2) : 0; if (this.currentCenterOffset === null && this.imageWidth !== null) { this.currentCenterOffset = retval; } return retval; }, centerOffsetSmoothed: function() { return Math.round(this.currentCenterOffset); }, dragToScroll: function() { return !this.hasTouchEvents; }, scrollLeftMin: function() { var w; w = (this.boundingRight - this.boundingLeft) * this.zoom; if (w < this.viewWidth) { return (this.boundingLeft + this.centerOffsetSmoothed) * this.zoom - (this.viewWidth - w) / 2; } else { return (this.boundingLeft + this.centerOffsetSmoothed) * this.zoom; } }, scrollLeftMax: function() { var w; w = (this.boundingRight - this.boundingLeft) * this.zoom; if (w < this.viewWidth) { return (this.boundingLeft + this.centerOffsetSmoothed) * this.zoom - (this.viewWidth - w) / 2; } else { return (this.boundingRight + this.centerOffsetSmoothed) * this.zoom - this.viewWidth; } }, scrollTopMin: function() { var h; h = this.pageHeight * this.zoom; if (h < this.viewHeight) { return this.yMargin * this.zoom - (this.viewHeight - h) / 2; } else { return this.yMargin * this.zoom; } }, scrollTopMax: function() { var h; h = this.pageHeight * this.zoom; if (h < this.viewHeight) { return this.yMargin * this.zoom - (this.viewHeight - h) / 2; } else { return (this.yMargin + this.pageHeight) * this.zoom - this.viewHeight; } }, scrollLeftLimited: function() { return Math.min(this.scrollLeftMax, Math.max(this.scrollLeftMin, this.scrollLeft)); }, scrollTopLimited: function() { return Math.min(this.scrollTopMax, Math.max(this.scrollTopMin, this.scrollTop)); } }, mounted: function() { window.addEventListener('resize', this.onResize, { passive: true }); this.onResize(); this.zoom = this.zooms_[0]; return this.goToPage(this.startPage); }, beforeDestroy: function() { return window.removeEventListener('resize', this.onResize, { passive: true }); }, methods: { onResize: function() { var viewport; viewport = this.$refs.viewport; if (!viewport) { return; } this.viewWidth = viewport.clientWidth; this.viewHeight = viewport.clientHeight; this.displayedPages = this.viewWidth > this.viewHeight && !this.singlePage ? 2 : 1; if (this.displayedPages === 2) { this.currentPage &= ~1; } this.fixFirstPage(); this.minX = 2e308; return this.maxX = -2e308; }, fixFirstPage: function() { if (this.displayedPages === 1 && this.currentPage === 0 && this.pages.length && !this.pageUrl(0)) { return this.currentPage++; } }, pageUrl: function(page, hiRes) { if ( hiRes === void 0 ) hiRes = false; var url; if (hiRes && this.zoom > 1 && !this.zooming) { url = this.pagesHiRes[page]; if (url) { return url; } } return this.pages[page] || null; }, pageUrlLoading: function(page, hiRes) { if ( hiRes === void 0 ) hiRes = false; var url; url = this.pageUrl(page, hiRes); if (hiRes && this.zoom > 1 && !this.zooming) { // High-res image doesn't use 'loading' return url; } return url && this.loadImage(url); }, flipLeft: function() { if (!this.canFlipLeft) { return; } return this.flipStart('left', true); }, flipRight: function() { if (!this.canFlipRight) { return; } return this.flipStart('right', true); }, makePolygonArray: function(face) { var bgPos, dRadian, dRotate, direction, i, image, j, lighting, m, originRight, pageMatrix, pageRotation, pageX, polygonWidth, progress, rad, radian, radius, ref, results, rotate, theta, x, x0, x1, z; if (!this.flip.direction) { return []; } progress = this.flip.progress; direction = this.flip.direction; if (this.displayedPages === 1 && direction !== this.forwardDirection) { progress = 1 - progress; direction = this.forwardDirection; } this.flip.opacity = this.displayedPages === 1 && progress > .7 ? 1 - (progress - .7) / .3 : 1; image = face === 'front' ? this.flip.frontImage : this.flip.backImage; polygonWidth = this.pageWidth / this.nPolygons; pageX = this.xMargin; originRight = false; if (this.displayedPages === 1) { if (this.forwardDirection === 'right') { if (face === 'back') { originRight = true; pageX = this.xMargin - this.pageWidth; } } else { if (direction === 'left') { if (face === 'back') { pageX = this.pageWidth - this.xMargin; } else { originRight = true; } } else { if (face === 'front') { pageX = this.pageWidth - this.xMargin; } else { originRight = true; } } } } else { if (direction === 'left') { if (face === 'back') { pageX = this.viewWidth / 2; } else { originRight = true; } } else { if (face === 'front') { pageX = this.viewWidth / 2; } else { originRight = true; } } } pageMatrix = new Matrix(); pageMatrix.translate(this.viewWidth / 2); pageMatrix.perspective(this.perspective); pageMatrix.translate(-this.viewWidth / 2); pageMatrix.translate(pageX, this.yMargin); pageRotation = 0; if (progress > 0.5) { pageRotation = -(progress - 0.5) * 2 * 180; } if (direction === 'left') { pageRotation = -pageRotation; } if (face === 'back') { pageRotation += 180; } if (pageRotation) { if (originRight) { pageMatrix.translate(this.pageWidth); } pageMatrix.rotateY(pageRotation); if (originRight) { pageMatrix.translate(-this.pageWidth); } } if (progress < 0.5) { theta = progress * 2 * Math.PI; } else { theta = (1 - (progress - 0.5) * 2) * Math.PI; } if (theta === 0) { theta = 1e-9; } radius = this.pageWidth / theta; radian = 0; dRadian = theta / this.nPolygons; rotate = dRadian / 2 / Math.PI * 180; dRotate = dRadian / Math.PI * 180; if (originRight) { rotate = -theta / Math.PI * 180 + dRotate / 2; } if (face === 'back') { rotate = -rotate; dRotate = -dRotate; } this.minX = 2e308; this.maxX = -2e308; results = []; for (i = j = 0, ref = this.nPolygons; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) { bgPos = (i / (this.nPolygons - 1) * 100) + "% 0px"; m = pageMatrix.clone(); rad = originRight ? theta - radian : radian; x = Math.sin(rad) * radius; if (originRight) { x = this.pageWidth - x; } z = (1 - Math.cos(rad)) * radius; if (face === 'back') { z = -z; } m.translate3d(x, 0, z); m.rotateY(-rotate); x0 = m.transformX(0); x1 = m.transformX(polygonWidth); this.maxX = Math.max(Math.max(x0, x1), this.maxX); this.minX = Math.min(Math.min(x0, x1), this.minX); lighting = this.computeLighting(pageRotation - rotate, dRotate); radian += dRadian; rotate += dRotate; results.push([face + i, image, lighting, bgPos, m.toString(), Math.abs(Math.round(z))]); } return results; }, computeLighting: function(rot, dRotate) { var DEG, POW, blackness, diffuse, gradients, lightingPoints, specular; gradients = []; lightingPoints = [-0.5, -0.25, 0, 0.25, 0.5]; if (this.ambient < 1) { blackness = 1 - this.ambient; diffuse = lightingPoints.map(function (d) { return (1 - Math.cos((rot - dRotate * d) / 180 * Math.PI)) * blackness; }); gradients.push(("linear-gradient(to right,\n rgba(0, 0, 0, " + (diffuse[0]) + "),\n rgba(0, 0, 0, " + (diffuse[1]) + ") 25%,\n rgba(0, 0, 0, " + (diffuse[2]) + ") 50%,\n rgba(0, 0, 0, " + (diffuse[3]) + ") 75%,\n rgba(0, 0, 0, " + (diffuse[4]) + "))")); } if (this.gloss > 0 && !this.IE) { DEG = 30; POW = 200; specular = lightingPoints.map(function (d) { return Math.max(Math.pow( Math.cos((rot + DEG - dRotate * d) / 180 * Math.PI), POW ), Math.pow( Math.cos((rot - DEG - dRotate * d) / 180 * Math.PI), POW )); }); gradients.push(("linear-gradient(to right,\n rgba(255, 255, 255, " + (specular[0] * this.gloss) + "),\n rgba(255, 255, 255, " + (specular[1] * this.gloss) + ") 25%,\n rgba(255, 255, 255, " + (specular[2] * this.gloss) + ") 50%,\n rgba(255, 255, 255, " + (specular[3] * this.gloss) + ") 75%,\n rgba(255, 255, 255, " + (specular[4] * this.gloss) + "))")); } return gradients.join(','); }, flipStart: function(direction, auto) { var this$1$1 = this; if (direction !== this.forwardDirection) { if (this.displayedPages === 1) { this.flip.frontImage = this.pageUrl(this.currentPage - 1); this.flip.backImage = null; } else { this.flip.frontImage = this.pageUrl(this.firstPage); this.flip.backImage = this.pageUrl(this.currentPage - this.displayedPages + 1); } } else { if (this.displayedPages === 1) { this.flip.frontImage = this.pageUrl(this.currentPage); this.flip.backImage = null; } else { this.flip.frontImage = this.pageUrl(this.secondPage); this.flip.backImage = this.pageUrl(this.currentPage + this.displayedPages); } } this.flip.direction = direction; this.flip.progress = 0; return requestAnimationFrame(function () { return requestAnimationFrame(function () { if (this$1$1.flip.direction !== this$1$1.forwardDirection) { if (this$1$1.displayedPages === 2) { this$1$1.firstPage = this$1$1.currentPage - this$1$1.displayedPages; } } else { if (this$1$1.displayedPages === 1) { this$1$1.firstPage = this$1$1.currentPage + this$1$1.displayedPages; } else { this$1$1.secondPage = this$1$1.currentPage + 1 + this$1$1.displayedPages; } } if (auto) { return this$1$1.flipAuto(true); } }); }); }, flipAuto: function(ease) { var this$1$1 = this; var animate, duration, startRatio, t0; t0 = Date.now(); duration = this.flipDuration * (1 - this.flip.progress); startRatio = this.flip.progress; this.flip.auto = true; this.$emit(("flip-" + (this.flip.direction) + "-start"), this.page); animate = function () { return requestAnimationFrame(function () { var ratio, t; t = Date.now() - t0; ratio = startRatio + t / duration; if (ratio > 1) { ratio = 1; } this$1$1.flip.progress = ease ? easeInOut(ratio) : ratio; if (ratio < 1) { return animate(); } else { if (this$1$1.flip.direction !== this$1$1.forwardDirection) { this$1$1.currentPage -= this$1$1.displayedPages; } else { this$1$1.currentPage += this$1$1.displayedPages; } this$1$1.$emit(("flip-" + (this$1$1.flip.direction) + "-end"), this$1$1.page); if (this$1$1.displayedPages === 1 && this$1$1.flip.direction === this$1$1.forwardDirection) { this$1$1.flip.direction = null; } else { this$1$1.onImageLoad(1, function () { return this$1$1.flip.direction = null; }); } return this$1$1.flip.auto = false; } }); }; return animate(); }, flipRevert: function() { var this$1$1 = this; var animate, duration, startRatio, t0; t0 = Date.now(); duration = this.flipDuration * this.flip.progress; startRatio = this.flip.progress; this.flip.auto = true; animate = function () { return requestAnimationFrame(function () { var ratio, t; t = Date.now() - t0; ratio = startRatio - startRatio * t / duration; if (ratio < 0) { ratio = 0; } this$1$1.flip.progress = ratio; if (ratio > 0) { return animate(); } else { this$1$1.firstPage = this$1$1.currentPage; this$1$1.secondPage = this$1$1.currentPage + 1; if (this$1$1.displayedPages === 1 && this$1$1.flip.direction !== this$1$1.forwardDirection) { this$1$1.flip.direction = null; } else { this$1$1.onImageLoad(1, function () { return this$1$1.flip.direction = null; }); } return this$1$1.flip.auto = false; } }); }; return animate(); }, onImageLoad: function(trigger, cb) { this.nImageLoad = 0; this.nImageLoadTrigger = trigger; return this.imageLoadCallback = cb; }, didLoadImage: function(ev) { if (this.imageWidth === null) { this.imageWidth = (ev.target || ev.path[0]).naturalWidth; this.imageHeight = (ev.target || ev.path[0]).naturalHeight; this.preloadImages(); } if (!this.imageLoadCallback) { return; } if (++this.nImageLoad >= this.nImageLoadTrigger) { this.imageLoadCallback(); return this.imageLoadCallback = null; } }, zoomIn: function(zoomAt) { if ( zoomAt === void 0 ) zoomAt = null; if (!this.canZoomIn) { return; } this.zoomIndex += 1; return this.zoomTo(this.zooms_[this.zoomIndex], zoomAt); }, zoomOut: function(zoomAt) { if ( zoomAt === void 0 ) zoomAt = null; if (!this.canZoomOut) { return; } this.zoomIndex -= 1; return this.zoomTo(this.zooms_[this.zoomIndex], zoomAt); }, zoomTo: function(zoom, zoomAt) { var this$1$1 = this; if ( zoomAt === void 0 ) zoomAt = null; var animate, containerFixedX, containerFixedY, end, endX, endY, fixedX, fixedY, rect, start, startX, startY, t0, viewport; viewport = this.$refs.viewport; if (zoomAt) { rect = viewport.getBoundingClientRect(); fixedX = zoomAt.pageX - rect.left; fixedY = zoomAt.pageY - rect.top; } else { fixedX = viewport.clientWidth / 2; fixedY = viewport.clientHeight / 2; } start = this.zoom; end = zoom; startX = viewport.scrollLeft; startY = viewport.scrollTop; containerFixedX = fixedX + startX; containerFixedY = fixedY + startY; endX = containerFixedX / start * end - fixedX; endY = containerFixedY / start * end - fixedY; t0 = Date.now(); this.zooming = true; this.$emit('zoom-start', zoom); animate = function () { return requestAnimationFrame(function () { var ratio, t; t = Date.now() - t0; ratio = t / this$1$1.zoomDuration; if (ratio > 1 || this$1$1.IE) { ratio = 1; } ratio = easeInOut(ratio); this$1$1.zoom = start + (end - start) * ratio; this$1$1.scrollLeft = startX + (endX - startX) * ratio; this$1$1.scrollTop = startY + (endY - startY) * ratio; if (t < this$1$1.zoomDuration) { return animate(); } else { this$1$1.$emit('zoom-end', zoom); this$1$1.zooming = false; this$1$1.zoom = zoom; this$1$1.scrollLeft = endX; return this$1$1.scrollTop = endY; } }); }; animate(); if (end > 1) { return this.preloadImages(true); } }, zoomAt: function(zoomAt) { this.zoomIndex = (this.zoomIndex + 1) % this.zooms_.length; return this.zoomTo(this.zooms_[this.zoomIndex], zoomAt); }, swipeStart: function(touch) { this.touchStartX = touch.pageX; this.touchStartY = touch.pageY; this.maxMove = 0; if (this.zoom <= 1) { if (this.dragToFlip) { return this.activeCursor = 'grab'; } } else { this.startScrollLeft = this.$refs.viewport.scrollLeft; this.startScrollTop = this.$refs.viewport.scrollTop; return this.activeCursor = 'all-scroll'; } }, swipeMove: function(touch) { var x, y; if (this.touchStartX == null) { return; } x = touch.pageX - this.touchStartX; y = touch.pageY - this.touchStartY; this.maxMove = Math.max(this.maxMove, Math.abs(x)); this.maxMove = Math.max(this.maxMove, Math.abs(y)); if (this.zoom > 1) { if (this.dragToScroll) { this.dragScroll(x, y); } return; } if (!this.dragToFlip) { return; } if (Math.abs(y) > Math.abs(x)) { return; } this.activeCursor = 'grabbing'; if (x > 0) { if (this.flip.direction === null && this.canFlipLeft && x >= this.swipeMin) { this.flipStart('left', false); } if (this.flip.direction === 'left') { this.flip.progress = x / this.pageWidth; if (this.flip.progress > 1) { this.flip.progress = 1; } } } else { if (this.flip.direction === null && this.canFlipRight && x <= -this.swipeMin) { this.flipStart('right', false); } if (this.flip.direction === 'right') { this.flip.progress = -x / this.pageWidth; if (this.flip.progress > 1) { this.flip.progress = 1; } } } return true; }, swipeEnd: function(touch) { if (this.touchStartX == null) { return; } if (this.clickToZoom && this.maxMove < this.swipeMin) { this.zoomAt(touch); } if (this.flip.direction !== null && !this.flip.auto) { if (this.flip.progress > 1 / 4) { this.flipAuto(false); } else { this.flipRevert(); } } this.touchStartX = null; return this.activeCursor = null; }, onTouchStart: function(ev) { this.hasTouchEvents = true; return this.swipeStart(ev.changedTouches[0]); }, onTouchMove: function(ev) { if (this.swipeMove(ev.changedTouches[0])) { if (ev.cancelable) { return ev.preventDefault(); } } }, onTouchEnd: function(ev) { return this.swipeEnd(ev.changedTouches[0]); }, onPointerDown: function(ev) { this.hasPointerEvents = true; if (this.hasTouchEvents) { return; } if (ev.which && ev.which !== 1) { // Ignore right-click return; } this.swipeStart(ev); try { return ev.target.setPointerCapture(ev.pointerId); } catch (error) { } }, onPointerMove: function(ev) { if (!this.hasTouchEvents) { return this.swipeMove(ev); } }, onPointerUp: function(ev) { if (this.hasTouchEvents) { return; } this.swipeEnd(ev); try { return ev.target.releasePointerCapture(ev.pointerId); } catch (error) { } }, onMouseDown: function(ev) { if (this.hasTouchEvents || this.hasPointerEvents) { return; } if (ev.which && ev.which !== 1) { // Ignore right-click return; } return this.swipeStart(ev); }, onMouseMove: function(ev) { if (!(this.hasTouchEvents || this.hasPointerEvents)) { return this.swipeMove(ev); } }, onMouseUp: function(ev) { if (!(this.hasTouchEvents || this.hasPointerEvents)) { return this.swipeEnd(ev); } }, dragScroll: function(x, y) { this.scrollLeft = this.startScrollLeft - x; return this.scrollTop = this.startScrollTop - y; }, onWheel: function(ev) { if (this.wheel === 'scroll' && this.zoom > 1 && this.dragToScroll) { this.scrollLeft = this.$refs.viewport.scrollLeft + ev.deltaX; this.scrollTop = this.$refs.viewport.scrollTop + ev.deltaY; if (ev.cancelable) { ev.preventDefault(); } } if (this.wheel === 'zoom') { if (ev.deltaY >= 100) { this.zoomOut(ev); return ev.preventDefault(); } else if (ev.deltaY <= -100) { this.zoomIn(ev); return ev.preventDefault(); } } }, preloadImages: function(hiRes) { if ( hiRes === void 0 ) hiRes = false; var i, j, k, ref, ref1, ref2, ref3, src; for (i = j = ref = this.currentPage - 3, ref1 = this.currentPage + 3; (ref <= ref1 ? j <= ref1 : j >= ref1); i = ref <= ref1 ? ++j : --j) { this.pageUrlLoading(i); // this preloads image } if (hiRes) { for (i = k = ref2 = this.currentPage, ref3 = this.currentPage + this.displayedPages; (ref2 <= ref3 ? k < ref3 : k > ref3); i = ref2 <= ref3 ? ++k : --k) { src = this.pagesHiRes[i]; if (src) { (new Image()).src = src; } } } }, goToPage: function(p) { if (p === null || p === this.page) { return; } if (this.pages[0] === null) { if (this.displayedPages === 2 && p === 1) { this.currentPage = 0; } else { this.currentPage = p; } } else { this.currentPage = p - 1; } this.minX = 2e308; this.maxX = -2e308; return this.currentCenterOffset = this.centerOffset; }, loadImage: function(url) { var this$1$1 = this; var img; if (this.imageWidth === null) { // First loaded image defines the image width and height. // So it must be true image, not 'loading' image. return url; } else { if (this.loadedImages[url]) { return url; } else { img = new Image(); img.onload = function () { if (this$1$1.$set) { return this$1$1.$set(this$1$1.loadedImages, url, true); } else { return this$1$1.loadedImages[url] = true; } }; img.src = url; return this.loadingImage; } } } }, watch: { currentPage: function() { this.firstPage = this.currentPage; this.secondPage = this.currentPage + 1; return this.preloadImages(); }, centerOffset: function() { var this$1$1 = this; var animate; if (this.animatingCenter) { return; } animate = function () { return requestAnimationFrame(function () { var diff, rate; rate = 0.1; diff = this$1$1.centerOffset - this$1$1.currentCenterOffset; if (Math.abs(diff) < 0.5) { this$1$1.currentCenterOffset = this$1$1.centerOffset; return this$1$1.animatingCenter = false; } else { this$1$1.currentCenterOffset += diff * rate; return animate(); } }); }; this.animatingCenter = true; return animate(); }, scrollLeftLimited: function(val) { var this$1$1 = this; if (this.IE) { return requestAnimationFrame(function () { return this$1$1.$refs.viewport.scrollLeft = val; }); } else { return this.$refs.viewport.scrollLeft = val; } }, scrollTopLimited: function(val) { var this$1$1 = this; if (this.IE) { return requestAnimationFrame(function () { return this$1$1.$refs.viewport.scrollTop = val; }); } else { return this.$refs.viewport.scrollTop = val; } }, pages: function(after, before) { this.fixFirstPage(); if (!(before != null ? before.length : void 0) && (after != null ? after.length : void 0)) { if (this.startPage > 1 && after[0] === null) { return this.currentPage++; } } }, startPage: function(p) { return this.goToPage(p); } } }; var _hoisted_1 = ["src"]; var _hoisted_2 = ["src"]; function render(_ctx, _cache) { return (vue.openBlock(), vue.createElementBlock("div", null, [ vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps({ canFlipLeft: _ctx.canFlipLeft, canFlipRight: _ctx.canFlipRight, canZoomIn: _ctx.canZoomIn, canZoomOut: _ctx.canZoomOut, page: _ctx.page, numPages: _ctx.numPages, flipLeft: _ctx.flipLeft, flipRight: _ctx.flipRight, zoomIn: _ctx.zoomIn, zoomOut: _ctx.zoomOut, }))), vue.createElementVNode("div", { class: vue.normalizeClass(["viewport", { zoom: _ctx.zooming || _ctx.zoom > 1, 'drag-to-scroll': _ctx.dragToScroll, }]), ref: "viewport", style: vue.normalizeStyle({ cursor: _ctx.cursor == 'grabbing' ? 'grabbing' : 'auto' }), onTouchmove: _cache[7] || (_cache[7] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onTouchMove && _ctx.onTouchMove.apply(_ctx, args)); }), onPointermove: _cache[8] || (_cache[8] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onPointerMove && _ctx.onPointerMove.apply(_ctx, args)); }), onMousemove: _cache[9] || (_cache[9] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onMouseMove && _ctx.onMouseMove.apply(_ctx, args)); }), onTouchend: _cache[10] || (_cache[10] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onTouchEnd && _ctx.onTouchEnd.apply(_ctx, args)); }), onTouchcancel: _cache[11] || (_cache[11] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onTouchEnd && _ctx.onTouchEnd.apply(_ctx, args)); }), onPointerup: _cache[12] || (_cache[12] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onPointerUp && _ctx.onPointerUp.apply(_ctx, args)); }), onPointercancel: _cache[13] || (_cache[13] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onPointerUp && _ctx.onPointerUp.apply(_ctx, args)); }), onMouseup: _cache[14] || (_cache[14] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onMouseUp && _ctx.onMouseUp.apply(_ctx, args)); }), onWheel: _cache[15] || (_cache[15] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onWheel && _ctx.onWheel.apply(_ctx, args)); }) }, [ vue.createElementVNode("div", { class: "flipbook-container", style: vue.normalizeStyle({ transform: ("scale(" + (_ctx.zoom) + ")") }) }, [ vue.createElementVNode("div", { class: "click-to-flip left", style: vue.normalizeStyle({ cursor: _ctx.canFlipLeft ? 'pointer' : 'auto' }), onClick: _cache[0] || (_cache[0] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.flipLeft && _ctx.flipLeft.apply(_ctx, args)); }) }, null, 4 /* STYLE */), vue.createElementVNode("div", { class: "click-to-flip right", style: vue.normalizeStyle({ cursor: _ctx.canFlipRight ? 'pointer' : 'auto' }), onClick: _cache[1] || (_cache[1] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.flipRight && _ctx.flipRight.apply(_ctx, args)); }) }, null, 4 /* STYLE */), vue.createElementVNode("div", { style: vue.normalizeStyle({ transform: ("translateX(" + (_ctx.centerOffsetSmoothed) + "px)") }) }, [ (_ctx.showLeftPage) ? (vue.openBlock(), vue.createElementBlock("img", { key: 0, class: "page fixed", style: vue.normalizeStyle({ width: _ctx.pageWidth + 'px', height: _ctx.pageHeight + 'px', left: _ctx.xMargin + 'px', top: _ctx.yMargin + 'px', }), src: _ctx.pageUrlLoading(_ctx.leftPage, true), onLoad: _cache[2] || (_cache[2] = function ($event) { return (_ctx.didLoadImage($event)); }) }, null, 44 /* STYLE, PROPS, HYDRATE_EVENTS */, _hoisted_1)) : vue.createCommentVNode("v-if", true), (_ctx.showRightPage) ? (vue.openBlock(), vue.createElementBlock("img", { key: 1, class: "page fixed", style: vue.normalizeStyle({ width: _ctx.pageWidth + 'px', height: _ctx.pageHeight + 'px', left: _ctx.viewWidth / 2 + 'px', top: _ctx.yMargin + 'px', }), src: _ctx.pageUrlLoading(_ctx.rightPage, true), onLoad: _cache[3] || (_cache[3] = function ($event) { return (_ctx.didLoadImage($event)); }) }, null, 44 /* STYLE, PROPS, HYDRATE_EVENTS */, _hoisted_2)) : vue.createCommentVNode("v-if", true), vue.createElementVNode("div", { style: vue.normalizeStyle({ opacity: _ctx.flip.opacity }) }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.polygonArray, function (ref) { var key = ref[0]; var bgImage = ref[1]; var lighting = ref[2]; var bgPos = ref[3]; var transform = ref[4]; var z = ref[5]; return (vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(["polygon", { blank: !bgImage }]), key: key, style: vue.normalizeStyle({ backgroundImage: bgImage && ("url(" + (_ctx.loadImage(bgImage)) + ")"), backgroundSize: _ctx.polygonBgSize, backgroundPosition: bgPos, width: _ctx.polygonWidth, height: _ctx.polygonHeight, transform: transform, zIndex: z, }) }, [ vue.withDirectives(vue.createElementVNode("div", { class: "lighting", style: vue.normalizeStyle({ backgroundImage: lighting }) }, null, 4 /* STYLE */), [ [vue.vShow, lighting.length] ]) ], 6 /* CLASS, STYLE */)) }), 128 /* KEYED_FRAGMENT */)) ], 4 /* STYLE */), vue.createElementVNode("div", { class: "bounding-box", style: vue.normalizeStyle({ left: _ctx.boundingLeft + 'px', top: _ctx.yMargin + 'px', width: _ctx.boundingRight - _ctx.boundingLeft + 'px', height: _ctx.pageHeight + 'px', cursor: _ctx.cursor, }), onTouchstart: _cache[4] || (_cache[4] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onTouchStart && _ctx.onTouchStart.apply(_ctx, args)); }), onPointerdown: _cache[5] || (_cache[5] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onPointerDown && _ctx.onPointerDown.apply(_ctx, args)); }), onMousedown: _cache[6] || (_cache[6] = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return (_ctx.onMouseDown && _ctx.onMouseDown.apply(_ctx, args)); }) }, null, 36 /* STYLE, HYDRATE_EVENTS */) ], 4 /* STYLE */) ], 4 /* STYLE */) ], 38 /* CLASS, STYLE, HYDRATE_EVENTS */) ])) } var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else { a=c(); }65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes){ for(var t=Object.keys(r.attributes),n=0;n<t.length;n++){ e.setAttribute(t[n],r.attributes[t[n]]); } }var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}} var css = ".viewport[data-v-5c04eecf]{-webkit-overflow-scrolling:touch;height:100%;width:100%}.viewport.zoom[data-v-5c04eecf]{overflow:scroll}.viewport.zoom.drag-to-scroll[data-v-5c04eecf]{overflow:hidden}.flipbook-container[data-v-5c04eecf]{height:100%;position:relative;-webkit-transform-origin:top left;transform-origin:top left;-webkit-user-select:none;user-select:none;width:100%}.click-to-flip[data-v-5c04eecf]{height:100%;position:absolute;top:0;-webkit-user-select:none;user-select:none;width:50%}.click-to-flip.left[data-v-5c04eecf]{left:0}.click-to-flip.right[data-v-5c04eecf]{right:0}.bounding-box[data-v-5c04eecf]{position:absolute;-webkit-user-select:none;user-select:none}.page[data-v-5c04eecf],.polygon[data-v-5c04eecf]{-webkit-backface-visibility:hidden;backface-visibility:hidden;position:absolute}.polygon[data-v-5c04eecf]{background-repeat:no-repeat;left:0;top:0;-webkit-transform-origin:center left;transform-origin:center left}.polygon.blank[data-v-5c04eecf]{background-color:#ddd}.polygon .lighting[data-v-5c04eecf]{height:100%;width:100%}"; n(css,{}); script.render = render; script.__scopeId = "data-v-5c04eecf"; script.__file = "src/Flipbook.vue"; module.exports = script;