qb-flip-book
Version:
2,141 lines • 73.4 kB
JavaScript
var L = Object.defineProperty;
var W = (a, e, t) => e in a ? L(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var r = (a, e, t) => (W(a, typeof e != "symbol" ? e + "" : e, t), t);
var u = /* @__PURE__ */ ((a) => (a[a.LEFT = 0] = "LEFT", a[a.RIGHT = 1] = "RIGHT", a))(u || {}), w = /* @__PURE__ */ ((a) => (a.SOFT = "soft", a.HARD = "hard", a))(w || {});
class v {
constructor(e, t) {
/** State of the page on the basis of which rendering */
r(this, "state");
/** Render object */
r(this, "render");
/** Page Orientation */
r(this, "orientation");
/** Density at creation */
r(this, "createdDensity");
/** Density at the time of rendering (Depends on neighboring pages) */
r(this, "nowDrawingDensity");
this.state = {
angle: 0,
area: [],
position: { x: 0, y: 0 },
hardAngle: 0,
hardDrawingAngle: 0
}, this.createdDensity = t, this.nowDrawingDensity = this.createdDensity, this.render = e;
}
/**
* Set a constant page density
*
* @param {PageDensity} density
*/
setDensity(e) {
this.createdDensity = e, this.nowDrawingDensity = e;
}
/**
* Set temp page density to next render
*
* @param {PageDensity} density
*/
setDrawingDensity(e) {
this.nowDrawingDensity = e;
}
/**
* Set page position
*
* @param {Point} pagePos
*/
setPosition(e) {
this.state.position = e;
}
/**
* Set page angle
*
* @param {number} angle
*/
setAngle(e) {
this.state.angle = e;
}
/**
* Set page crop area
*
* @param {Point[]} area
*/
setArea(e) {
this.state.area = e;
}
/**
* Rotate angle for hard pages to next render
*
* @param {number} angle
*/
setHardDrawingAngle(e) {
this.state.hardDrawingAngle = e;
}
/**
* Rotate angle for hard pages
*
* @param {number} angle
*/
setHardAngle(e) {
this.state.hardAngle = e, this.state.hardDrawingAngle = e;
}
/**
* Set page orientation
*
* @param {PageOrientation} orientation
*/
setOrientation(e) {
this.orientation = e;
}
/**
* Get temp page density
*/
getDrawingDensity() {
return this.nowDrawingDensity;
}
/**
* Get a constant page density
*/
getDensity() {
return this.createdDensity;
}
/**
* Get rotate angle for hard pages
*/
getHardAngle() {
return this.state.hardAngle;
}
}
class M extends v {
constructor(t, i, s) {
super(t, s);
r(this, "image", null);
r(this, "isLoad", !1);
r(this, "loadingAngle", 0);
this.image = new Image(), this.image.src = i;
}
draw(t) {
console.log("%c tempDensity: ", "background-color: pink", t);
const i = this.render.getContext(), s = this.render.convertToGlobal(this.state.position), n = this.render.getRect().pageWidth, h = this.render.getRect().height;
i.save(), i.translate(s.x, s.y), i.beginPath();
for (let o of this.state.area)
o !== null && (o = this.render.convertToGlobal(o), i.lineTo(o.x - s.x, o.y - s.y));
i.rotate(this.state.angle), i.clip(), this.isLoad ? i.drawImage(this.image, 0, 0, n, h) : this.drawLoader(i, { x: 0, y: 0 }, n, h), i.restore();
}
simpleDraw(t) {
const i = this.render.getRect(), s = this.render.getContext(), n = i.pageWidth, h = i.height, o = t === u.RIGHT ? i.left + i.pageWidth : i.left, g = i.top;
this.isLoad ? s.drawImage(this.image, o, g, n, h) : this.drawLoader(s, { x: o, y: g }, n, h);
}
drawLoader(t, i, s, n) {
t.beginPath(), t.strokeStyle = "rgb(200, 200, 200)", t.fillStyle = "rgb(255, 255, 255)", t.lineWidth = 1, t.rect(i.x + 1, i.y + 1, s - 1, n - 1), t.stroke(), t.fill();
const h = {
x: i.x + s / 2,
y: i.y + n / 2
};
t.beginPath(), t.lineWidth = 10, t.arc(
h.x,
h.y,
20,
this.loadingAngle,
3 * Math.PI / 2 + this.loadingAngle
), t.stroke(), t.closePath(), this.loadingAngle += 0.07, this.loadingAngle >= 2 * Math.PI && (this.loadingAngle = 0);
}
load() {
this.isLoad || (this.image.onload = () => {
this.isLoad = !0;
});
}
newTemporaryCopy() {
return this;
}
getTemporaryCopy() {
return this;
}
hideTemporaryCopy() {
}
}
class d {
/**
* Get the distance between two points
*
* @param {Point} point1
* @param {Point} point2
*/
static GetDistanceBetweenTwoPoint(e, t) {
return e === null || t === null ? 1 / 0 : Math.sqrt(
Math.pow(t.x - e.x, 2) + Math.pow(t.y - e.y, 2)
);
}
/**
* Get the length of the line segment
*
* @param {Segment} segment
*/
static GetSegmentLength(e) {
return d.GetDistanceBetweenTwoPoint(e[0], e[1]);
}
/**
* Get the angle between two lines
*
* @param {Segment} line1
* @param {Segment} line2
*/
static GetAngleBetweenTwoLine(e, t) {
const i = e[0].y - e[1].y, s = t[0].y - t[1].y, n = e[1].x - e[0].x, h = t[1].x - t[0].x;
return Math.acos(
(i * s + n * h) / (Math.sqrt(i * i + n * n) * Math.sqrt(s * s + h * h))
);
}
/**
* Check for a point in a rectangle
*
* @param {Rect} rect
* @param {Point} pos
*
* @returns {Point} If the point enters the rectangle its coordinates will be returned, otherwise - null
*/
static PointInRect(e, t) {
return t === null ? null : t.x >= e.left && t.x <= e.width + e.left && t.y >= e.top && t.y <= e.top + e.height ? t : null;
}
/**
* Transform point coordinates to a given angle
*
* @param {Point} transformedPoint - Point to rotate
* @param {Point} startPoint - Transformation reference point
* @param {number} angle - Rotation angle (in radians)
*
* @returns {Point} Point coordinates after rotation
*/
static GetRotatedPoint(e, t, i) {
return {
x: e.x * Math.cos(i) + e.y * Math.sin(i) + t.x,
y: e.y * Math.cos(i) - e.x * Math.sin(i) + t.y
};
}
/**
* Limit a point "linePoint" to a given circle centered at point "startPoint" and a given radius
*
* @param {Point} startPoint - Circle center
* @param {number} radius - Circle radius
* @param {Point} limitedPoint - Сhecked point
*
* @returns {Point} If "linePoint" enters the circle, then its coordinates are returned.
* Else will be returned the intersection point between the line ([startPoint, linePoint]) and the circle
*/
static LimitPointToCircle(e, t, i) {
if (d.GetDistanceBetweenTwoPoint(e, i) <= t)
return i;
const s = e.x, n = e.y, h = i.x, o = i.y;
let g = Math.sqrt(
Math.pow(t, 2) * Math.pow(s - h, 2) / (Math.pow(s - h, 2) + Math.pow(n - o, 2))
) + s;
i.x < 0 && (g *= -1);
let c = (g - s) * (n - o) / (s - h) + n;
return s - h + n === 0 && (c = t), { x: g, y: c };
}
/**
* Find the intersection of two lines bounded by a rectangle "rectBorder"
*
* @param {Rect} rectBorder
* @param {Segment} one
* @param {Segment} two
*
* @returns {Point} The intersection point, or "null" if it does not exist, or it lies outside the rectangle "rectBorder"
*/
static GetIntersectBetweenTwoSegment(e, t, i) {
return d.PointInRect(
e,
d.GetIntersectBeetwenTwoLine(t, i)
);
}
/**
* Find the intersection point of two lines
*
* @param one
* @param two
*
* @returns {Point} The intersection point, or "null" if it does not exist
* @throws Error if the segments are on the same line
*/
static GetIntersectBeetwenTwoLine(e, t) {
const i = e[0].y - e[1].y, s = t[0].y - t[1].y, n = e[1].x - e[0].x, h = t[1].x - t[0].x, o = e[0].x * e[1].y - e[1].x * e[0].y, g = t[0].x * t[1].y - t[1].x * t[0].y, c = i * g - s * o, x = n * g - h * o, f = -((o * h - g * n) / (i * h - s * n)), y = -((i * g - s * o) / (i * h - s * n));
if (isFinite(f) && isFinite(y))
return { x: f, y };
if (Math.abs(c - x) < 0.1)
throw new Error("Segment included");
return null;
}
/**
* Get a list of coordinates (step: 1px) between two points
*
* @param pointOne
* @param pointTwo
*
* @returns {Point[]}
*/
static GetCordsFromTwoPoint(e, t) {
const i = Math.abs(e.x - t.x), s = Math.abs(e.y - t.y), n = Math.max(i, s), h = [e];
function o(g, c, x, f, y) {
return c > g ? g + y * (x / f) : c < g ? g - y * (x / f) : g;
}
for (let g = 1; g <= n; g += 1)
h.push({
x: o(e.x, t.x, i, n, g),
y: o(e.y, t.y, s, n, g)
});
return h;
}
}
class O {
/**
* @constructor
*
* @param {FlipDirection} direction - Flipping direction
* @param {FlipCorner} corner - Flipping corner
* @param pageWidth - Current page width
* @param pageHeight - Current page height
*/
constructor(e, t, i, s) {
/** Calculated rotation angle to flipping page */
r(this, "angle");
/** Calculated position to flipping page */
r(this, "position");
r(this, "rect");
/** The point of intersection of the page with the borders of the book */
r(this, "topIntersectPoint", null);
// With top border
r(this, "sideIntersectPoint", null);
// With side border
r(this, "bottomIntersectPoint", null);
// With bottom border
r(this, "pageWidth");
r(this, "pageHeight");
this.direction = e, this.corner = t, this.pageWidth = parseInt(i, 10), this.pageHeight = parseInt(s, 10);
}
/**
* The main calculation method
*
* @param {Point} localPos - Touch Point Coordinates (relative active page!)
*
* @returns {boolean} True - if the calculations were successful, false if errors occurred
*/
calc(e) {
try {
return this.position = this.calcAngleAndPosition(e), this.calculateIntersectPoint(this.position), !0;
} catch {
return !1;
}
}
/**
* Get the crop area for the flipping page
*
* @returns {Point[]} Polygon page
*/
getFlippingClipArea() {
const e = [];
let t = !1;
return e.push(this.rect.topLeft), e.push(this.topIntersectPoint), this.sideIntersectPoint === null ? t = !0 : (e.push(this.sideIntersectPoint), this.bottomIntersectPoint === null && (t = !1)), e.push(this.bottomIntersectPoint), (t || this.corner === p.BOTTOM) && e.push(this.rect.bottomLeft), e;
}
/**
* Get the crop area for the page that is below the page to be flipped
*
* @returns {Point[]} Polygon page
*/
getBottomClipArea() {
const e = [];
return e.push(this.topIntersectPoint), this.corner === p.TOP ? e.push({ x: this.pageWidth, y: 0 }) : (this.topIntersectPoint !== null && e.push({ x: this.pageWidth, y: 0 }), e.push({ x: this.pageWidth, y: this.pageHeight })), this.sideIntersectPoint !== null ? d.GetDistanceBetweenTwoPoint(
this.sideIntersectPoint,
this.topIntersectPoint
) >= 10 && e.push(this.sideIntersectPoint) : this.corner === p.TOP && e.push({ x: this.pageWidth, y: this.pageHeight }), e.push(this.bottomIntersectPoint), e.push(this.topIntersectPoint), e;
}
/**
* Get page rotation angle
*/
getAngle() {
return this.direction === l.FORWARD ? -this.angle : this.angle;
}
/**
* Get page area while flipping
*/
getRect() {
return this.rect;
}
/**
* Get the position of the active angle when turning
*/
getPosition() {
return this.position;
}
/**
* Get the active corner of the page (which pull)
*/
getActiveCorner() {
return this.direction === l.FORWARD ? this.rect.topLeft : this.rect.topRight;
}
/**
* Get flipping direction
*/
getDirection() {
return this.direction;
}
/**
* Get flipping progress (0-100)
*/
getFlippingProgress() {
return Math.abs(
(this.position.x - this.pageWidth) / (2 * this.pageWidth) * 100
);
}
/**
* Get flipping corner position (top, bottom)
*/
getCorner() {
return this.corner;
}
/**
* Get start position for the page that is below the page to be flipped
*/
getBottomPagePosition() {
return this.direction === l.BACK ? { x: this.pageWidth, y: 0 } : { x: 0, y: 0 };
}
/**
* Get the starting position of the shadow
*/
getShadowStartPoint() {
return this.corner === p.TOP ? this.topIntersectPoint : this.sideIntersectPoint !== null ? this.sideIntersectPoint : this.topIntersectPoint;
}
/**
* Get the rotate angle of the shadow
*/
getShadowAngle() {
const e = d.GetAngleBetweenTwoLine(this.getSegmentToShadowLine(), [
{ x: 0, y: 0 },
{ x: this.pageWidth, y: 0 }
]);
return this.direction === l.FORWARD ? e : Math.PI - e;
}
calcAngleAndPosition(e) {
let t = e;
if (this.updateAngleAndGeometry(t), this.corner === p.TOP ? t = this.checkPositionAtCenterLine(
t,
{ x: 0, y: 0 },
{ x: 0, y: this.pageHeight }
) : t = this.checkPositionAtCenterLine(
t,
{ x: 0, y: this.pageHeight },
{ x: 0, y: 0 }
), Math.abs(t.x - this.pageWidth) < 1 && Math.abs(t.y) < 1)
throw new Error("Point is too small");
return t;
}
updateAngleAndGeometry(e) {
this.angle = this.calculateAngle(e), this.rect = this.getPageRect(e);
}
calculateAngle(e) {
const t = this.pageWidth - e.x + 1, i = this.corner === p.BOTTOM ? this.pageHeight - e.y : e.y;
let s = 2 * Math.acos(t / Math.sqrt(i * i + t * t));
i < 0 && (s = -s);
const n = Math.PI - s;
if (!isFinite(s) || n >= 0 && n < 3e-3)
throw new Error("The G point is too small");
return this.corner === p.BOTTOM && (s = -s), s;
}
getPageRect(e) {
return this.corner === p.TOP ? this.getRectFromBasePoint(
[
{ x: 0, y: 0 },
{ x: this.pageWidth, y: 0 },
{ x: 0, y: this.pageHeight },
{ x: this.pageWidth, y: this.pageHeight }
],
e
) : this.getRectFromBasePoint(
[
{ x: 0, y: -this.pageHeight },
{ x: this.pageWidth, y: -this.pageHeight },
{ x: 0, y: 0 },
{ x: this.pageWidth, y: 0 }
],
e
);
}
getRectFromBasePoint(e, t) {
return {
topLeft: this.getRotatedPoint(e[0], t),
topRight: this.getRotatedPoint(e[1], t),
bottomLeft: this.getRotatedPoint(e[2], t),
bottomRight: this.getRotatedPoint(e[3], t)
};
}
getRotatedPoint(e, t) {
return {
x: e.x * Math.cos(this.angle) + e.y * Math.sin(this.angle) + t.x,
y: e.y * Math.cos(this.angle) - e.x * Math.sin(this.angle) + t.y
};
}
calculateIntersectPoint(e) {
const t = {
left: -1,
top: -1,
width: this.pageWidth + 2,
height: this.pageHeight + 2
};
this.corner === p.TOP ? (this.topIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[e, this.rect.topRight],
[
{ x: 0, y: 0 },
{ x: this.pageWidth, y: 0 }
]
), this.sideIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[e, this.rect.bottomLeft],
[
{ x: this.pageWidth, y: 0 },
{ x: this.pageWidth, y: this.pageHeight }
]
), this.bottomIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[this.rect.bottomLeft, this.rect.bottomRight],
[
{ x: 0, y: this.pageHeight },
{ x: this.pageWidth, y: this.pageHeight }
]
)) : (this.topIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[this.rect.topLeft, this.rect.topRight],
[
{ x: 0, y: 0 },
{ x: this.pageWidth, y: 0 }
]
), this.sideIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[e, this.rect.topLeft],
[
{ x: this.pageWidth, y: 0 },
{ x: this.pageWidth, y: this.pageHeight }
]
), this.bottomIntersectPoint = d.GetIntersectBetweenTwoSegment(
t,
[this.rect.bottomLeft, this.rect.bottomRight],
[
{ x: 0, y: this.pageHeight },
{ x: this.pageWidth, y: this.pageHeight }
]
));
}
checkPositionAtCenterLine(e, t, i) {
let s = e;
const n = d.LimitPointToCircle(t, this.pageWidth, s);
s !== n && (s = n, this.updateAngleAndGeometry(s));
const h = Math.sqrt(
Math.pow(this.pageWidth, 2) + Math.pow(this.pageHeight, 2)
);
let o = this.rect.bottomRight, g = this.rect.topLeft;
if (this.corner === p.BOTTOM && (o = this.rect.topRight, g = this.rect.bottomLeft), o.x <= 0) {
const c = d.LimitPointToCircle(
i,
h,
g
);
c !== s && (s = c, this.updateAngleAndGeometry(s));
}
return s;
}
getSegmentToShadowLine() {
const e = this.getShadowStartPoint(), t = e !== this.sideIntersectPoint && this.sideIntersectPoint !== null ? this.sideIntersectPoint : this.bottomIntersectPoint;
return [e, t];
}
}
var l = /* @__PURE__ */ ((a) => (a[a.FORWARD = 0] = "FORWARD", a[a.BACK = 1] = "BACK", a))(l || {}), p = /* @__PURE__ */ ((a) => (a.TOP = "top", a.BOTTOM = "bottom", a))(p || {}), P = /* @__PURE__ */ ((a) => (a.USER_FOLD = "user_fold", a.FOLD_CORNER = "fold_corner", a.FLIPPING = "flipping", a.READ = "read", a))(P || {});
class T {
constructor(e, t) {
r(this, "render");
r(this, "app");
r(this, "flippingPage", null);
r(this, "bottomPage", null);
r(this, "calc", null);
r(this, "state", "read");
this.render = e, this.app = t;
}
/**
* Called when the page folding (User drags page corner)
*
* @param globalPos - Touch Point Coordinates (relative window)
*/
fold(e) {
this.setState(
"user_fold"
/* USER_FOLD */
), this.calc === null && this.start(e), this.do(this.render.convertToPage(e));
}
/**
* Page turning with animation
*
* @param globalPos - Touch Point Coordinates (relative window)
*/
flip(e) {
if (this.app.getSettings().disableFlipByClick && !this.isPointOnCorners(e) || (this.calc !== null && this.render.finishAnimation(), !this.start(e)))
return;
const t = this.getBoundsRect();
this.setState(
"flipping"
/* FLIPPING */
);
const i = t.height / 10, s = this.calc.getCorner() === "bottom" ? t.height - i : i, n = this.calc.getCorner() === "bottom" ? t.height : 0;
this.calc.calc({ x: t.pageWidth - i, y: s }), this.animateFlippingTo(
{ x: t.pageWidth - i, y: s },
{ x: -t.pageWidth, y: n },
!0
);
}
/**
* Start the flipping process. Find direction and corner of flipping. Creating an object for calculation.
*
* @param {Point} globalPos - Touch Point Coordinates (relative window)
*
* @returns {boolean} True if flipping is possible, false otherwise
*/
start(e) {
this.reset();
const t = this.render.convertToBook(e), i = this.getBoundsRect(), s = this.getDirectionByPoint(t), n = t.y >= i.height / 2 ? "bottom" : "top";
if (!this.checkDirection(s))
return !1;
try {
if (this.flippingPage = this.app.getPageCollection().getFlippingPage(s), this.bottomPage = this.app.getPageCollection().getBottomPage(s), this.render.getOrientation() === m.LANDSCAPE)
if (s === 1) {
const h = this.app.getPageCollection().nextBy(this.flippingPage);
h !== null && this.flippingPage.getDensity() !== h.getDensity() && (this.flippingPage.setDrawingDensity(w.HARD), h.setDrawingDensity(w.HARD));
} else {
const h = this.app.getPageCollection().prevBy(this.flippingPage);
h !== null && this.flippingPage.getDensity() !== h.getDensity() && (this.flippingPage.setDrawingDensity(w.HARD), h.setDrawingDensity(w.HARD));
}
return this.render.setDirection(s), this.calc = new O(
s,
n,
i.pageWidth.toString(10),
// fix bug with type casting
i.height.toString(10)
// fix bug with type casting
), !0;
} catch {
return !1;
}
}
/**
* Perform calculations for the current page position. Pass data to render object
*
* @param {Point} pagePos - Touch Point Coordinates (relative active page)
*/
do(e) {
if (this.calc !== null && this.calc.calc(e)) {
const t = this.calc.getFlippingProgress();
this.bottomPage.setArea(this.calc.getBottomClipArea()), this.bottomPage.setPosition(this.calc.getBottomPagePosition()), this.bottomPage.setAngle(0), this.bottomPage.setHardAngle(0), this.flippingPage.setArea(this.calc.getFlippingClipArea()), this.flippingPage.setPosition(this.calc.getActiveCorner()), this.flippingPage.setAngle(this.calc.getAngle()), this.calc.getDirection() === 0 ? this.flippingPage.setHardAngle(90 * (200 - t * 2) / 100) : this.flippingPage.setHardAngle(-90 * (200 - t * 2) / 100), this.render.setPageRect(this.calc.getRect()), this.render.setBottomPage(this.bottomPage), this.render.setFlippingPage(this.flippingPage), this.render.setShadowData(
this.calc.getShadowStartPoint(),
this.calc.getShadowAngle(),
t,
this.calc.getDirection()
);
}
}
/**
* Turn to the specified page number (with animation)
*
* @param {number} page - New page number
* @param {FlipCorner} corner - Active page corner when turning
*/
flipToPage(e, t) {
const i = this.app.getPageCollection().getCurrentSpreadIndex(), s = this.app.getPageCollection().getSpreadIndexByPage(e);
try {
s > i && (this.app.getPageCollection().setCurrentSpreadIndex(s - 1), this.flipNext(t)), s < i && (this.app.getPageCollection().setCurrentSpreadIndex(s + 1), this.flipPrev(t));
} catch {
}
}
/**
* Turn to the next page (with animation)
*
* @param {FlipCorner} corner - Active page corner when turning
*/
flipNext(e) {
this.flip({
x: this.render.getRect().left + this.render.getRect().pageWidth * 2 - 10,
y: e === "top" ? 1 : this.render.getRect().height - 2
});
}
/**
* Turn to the prev page (with animation)
*
* @param {FlipCorner} corner - Active page corner when turning
*/
flipPrev(e) {
this.flip({
x: 10,
y: e === "top" ? 1 : this.render.getRect().height - 2
});
}
/**
* Called when the user has stopped flipping
*/
stopMove() {
if (this.calc === null)
return;
const e = this.calc.getPosition(), t = this.getBoundsRect(), i = this.calc.getCorner() === "bottom" ? t.height : 0;
e.x <= 0 ? this.animateFlippingTo(e, { x: -t.pageWidth, y: i }, !0) : this.animateFlippingTo(e, { x: t.pageWidth, y: i }, !1);
}
/**
* Fold the corners of the book when the mouse pointer is over them.
* Called when the mouse pointer is over the book without clicking
*
* @param globalPos
*/
showCorner(e) {
if (!this.checkState(
"read",
"fold_corner"
/* FOLD_CORNER */
))
return;
const t = this.getBoundsRect(), i = t.pageWidth;
if (this.isPointOnCorners(e))
if (this.calc === null) {
if (!this.start(e))
return;
this.setState(
"fold_corner"
/* FOLD_CORNER */
), this.calc.calc({ x: i - 1, y: 1 });
const s = 50, n = this.calc.getCorner() === "bottom" ? t.height - 1 : 1, h = this.calc.getCorner() === "bottom" ? t.height - s : s;
this.animateFlippingTo(
{ x: i - 1, y: n },
{ x: i - s, y: h },
!1,
!1
);
} else
this.do(this.render.convertToPage(e));
else
this.setState(
"read"
/* READ */
), this.render.finishAnimation(), this.stopMove();
}
/**
* Starting the flipping animation process
*
* @param {Point} start - animation start point
* @param {Point} dest - animation end point
* @param {boolean} isTurned - will the page turn over, or just bring it back
* @param {boolean} needReset - reset the flipping process at the end of the animation
*/
animateFlippingTo(e, t, i, s = !0) {
const n = d.GetCordsFromTwoPoint(e, t), h = [];
for (const g of n)
h.push(() => this.do(g));
const o = this.getAnimationDuration(n.length);
this.render.startAnimation(h, o, () => {
this.calc && (i && (this.calc.getDirection() === 1 ? this.app.turnToPrevPage() : this.app.turnToNextPage()), s && (this.render.setBottomPage(null), this.render.setFlippingPage(null), this.render.clearShadow(), this.setState(
"read"
/* READ */
), this.reset()));
});
}
/**
* Get the current calculations object
*/
getCalculation() {
return this.calc;
}
/**
* Get current flipping state
*/
getState() {
return this.state;
}
setState(e) {
this.state !== e && (this.app.updateState(e), this.state = e);
}
getDirectionByPoint(e) {
const t = this.getBoundsRect();
if (this.render.getOrientation() === m.PORTRAIT) {
if (e.x - t.pageWidth <= t.width / 5)
return 1;
} else if (e.x < t.width / 2)
return 1;
return 0;
}
getAnimationDuration(e) {
const t = this.app.getSettings().flippingTime;
return e >= 1e3 ? t : e / 1e3 * t;
}
checkDirection(e) {
return e === 0 ? this.app.getCurrentPageIndex() < this.app.getPageCount() - 1 : this.app.getCurrentPageIndex() >= 1;
}
reset() {
this.calc = null, this.flippingPage = null, this.bottomPage = null;
}
getBoundsRect() {
return this.render.getRect();
}
checkState(...e) {
for (const t of e)
if (this.state === t)
return !0;
return !1;
}
isPointOnCorners(e) {
const t = this.getBoundsRect(), i = t.pageWidth, s = Math.sqrt(Math.pow(i, 2) + Math.pow(t.height, 2)) / 5, n = this.render.convertToBook(e);
return n.x > 0 && n.y > 0 && n.x < t.width && n.y < t.height && (n.x < s || n.x > t.width - s) && (n.y < s || n.y > t.height - s);
}
}
var S = /* @__PURE__ */ ((a) => (a.FIXED = "fixed", a.STRETCH = "stretch", a))(S || {});
class H {
constructor() {
r(this, "_default", {
startPage: 0,
size: "fixed",
width: 0,
height: 0,
minWidth: 0,
maxWidth: 0,
minHeight: 0,
maxHeight: 0,
drawShadow: !0,
flippingTime: 1e3,
usePortrait: !0,
startZIndex: 0,
autoSize: !0,
maxShadowOpacity: 1,
showCover: !1,
mobileScrollSupport: !0,
swipeDistance: 30,
clickEventForward: !0,
useMouseEvents: !0,
showPageCorners: !0,
disableFlipByClick: !1
});
}
/**
* Processing parameters received from the user. Substitution default values
*
* @param userSetting
* @returns {FlipSetting} Сonfiguration object
*/
getSettings(e) {
const t = this._default;
if (Object.assign(t, e), t.size !== "stretch" && t.size !== "fixed")
throw new Error(
'Invalid size type. Available only "fixed" and "stretch" value'
);
if (t.width <= 0 || t.height <= 0)
throw new Error("Invalid width or height");
if (t.flippingTime <= 0)
throw new Error("Invalid flipping time");
return t.size === "stretch" ? (t.minWidth <= 0 && (t.minWidth = 100), t.maxWidth < t.minWidth && (t.maxWidth = 2e3), t.minHeight <= 0 && (t.minHeight = 100), t.maxHeight < t.minHeight && (t.maxHeight = 2e3)) : (t.minWidth = t.width, t.maxWidth = t.width, t.minHeight = t.height, t.maxHeight = t.height), t;
}
}
var m = /* @__PURE__ */ ((a) => (a.PORTRAIT = "portrait", a.LANDSCAPE = "landscape", a))(m || {});
class I {
constructor(e, t) {
r(this, "setting");
r(this, "app");
/** Left static book page */
r(this, "leftPage", null);
/** Right static book page */
r(this, "rightPage", null);
/** Page currently flipping */
r(this, "flippingPage", null);
/** Next page at the time of flipping */
r(this, "bottomPage", null);
/** Current flipping direction */
r(this, "direction", null);
/** Current book orientation */
r(this, "orientation", null);
/** Сurrent state of the shadows */
r(this, "shadow", null);
/** Сurrent animation process */
r(this, "animation", null);
/** Page borders while flipping */
r(this, "pageRect", null);
/** Current book area */
r(this, "boundsRect", null);
/** Timer started from start of rendering */
r(this, "timer", 0);
/**
* Safari browser definitions for resolving a bug with a css property clip-area
*
* https://bugs.webkit.org/show_bug.cgi?id=126207
*/
r(this, "safari", !1);
this.setting = t, this.app = e;
const i = new RegExp("Version\\/[\\d\\.]+.*Safari/");
this.safari = i.exec(window.navigator.userAgent) !== null;
}
/**
* Executed when requestAnimationFrame is called. Performs the current animation process and call drawFrame()
*
* @param timer
*/
render(e) {
if (this.animation !== null) {
const t = Math.round(
(e - this.animation.startedAt) / this.animation.durationFrame
);
t < this.animation.frames.length ? this.animation.frames[t]() : (this.animation.onAnimateEnd(), this.animation = null);
}
this.timer = e, this.drawFrame();
}
/**
* Running requestAnimationFrame, and rendering process
*/
start() {
this.update();
const e = (t) => {
this.render(t), requestAnimationFrame(e);
};
requestAnimationFrame(e);
}
/**
* Start a new animation process
*
* @param {FrameAction[]} frames - Frame list
* @param {number} duration - total animation duration
* @param {AnimationSuccessAction} onAnimateEnd - Animation callback function
*/
startAnimation(e, t, i) {
this.finishAnimation(), this.animation = {
frames: e,
duration: t,
durationFrame: t / e.length,
onAnimateEnd: i,
startedAt: this.timer
};
}
/**
* End the current animation process and call the callback
*/
finishAnimation() {
this.animation !== null && (this.animation.frames[this.animation.frames.length - 1](), this.animation.onAnimateEnd !== null && this.animation.onAnimateEnd()), this.animation = null;
}
/**
* Recalculate the size of the displayed area, and update the page orientation
*/
update() {
this.boundsRect = null;
const e = this.calculateBoundsRect();
this.orientation !== e && (this.orientation = e, this.app.updateOrientation(e));
}
/**
* Calculate the size and position of the book depending on the parent element and configuration parameters
*/
calculateBoundsRect() {
let e = "landscape";
const t = this.getBlockWidth(), i = {
x: t / 2,
y: this.getBlockHeight() / 2
}, s = this.setting.width / this.setting.height;
let n = this.setting.width, h = this.setting.height, o = i.x - n;
return this.setting.size === S.STRETCH ? (t < this.setting.minWidth * 2 && this.app.getSettings().usePortrait && (e = "portrait"), n = e === "portrait" ? this.getBlockWidth() : this.getBlockWidth() / 2, n > this.setting.maxWidth && (n = this.setting.maxWidth), h = n / s, h > this.getBlockHeight() && (h = this.getBlockHeight(), n = h * s), o = e === "portrait" ? i.x - n / 2 - n : i.x - n) : t < n * 2 && this.app.getSettings().usePortrait && (e = "portrait", o = i.x - n / 2 - n), this.boundsRect = {
left: o,
top: i.y - h / 2,
width: n * 2,
height: h,
pageWidth: n
}, e;
}
/**
* Set the current parameters of the drop shadow
*
* @param {Point} pos - Shadow Position Start Point
* @param {number} angle - The angle of the shadows relative to the book
* @param {number} progress - Flipping progress in percent (0 - 100)
* @param {FlipDirection} direction - Flipping Direction, the direction of the shadow gradients
*/
setShadowData(e, t, i, s) {
if (!this.app.getSettings().drawShadow)
return;
const n = 100 * this.getSettings().maxShadowOpacity;
this.shadow = {
pos: e,
angle: t,
width: this.getRect().pageWidth * 3 / 4 * i / 100,
opacity: (100 - i) * n / 100 / 100,
direction: s,
progress: i * 2
};
}
/**
* Clear shadow
*/
clearShadow() {
this.shadow = null;
}
/**
* Get parent block offset width
*/
getBlockWidth() {
return this.app.getUI().getDistElement().offsetWidth;
}
/**
* Get parent block offset height
*/
getBlockHeight() {
return this.app.getUI().getDistElement().offsetHeight;
}
/**
* Get current flipping direction
*/
getDirection() {
return this.direction;
}
/**
* Сurrent size and position of the book
*/
getRect() {
return this.boundsRect === null && this.calculateBoundsRect(), this.boundsRect;
}
/**
* Get configuration object
*/
getSettings() {
return this.app.getSettings();
}
/**
* Get current book orientation
*/
getOrientation() {
return this.orientation;
}
/**
* Set page area while flipping
*
* @param direction
*/
setPageRect(e) {
this.pageRect = e;
}
/**
* Set flipping direction
*
* @param direction
*/
setDirection(e) {
this.direction = e;
}
/**
* Set right static book page
*
* @param page
*/
setRightPage(e) {
e !== null && e.setOrientation(u.RIGHT), this.rightPage = e;
}
/**
* Set left static book page
* @param page
*/
setLeftPage(e) {
e !== null && e.setOrientation(u.LEFT), this.leftPage = e;
}
/**
* Set next page at the time of flipping
* @param page
*/
setBottomPage(e) {
e !== null && e.setOrientation(
this.direction === l.BACK ? u.LEFT : u.RIGHT
), this.bottomPage = e;
}
/**
* Set currently flipping page
*
* @param page
*/
setFlippingPage(e) {
e !== null && e.setOrientation(
this.direction === l.FORWARD && this.orientation !== "portrait" ? u.LEFT : u.RIGHT
), this.flippingPage = e;
}
/**
* Coordinate conversion function. Window coordinates -> to book coordinates
*
* @param {Point} pos - Global coordinates relative to the window
* @returns {Point} Coordinates relative to the book
*/
convertToBook(e) {
const t = this.getRect();
return {
x: e.x - t.left,
y: e.y - t.top
};
}
isSafari() {
return this.safari;
}
/**
* Coordinate conversion function. Window coordinates -> to current coordinates of the working page
*
* @param {Point} pos - Global coordinates relative to the window
* @param {FlipDirection} direction - Current flipping direction
*
* @returns {Point} Coordinates relative to the work page
*/
convertToPage(e, t) {
t || (t = this.direction);
const i = this.getRect();
return {
x: t === l.FORWARD ? e.x - i.left - i.width / 2 : i.width / 2 - e.x + i.left,
y: e.y - i.top
};
}
/**
* Coordinate conversion function. Coordinates relative to the work page -> Window coordinates
*
* @param {Point} pos - Coordinates relative to the work page
* @param {FlipDirection} direction - Current flipping direction
*
* @returns {Point} Global coordinates relative to the window
*/
convertToGlobal(e, t) {
if (t || (t = this.direction), e == null)
return null;
const i = this.getRect();
return {
x: t === l.FORWARD ? e.x + i.left + i.width / 2 : i.width / 2 - e.x + i.left,
y: e.y + i.top
};
}
/**
* Casting the coordinates of the corners of the rectangle in the coordinates relative to the window
*
* @param {RectPoints} rect - Coordinates of the corners of the rectangle relative to the work page
* @param {FlipDirection} direction - Current flipping direction
*
* @returns {RectPoints} Coordinates of the corners of the rectangle relative to the window
*/
convertRectToGlobal(e, t) {
return t || (t = this.direction), {
topLeft: this.convertToGlobal(e.topLeft, t),
topRight: this.convertToGlobal(e.topRight, t),
bottomLeft: this.convertToGlobal(e.bottomLeft, t),
bottomRight: this.convertToGlobal(e.bottomRight, t)
};
}
}
class C {
constructor(e, t) {
r(this, "app");
r(this, "render");
r(this, "isShowCover");
/** Pages List */
r(this, "pages", []);
/** Index of the current page in list */
r(this, "currentPageIndex", 0);
/** Number of the current spread in book */
r(this, "currentSpreadIndex", 0);
/** Two-page spread in landscape mode */
r(this, "landscapeSpread", []);
/** One-page spread in portrait mode */
r(this, "portraitSpread", []);
this.render = t, this.app = e, this.currentPageIndex = 0, this.isShowCover = this.app.getSettings().showCover;
}
/**
* Clear pages list
*/
destroy() {
this.pages = [];
}
/**
* Split the book on the two-page spread in landscape mode and one-page spread in portrait mode
*/
createSpread() {
this.landscapeSpread = [], this.portraitSpread = [];
for (let t = 0; t < this.pages.length; t++)
this.portraitSpread.push([t]);
let e = 0;
this.isShowCover && (this.pages[0].setDensity(w.HARD), this.landscapeSpread.push([e]), e++);
for (let t = e; t < this.pages.length; t += 2)
t < this.pages.length - 1 ? this.landscapeSpread.push([t, t + 1]) : (this.landscapeSpread.push([t]), this.pages[t].setDensity(w.HARD));
}
/**
* Get spread by mode (portrait or landscape)
*/
getSpread() {
return this.render.getOrientation() === m.LANDSCAPE ? this.landscapeSpread : this.portraitSpread;
}
/**
* Get spread index by page number
*
* @param {number} pageNum - page index
*/
getSpreadIndexByPage(e) {
const t = this.getSpread();
for (let i = 0; i < t.length; i++)
if (e === t[i][0] || e === t[i][1])
return i;
return null;
}
/**
* Get the total number of pages
*/
getPageCount() {
return this.pages.length;
}
/**
* Get the pages list
*/
getPages() {
return this.pages;
}
/**
* Get page by index
*
* @param {number} pageIndex
*/
getPage(e) {
if (e >= 0 && e < this.pages.length)
return this.pages[e];
throw new Error("Invalid page number");
}
/**
* Get the next page from the specified
*
* @param {Page} current
*/
nextBy(e) {
const t = this.pages.indexOf(e);
return t < this.pages.length - 1 ? this.pages[t + 1] : null;
}
/**
* Get previous page from specified
*
* @param {Page} current
*/
prevBy(e) {
const t = this.pages.indexOf(e);
return t > 0 ? this.pages[t - 1] : null;
}
/**
* Get flipping page depending on the direction
*
* @param {FlipDirection} direction
*/
getFlippingPage(e) {
const t = this.currentSpreadIndex;
if (this.render.getOrientation() === m.PORTRAIT)
return e === l.FORWARD ? this.pages[t].newTemporaryCopy() : this.pages[t - 1];
{
const i = e === l.FORWARD ? this.getSpread()[t + 1] : this.getSpread()[t - 1];
return i.length === 1 ? this.pages[i[0]] : e === l.FORWARD ? this.pages[i[0]] : this.pages[i[1]];
}
}
/**
* Get Next page at the time of flipping
*
* @param {FlipDirection} direction
*/
getBottomPage(e) {
const t = this.currentSpreadIndex;
if (this.render.getOrientation() === m.PORTRAIT)
return e === l.FORWARD ? this.pages[t + 1] : this.pages[t - 1];
{
const i = e === l.FORWARD ? this.getSpread()[t + 1] : this.getSpread()[t - 1];
return i.length === 1 ? this.pages[i[0]] : e === l.FORWARD ? this.pages[i[1]] : this.pages[i[0]];
}
}
/**
* Show next spread
*/
showNext() {
this.currentSpreadIndex < this.getSpread().length && (this.currentSpreadIndex++, this.showSpread());
}
/**
* Show prev spread
*/
showPrev() {
this.currentSpreadIndex > 0 && (this.currentSpreadIndex--, this.showSpread());
}
/**
* Get the number of the current spread in book
*/
getCurrentPageIndex() {
return this.currentPageIndex;
}
/**
* Show specified page
* @param {number} pageNum - Page index (from 0s)
*/
show(e = null) {
if (e === null && (e = this.currentPageIndex), e < 0 || e >= this.pages.length)
return;
const t = this.getSpreadIndexByPage(e);
t !== null && (this.currentSpreadIndex = t, this.showSpread());
}
/**
* Index of the current page in list
*/
getCurrentSpreadIndex() {
return this.currentSpreadIndex;
}
/**
* Set new spread index as current
*
* @param {number} newIndex - new spread index
*/
setCurrentSpreadIndex(e) {
if (e >= 0 && e < this.getSpread().length)
this.currentSpreadIndex = e;
else
throw new Error("Invalid page");
}
/**
* Show current spread
*/
showSpread() {
const e = this.getSpread()[this.currentSpreadIndex];
e.length === 2 ? (this.render.setLeftPage(this.pages[e[0]]), this.render.setRightPage(this.pages[e[1]])) : this.render.getOrientation() === m.LANDSCAPE ? e[0] === this.pages.length - 1 ? (this.render.setLeftPage(this.pages[e[0]]), this.render.setRightPage(null)) : (this.render.setLeftPage(null), this.render.setRightPage(this.pages[e[0]])) : (this.render.setLeftPage(null), this.render.setRightPage(this.pages[e[0]])), this.currentPageIndex = e[0], this.app.updatePageIndex(this.currentPageIndex);
}
}
class D extends C {
constructor(t, i, s) {
super(t, i);
r(this, "imagesHref");
this.imagesHref = s;
}
load() {
for (const t of this.imagesHref) {
const i = new M(this.render, t, w.SOFT);
i.load(), this.pages.push(i);
}
this.createSpread();
}
}
class R extends v {
constructor(t, i, s) {
super(t, s);
r(this, "element");
r(this, "copiedElement", null);
r(this, "temporaryCopy", null);
r(this, "isLoad", !1);
this.element = i, this.element.classList.add("stf__item"), this.element.classList.add("--" + s);
}
newTemporaryCopy() {
return this.nowDrawingDensity === w.HARD ? this : (this.temporaryCopy === null && (this.copiedElement = this.element.cloneNode(!0), this.element.parentElement.appendChild(this.copiedElement), this.temporaryCopy = new R(
this.render,
this.copiedElement,
this.nowDrawingDensity
)), this.getTemporaryCopy());
}
getTemporaryCopy() {
return this.temporaryCopy;
}
hideTemporaryCopy() {
this.temporaryCopy !== null && (this.copiedElement.remove(), this.copiedElement = null, this.temporaryCopy = null);
}
draw(t) {
const i = t || this.nowDrawingDensity, s = this.render.convertToGlobal(this.state.position), n = this.render.getRect().pageWidth, h = this.render.getRect().height;
this.element.classList.remove("--simple");
const o = `
display: block;
z-index: ${this.element.style.zIndex};
left: 0;
top: 0;
width: ${n}px;
height: ${h}px;
`;
i === w.HARD ? this.drawHard(o) : this.drawSoft(s, o);
}
drawHard(t = "") {
const i = this.render.getRect().left + this.render.getRect().width / 2, s = this.state.hardDrawingAngle, n = t + `
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
clip-path: none;
-webkit-clip-path: none;
` + (this.orientation === u.LEFT ? `transform-origin: ${this.render.getRect().pageWidth}px 0;
transform: translate3d(0, 0, 0) rotateY(${s}deg);` : `transform-origin: 0 0;
transform: translate3d(${i}px, 0, 0) rotateY(${s}deg);`);
this.element.style.cssText = n;
}
drawSoft(t, i = "") {
let s = "polygon( ";
for (const h of this.state.area)
if (h !== null) {
let o = this.render.getDirection() === l.BACK ? {
x: -h.x + this.state.position.x,
y: h.y - this.state.position.y
} : {
x: h.x - this.state.position.x,
y: h.y - this.state.position.y
};
o = d.GetRotatedPoint(o, { x: 0, y: 0 }, this.state.angle), s += o.x + "px " + o.y + "px, ";
}
s = s.slice(0, -2), s += ")";
const n = i + `transform-origin: 0 0; clip-path: ${s}; -webkit-clip-path: ${s};` + (this.render.isSafari() && this.state.angle === 0 ? `transform: translate(${t.x}px, ${t.y}px);` : `transform: translate3d(${t.x}px, ${t.y}px, 0) rotate(${this.state.angle}rad);`);
this.element.style.cssText = n;
}
simpleDraw(t) {
const i = this.render.getRect(), s = i.pageWidth, n = i.height, h = t === u.RIGHT ? i.left + i.pageWidth : i.left, o = i.top;
this.element.classList.add("--simple"), this.element.style.cssText = `
position: absolute;
display: block;
height: ${n}px;
left: ${h}px;
top: ${o}px;
width: ${s}px;
z-index: ${this.render.getSettings().startZIndex + 1};`;
}
getElement() {
return this.element;
}
load() {
this.isLoad = !0, console.log("%c this.isLoad: ", "background-color: pink", this.isLoad);
}
setOrientation(t) {
super.setOrientation(t), this.element.classList.remove("--left", "--right"), this.element.classList.add(
t === u.RIGHT ? "--right" : "--left"
);
}
setDrawingDensity(t) {
this.element.classList.remove("--soft", "--hard"), this.element.classList.add("--" + t), super.setDrawingDensity(t);
}
}
class b extends C {
constructor(t, i, s, n) {
super(t, i);
r(this, "element");
r(this, "pagesElement");
this.element = s, this.pagesElement = n;
}
load() {
for (const t of this.pagesElement) {
const i = new R(
this.render,
t,
t.dataset.density === "hard" ? w.HARD : w.SOFT
);
i.load(), this.pages.push(i);
}
this.createSpread(), console.log("%c element: ", "background-color: pink", this.element);
}
}
class E extends I {
constructor(t, i, s) {
super(t, i);
r(this, "canvas");
r(this, "ctx");
this.canvas = s, this.ctx = s.getContext("2d");
}
getContext() {
return this.ctx;
}
reload() {
}
drawFrame() {
this.clear(), this.orientation !== m.PORTRAIT && this.leftPage != null && this.leftPage.simpleDraw(u.LEFT), this.rightPage != null && this.rightPage.simpleDraw(u.RIGHT), this.bottomPage != null && this.bottomPage.draw(), this.drawBookShadow(), this.flippingPage != null && this.flippingPage.draw(), this.shadow != null && (this.drawOuterShadow(), this.drawInnerShadow());
const t = this.getRect();
this.orientation === m.PORTRAIT && (this.ctx.beginPath(), this.ctx.rect(t.left + t.pageWidth, t.top, t.width, t.height), this.ctx.clip());
}
drawBookShadow() {
const t = this.getRect();
this.ctx.save(), this.ctx.beginPath();
const i = t.width / 20;
this.ctx.rect(t.left, t.top, t.width, t.height);
const s = { x: t.left + t.width / 2 - i / 2, y: 0 };
this.ctx.translate(s.x, s.y);
const n = this.ctx.createLinearGradient(0, 0, i, 0);
n.addColorStop(0, "rgba(0, 0, 0, 0)"), n.addColorStop(0.4, "rgba(0, 0, 0, 0.2)"), n.addColorStop(0.49, "rgba(0, 0, 0, 0.1)"), n.addColorStop(0.5, "rgba(0, 0, 0, 0.5)"), n.addColorStop(0.51, "rgba(0, 0, 0, 0.4)"), n.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.clip(), this.ctx.fillStyle = n, this.ctx.fillRect(0, 0, i, t.height * 2), this.ctx.restore();
}
drawOuterShadow() {
const t = this.getRect();
this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(t.left, t.top, t.width, t.height);
const i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y });
this.ctx.translate(i.x, i.y), this.ctx.rotate(Math.PI + this.shadow.angle + Math.PI / 2);
const s = this.ctx.createLinearGradient(0, 0, this.shadow.width, 0);
this.shadow.direction === l.FORWARD ? (this.ctx.translate(0, -100), s.addColorStop(0, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), s.addColorStop(1, "rgba(0, 0, 0, 0)")) : (this.ctx.translate(-this.shadow.width, -100), s.addColorStop(0, "rgba(0, 0, 0, 0)"), s.addColorStop(1, "rgba(0, 0, 0, " + this.shadow.opacity + ")")), this.ctx.clip(), this.ctx.fillStyle = s, this.ctx.fillRect(0, 0, this.shadow.width, t.height * 2), this.ctx.restore();
}
drawInnerShadow() {
const t = this.getRect();
this.ctx.save(), this.ctx.beginPath();
const i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y }), s = this.convertRectToGlobal(this.pageRect);
this.ctx.moveTo(s.topLeft.x, s.topLeft.y), this.ctx.lineTo(s.topRight.x, s.topRight.y), this.ctx.lineTo(s.bottomRight.x, s.bottomRight.y), this.ctx.lineTo(s.bottomLeft.x, s.bottomLeft.y), this.ctx.translate(i.x, i.y), this.ctx.rotate(Math.PI + this.shadow.angle + Math.PI / 2);
const n = this.shadow.width * 3 / 4, h = this.ctx.createLinearGradient(0, 0, n, 0);
this.shadow.direction === l.FORWARD ? (this.ctx.translate(-n, -100), h.addColorStop(1, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0.9, "rgba(0, 0, 0, 0.05)"), h.addColorStop(0.7, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0, "rgba(0, 0, 0, 0)")) : (this.ctx.translate(0, -100), h.addColorStop(0, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(0.1, "rgba(0, 0, 0, 0.05)"), h.addColorStop(0.3, "rgba(0, 0, 0, " + this.shadow.opacity + ")"), h.addColorStop(1, "rgba(0, 0, 0, 0)")), this.ctx.clip(), this.ctx.fillStyle = h, this.ctx.fillRect(0, 0, n, t.height * 2), this.ctx.restore();
}
clear() {
this.ctx.fillStyle = "white", this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
}
class A {
/**
* @constructor
*
* @param {HTMLElement} inBlock - Root HTML Element
* @param {PageFlip} app - PageFlip instanse
* @param {FlipSetting} setting - Configuration object
*/
constructor(e, t, i) {
r(this, "parentElement");
r(this, "app");
r(this, "wrapper");
r(this, "distElement");
r(this, "touchPoint", null);
r(this, "swipeTimeout", 250);
r(this, "swipeDistance");
r(this, "onResize", () => {
this.update();
});
r(this, "onMouseDown", (e) => {
if (this.checkTarget(e.target)) {
const t = this.getMousePos(e.clientX, e.clientY);
this.app.startUserTouch(t), e.preventDefault();
}
});
r(this, "onTouchStart", (e) => {
if (this.checkTarget(e.target) && e.changedTouches.length > 0) {
const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
this.touchPoint = {
point: i,
time: Date.now()
}, setTimeout(() => {
this.touchPoint !== null && this.app.startUserTouch(i);
}, this.swipeTimeout), this.app.getSettings().mobileScrollSupport || e.preventDefault();
}
});
r(this, "onMouseUp", (e) => {
const t = this.getMousePos(e.clientX, e.clientY);
this.app.userStop(t);
});
r(this, "onMouseMove", (e) => {
const t = this.getMousePos(e.clientX, e.clientY);
this.app.userMove(t, !1);
});
r(this, "onTouchMove", (e) => {
if (e.changedTouches.length > 0) {
const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
this.app.getSettings().mobileScrollSupport ? (this.touchPoint !== null && (Math.abs(this.touchPoint.point.x - i.x) > 10 || this.app.getState() !== P.READ) && e.cancelable && this.app.userMove(i, !0), this.app.getState() !== P.READ && e.preventDefault()) : this.app.userMove(i, !0);
}
});
r(this, "onTouchEnd", (e) => {
if (e.changedTouches.length > 0) {
const t = e.changedTouches[0], i = this.getMousePos(t.clientX, t.clientY);
let s = !1;
if (this.touchPoint !== null) {
const n = i.x - this.touchPoint.point.x, h = Math.abs(i.y - this.touchPoint.point.y);
Math.abs(n) > this.swipeDistance && h < this.swipeDistance * 2 && Date.now() - this.touchPoint.time < this.swipeTimeout && (n > 0 ? this.app.flipPrev(
this.touchPoint.point.y < this.app.getRender().getRect().height / 2 ? p.TOP : p.BOTTOM
) : this.app.flipNext(
this.touchPoint.point.y < this.app.getRender().getRect().height / 2 ? p.TOP : p.BOTTOM
), s = !0), this.touchPoint = null;
}
this.app.userStop(i, s);
}
});
this.parentElement = e, e.classList.add("stf__parent"), e.insertAdjacentHTML(
"afterbegin",
'<div class="stf__wrapper"></div>'
), this.wrapper = e.querySelector(".stf__wrapper"), this.app = t;
const s = this.app.getSettings().usePortrait ? 1 : 2;
e.style.minWidth = i.minWidth * s + "px", e.style.minHeight = i.minHeight + "px", i.size === S.FIXED && (e.style.minWidth = i.width * s + "px", e.style.minHeight = i.height + "px"), i.autoSize && (e.style.width = "100%", e.style.maxWidth = i.maxWidth * 2 + "px"), e.style.display = "block", window.addEventListener("resize", this.onResize, !1), this.swipeDistance = i.swipeDistance;
}
/**
* Destructor. Remove all HTML elements and all event handlers
*/
destroy() {
this.app.getSettings().useMouseEvents && this.removeHandlers(), this.distElement.remove(), this.wrapper.remove();
}
/**
* Get parent element for book
*
* @returns {HTMLElement}
*/
getDistElement() {
return this.distElement;
}
/**
* Get wrapper element
*
* @returns {HTMLElement}
*/
getWrapper() {
return this.wrapper;
}
/**
* Updates styles and sizes based on book orientation
*
* @param {Orientation} orientation - New book orientation
*/
setOrientationStyle(e) {
this.wrapper.classList.remove("--portrait", "--landscape"), e === m.PORTRAIT ? (this.app.getSettings().autoSize && (this.wrapper.style.paddingBottom = this.app.getSettings().height / this.app.getSettings().width * 100 + "%"), this.wrapper.classList.add("--portrait")) : (this.app.getSettings().autoSize && (this.wrapper.style.paddingBottom = this.app.getSettings().height / (this.app.getSettings().width * 2) * 100 + "%"), this.wrapper.classList.add("--landscape")), this.update();
}
removeHandlers() {
window.removeEventListener("resize", this.onResize), this.distElement.removeEventListener("mousedown", this.onMouseDown), this.distElement.removeEventListener("touchstart", this.onTouchStart), window.removeEventListener("mousemove", this.onMouseMove), window.removeEventListener("touchmove", this.onTouchMove), window.removeEventListener("mouseup", this.onMouseUp), window.removeEventListener("touchend", this.onTouchEnd);
}
setHandlers() {
window.addEventListener("resize", this.onResize, !1), this.app.getSettings().useMouseEvents && (this.distElement.addEventListener("mousedown", this.onMouseDown), this.distElement.addEventListener("touchstart", this.onTouchStart), window.addEventListener("mousemove", this.onMouseMove), window.addEventListener("touchmove", this.onTouchMove, {
passive: !this.app.getSettings().mobileScrollSupport
}), window.addEventListener("mouseup", this.onMouseUp), window.addEventListener("touchend", this.onTouchEnd));
}
/**
* Convert global coordinates to relative book coordinates
*
* @param x
* @param y
*/
getMousePos(e, t) {
const i = this.distElement.getBoundingClientRect();
return {
x: e - i.left,
y: t - i.top
};
}
checkTarget(e) {
return this.app.getSettings().clickEventForward ? !["a", "button"].includes(e.tagName.toLowerCase()) : !0;
}
}
class B extends A {
constructor(t, i, s, n) {
super(t, i, s);
r(this, "items");
this.wrapper.insertAdjacentHTML(
"afterbegin",
'<div class="stf__block"></div>'
), this.distElement = t.querySelector(".stf__block"), this.items = n;
for (const h of n)
this.distElement.appendChild(h);
this.setHandlers();
}
clear() {
for (const t of this.items)
this.parentElement.appendChild(t);
}
/**
* Update page list from HTMLElements
*
* @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
*/
updateItems(t) {
this.removeHandlers(), this.distElement.innerHTML = "";
for (const i of t)
this.distElement.appendChild(i);
this.items = t, this.setHandlers();
}
update() {
this.app.getRender().update();
}
}
class F extends A {
constructor(t, i, s) {
super(t, i, s);
r(this, "canvas");
this.wrapper.innerHTML = '<canvas class="stf__canvas"></canvas>', this.canvas = t.querySelectorAll("canvas")[0], this.distElement = this.canvas, this.resizeCanvas(), this.setHandlers();
}
resizeCanvas() {
const t = getComputedStyle(this.canvas), i = parseInt(t.getPropertyValue("width"), 10), s = parseInt(t.getPropertyValue("height"), 10);
this.canvas.width = i, this.canvas.height = s;
}
/**
* Get canvas element
*/
getCanvas() {
return this.canvas;
}
update() {
this.resizeCanvas(), this.app.getRender().update();
}
}
class G {
constructor() {
r(this, "events", /* @__PURE__ */ new Map());
}
/**
* Add new event handler
*
* @param {string} eventName
* @param {EventCallback} callback
*/
on(e, t) {
return this.events.has(e) ? this.events.get(e).push(t) : this.events.set(e, [t]), this;
}
/**
* Removing all handlers from an event
*
* @param {string} event - Event name
*/
off(e) {
this.events.delete(e);
}
trigger(e, t, i = null) {
if (this.events.has(e))
for (const s of this.events.get(e))
s({ data: i, object: t });
}
}
class k extends I {
/**
* @constructor
*
* @param {PageFlip} app - PageFlip object
* @param {FlipSetting} setting - Configuration object
* @param {HTMLElement} element - Parent HTML Element
*/
constructor(t, i, s) {
super(t, i);
/** Parent HTML Element */
r(this, "element");
/** Pages List as HTMLElements */
// private readonly items: NodeListOf<HTMLElement> | HTMLElement[];
r(this, "outerShadow", null);
r(this, "innerShadow", null);
r(this, "hardShadow", null);
r(this, "hardInnerShadow", null);
this.element = s, this.createShadows();
}
createShadows() {
this.element.insertAdjacentHTML(
"beforeend",
`<div class="stf__outerShadow"></div>
<div class="stf__innerShadow"></div>
<div class="stf__hardShadow"></div>
<div class="stf__hardInnerShadow"></div>`
), this.outerShadow = this.element.querySelector(".stf__outerShadow"), this.innerShadow = this.element.querySelector(".stf__innerShadow"), this.hardShadow = this.element.querySelector(".stf__hardShadow"), this.hardInnerShadow = this.element.querySelector(".stf__hardInnerShadow");
}
clearShadow() {
super.clearShadow(), this.outerShadow.style.cssText = "display: none", this.innerShadow.style.cssText = "display: none", this.hardShadow.style.cssText = "display: none", this.hardInnerShadow.style.cssText = "display: none";
}
reload() {
this.element.querySelector(".stf__outerShadow") || this.createShadows();
}
/**
* Draw inner shadow to the hard page
*/
drawHardInnerShadow() {
const t = this.getRect(), i = this.shadow.progress > 100 ? 200 - this.shadow.progress : this.shadow.progress;
let s = (100 - i) * (2.5 * t.pageWidth) / 100 + 20;
s > t.pageWidth && (s = t.pageWidth);
let n = `
display: block;
z-index: ${(this.getSettings().startZIndex + 5).toString(10)};
width: ${s}px;
height: ${t.height}px;
background: linear-gradient(to right,
rgba(0, 0, 0, ${this.shadow.opacity * i / 100}) 5%,
rgba(0, 0, 0, 0) 100%);
left: ${t.left + t.width / 2}px;
transform-origin: 0 0;
`;
n += this.getDirection() === l.FORWARD && this.shadow.progress > 100 || this.getDirection() === l.BACK && this.shadow.progress <= 100 ? "transform: translate3d(0, 0, 0);" : "transform: translate3d(0, 0, 0) rotateY(180deg);", this.hardInnerShadow.style.cssText = n;
}
/**
* Draw outer shadow to the hard page
*/
drawHardOuterShadow() {
const t = this.getRect();
let s = (100 - (this.shadow.progress > 100 ? 200 - this.shadow.progress : this.shadow.progress)) * (2.5 * t.pageWidth) / 100 + 20;
s > t.pageWidth && (s = t.pageWidth);
let n = `
display: block;
z-index: ${(this.getSettings().startZIndex + 4).toString(10)};
width: ${s}px;
height: ${t.height}px;
background: linear-gradient(to left, rgba(0, 0, 0, ${this.shadow.opacity}) 5%, rgba(0, 0, 0, 0) 100%);
left: ${t.left + t.width / 2}px;
transform-origin: 0 0;
`;
n += this.getDirection() === l.FORWARD && this.shadow.progress > 100 || this.getDirection() === l.BACK && this.shadow.progress <= 100 ? "transform: translate3d(0, 0, 0) rotateY(180deg);" : "transform: translate3d(0, 0, 0);", this.hardShadow.style.cssText = n;
}
/**
* Draw inner shadow to the soft page
*/
drawInnerShadow() {
const t = this.getRect(), i = this.shadow.width * 3 / 4, s = this.getDirection() === l.FORWARD ? i : 0, n = this.getDirection() === l.FORWARD ? "to left" : "to right", h = this.convertToGlobal(this.shadow.pos), o = this.shadow.angle + 3 * Math.PI / 2, g = [
this.pageRect.topLeft,
this.pageRect.topRight,
this.pageRect.bottomRight,
this.pageRect.bottomLeft
];
let c = "polygon( ";
for (const f of g) {
let y = this.getDirection() === l.BACK ? {
x: -f.x + this.shadow.pos.x,
y: f.y - this.shadow.pos.y
} : {
x: f.x - this.shadow.pos.x,
y: f.y - this.shadow.pos.y
};
y = d.GetRotatedPoint(y, { x: s, y: 100 }, o), c += y.x + "px " + y.y + "px, ";
}
c = c.slice(0, -2), c += ")";
const x = `
display: block;
z-index: ${(this.getSettings().startZIndex + 10).toString(10)};
width: ${i}px;
height: ${t.height * 2}px;
background: linear-gradient(${n},
rgba(0, 0, 0, ${this.shadow.opacity}) 5%,
rgba(0, 0, 0, 0.05) 15%,
rgba(0, 0, 0, ${this.shadow.opacity}) 35%,
rgba(0, 0, 0, 0) 100%);
transform-origin: ${s}px 100px;
transform: translate3d(${h.x - s}px, ${h.y - 100}px, 0) rotate(${o}rad);
clip-path: ${c};
-webkit-clip-path: ${c};
`;
this.innerShadow.style.cssText = x;
}
/**
* Draw outer shadow to the soft page
*/
drawOuterShadow() {
const t = this.getRect(), i = this.convertToGlobal({ x: this.shadow.pos.x, y: this.shadow.pos.y }), s = this.shadow.angle + 3 * Math.PI / 2, n = this.getDirection() === l.BACK ? this.shadow.width : 0, h = this.getDirection() === l.FORWARD ? "to right" : "to left", o = [
{ x: 0, y: 0 },
{ x: t.pageWidth, y: 0 },
{ x: t.pageWidth, y: t.height },
{ x: 0, y: t.height }
];
let g = "polygon( ";
for (const x of o)
if (x !== null) {
let f = this.getDirection() === l.BACK ? {
x: -x.x + this.shadow.pos.x,
y: x.y - this.shadow.pos.y
} : {
x: x.x - this.shadow.pos.x,
y: x.y - this.shadow.pos.y
};
f = d.GetRotatedPoint(f, { x: n, y: 100 }, s), g += f.x + "px " + f.y + "px, ";
}
g = g.slice(0, -2), g += ")";
const c = `
display: block;
z-index: ${(this.getSettings().startZIndex + 10).toString(10)};
width: ${this.shadow.width}px;
height: ${t.height * 2}px;
background: linear-gradient(${h}, rgba(0, 0, 0, ${this.shadow.opacity}), rgba(0, 0, 0, 0));
transform-origin: ${n}px 100px;
transform: translate3d(${i.x - n}px, ${i.y - 100}px, 0) rotate(${s}rad);
clip-path: ${g};
-webkit-clip-path: ${g};
`;
this.outerShadow.style.cssText = c;
}
/**
* Draw left static page
*/
drawLeftPage() {
this.orientation === m.PORTRAIT || this.leftPage === null || (this.direction === l.BACK && this.flippingPage !== null && this.flippingPage.getDrawingDensity() === w.HARD ? (this.leftPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.leftPage.setHardDrawingAngle(180 + this.flippingPage.getHardAngle()), this.leftPage.draw(this.flippingPage.getDrawingDensity())) : this.leftPage.simpleDraw(u.LEFT));
}
/**
* Draw right static page
*/
drawRightPage() {
this.rightPage !== null && (this.direction === l.FORWARD && this.flippingPage !== null && this.flippingPage.getDrawingDensity() === w.HARD ? (this.rightPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.rightPage.setHardDrawingAngle(180 + this.flippingPage.getHardAngle()), this.rightPage.draw(this.flippingPage.getDrawingDensity())) : this.rightPage.simpleDraw(u.RIGHT));
}
/**
* Draw the next page at the time of flipping
*/
drawBottomPage() {
if (this.bottomPage === null)
return;
const t = this.flippingPage != null ? this.flippingPage.getDrawingDensity() : null;
this.orientation === m.PORTRAIT && this.direction === l.BACK || (this.bottomPage.getElement().style.zIndex = (this.getSettings().startZIndex + 3).toString(10), this.bottomPage.draw(t));
}
drawFrame() {
this.clear(), this.drawLeftPage(), this.drawRightPage(), this.drawBottomPage(), this.flippingPage != null && (this.flippingPage.getElement().style.zIndex = (this.getSettings().startZIndex + 5).toString(10), this.flippingPage.draw()), this.shadow != null && this.flippingPage !== null && (this.flippingPage.getDrawingDensity() === w.SOFT ? (this.drawOuterShadow(), this.drawInnerShadow()) : (this.drawHardOuterShadow(), this.drawHardInnerShadow()));
}
clear() {
for (const t of this.app.getPageCollection().getPages())
t !== this.leftPage && t !== this.rightPage && t !== this.flippingPage && t !== this.bottomPage && (t.getElement().style.cssText = "display: none"), t.getTemporaryCopy() !== this.flippingPage && t.hideTemporaryCopy();
}
update() {
super.update(), this.rightPage !== null && this.rightPage.setOrientation(u.RIGHT), this.leftPage !== null && this.leftPage.setOrientation(u.LEFT);
}
}
class z extends G {
/**
* Create a new PageFlip instance
*
* @constructor
* @param {HTMLElement} inBlock - Root HTML Element
* @param {Object} setting - Configuration object
*/
constructor(t, i) {
super();
r(this, "mousePosition");
r(this, "isUserTouch", !1);
r(this, "isUserMove", !1);
r(this, "setting", null);
r(this, "block");
// Root HTML Element
r(this, "pages", null);
r(this, "flipController");
r(this, "render");
r(this, "ui");
this.setting = new H().getSettings(i), this.block = t;
}
/**
* Destructor. Remove a root HTML element and all event handlers
*/
destroy() {
this.ui.destroy(), this.block.remove();
}
/**
* Update the render area. Re-show current page.
*/
update() {
this.render.update(), this.pages.show();
}
/**
* Load pages from images on the Canvas mode
*
* @param {string[]} imagesHref - List of paths to images
*/
loadFromImages(t) {
this.ui = new F(this.block, this, this.setting);
const i = this.ui.getCanvas();
this.render = new E(this, this.setting, i), this.flipController = new T(this.render, this), this.pages = new D(this, this.render, t), this.pages.load(), this.render.start(), this.pages.show(this.setting.startPage), setTimeout(() => {
this.ui.update(), this.trigger("init", this, {
page: this.setting.startPage,
mode: this.render.getOrientation()
});
}, 1);
}
/**
* Load pages from HTML elements on the HTML mode
*
* @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
*/
loadFromHTML(t) {
this.ui = new B(this.block, this, this.setting, t), this.render = new k(this, this.setting, this.ui.getDistElement()), this.flipController = new T(this.render, this), this.pages = new b(
this,
this.render,
this.ui.getDistElement(),
t
), this.pages.load(), this.render.start(), this.pages.show(this.setting.startPage), setTimeout(() => {
this.ui.update(), this.trigger("init", this, {
page: this.setting.startPage,
mode: this.render.getOrientation()
});
}, 1);
}
/**
* Update current pages from images
*
* @param {string[]} imagesHref - List of paths to images
*/
updateFromImages(t) {
const i = this.pages.getCurrentPageIndex();
this.pages.destroy(), this.pages = new D(this, this.render, t), this.pages.load(), this.pages.show(i), this.trigger("update", this, {
page: i,
mode: this.render.getOrientation()
});
}
/**
* Update current pages from HTML
*
* @param {(NodeListOf<HTMLElement>|HTMLElement[])} items - List of pages as HTML Element
*/
updateFromHtml(t) {
const i = this.pages.getCurrentPageIndex();
this.pages.destroy(), this.pages = new b(
this,
this.render,
this.ui.getDistElement(),
t
), this.pages.load(), this.ui.updateItems(t), this.render.reload(), this.pages.show(i), this.trigger("update", this, {
page: i,
mode: this.render.getOrientation()
});
}
/**
* Clear pages from HTML (remove to initinalState)
*/
clear() {
this.pages.destroy(), this.ui.clear();
}
/**
* Turn to the previous page (without animation)
*/
turnToPrevPage() {
this.pages.showPrev();
}
/**
* Turn to the next page (without animation)
*/
turnToNextPage() {
this.pages.showNext();
}
/**
* Turn to the specified page number (without animation)
*
* @param {number} page - New page number
*/
turnToPage(t) {
this.pages.show(t);
}
/**
* Turn to the next page (with animation)
*
* @param {FlipCorner} corner - Active page corner when turning
*/
flipNext(t = p.TOP) {
this.flipController.flipNext(t);
}
/**
* Turn to the prev page (with animation)
*
* @param {FlipCorner} corner - Active page corner when turning
*/
flipPrev(t = p.TOP) {
this.flipController.flipPrev(t);
}
/**
* Turn to the specified page number (with animation)
*
* @param {number} page - New page number
* @param {FlipCorner} corner - Active page corner when turning
*/
flip(t, i = p.TOP) {
this.flipController.flipToPage(t, i);
}
/**
* Call a state change event trigger
*
* @param {FlippingState} newState - New state of the object
*/
updateState(t) {
this.trigger("changeState", this, t);
}
/**
* Call a page number change event trigger
*
* @param {number} newPage - New page Number
*/
updatePageIndex(t) {
this.trigger("flip", this, t);
}
/**
* Call a page orientation change event trigger. Update UI and rendering area
*
* @param {Orientation} newOrientation - New page orientation (portrait, landscape)
*/
updateOrientation(t) {
this.ui.setOrientationStyle(t), this.update(), this.trigger("changeOrientation", this, t);
}
/**
* Get the total number of pages in a book
*
* @returns {number}
*/
getPageCount() {
return this.pages.getPageCount();
}
/**
* Get the index of the current page in the page list (starts at 0)
*
* @returns {number}
*/
getCurrentPageIndex() {
return this.pages.getCurrentPageIndex();
}
/**
* Get page from collection by number
*
* @param {number} pageIndex
* @returns {Page}
*/
getPage(t) {
return this.pages.getPage(t);
}
/**
* Get the current rendering object
*
* @returns {Render}
*/
getRender() {
return this.render;
}
/**
* Get current object responsible for flipping
*
* @returns {Flip}
*/
getFlipController() {
return this.flipController;
}
/**
* Get current page orientation
*
* @returns {Orientation} Сurrent orientation: portrait or landscape
*/
getOrientation() {
return this.render.getOrientation();
}
/**
* Get current book sizes and position
*
* @returns {PageRect}
*/
getBoundsRect() {
return this.render.getRect();
}
/**
* Get configuration object
*
* @returns {FlipSetting}
*/
getSettings() {
return this.setting;
}
/**
* Get UI object
*
* @returns {UI}
*/
getUI() {
return this.ui;
}
/**
* Get current flipping state
*
* @returns {FlippingState}
*/
getState() {
return this.flipController.getState();
}
/**
* Get page collection
*
* @returns {PageCollection}
*/
getPageCollection() {
return this.pages;
}
/**
* Start page turning. Called when a user clicks or touches
*
* @param {Point} pos - Touch position in coordinates relative to the book
*/
startUserTouch(t) {
this.mousePosition = t, this.isUserTouch = !0, this.isUserMove = !1;
}
/**
* Called when a finger / mouse moves
*
* @param {Point} pos - Touch position in coordinates relative to the book
* @param {boolean} isTouch - True if there was a touch event, not a mouse click
*/
userMove(t, i) {
!this.isUserTouch && !i && this.setting.showPageCorners ? this.flipController.showCorner(t) : this.isUserTouch && d.GetDistanceBetweenTwoPoint(this.mousePosition, t) > 5 && (this.isUserMove = !0, this.flipController.fold(t));
}
/**
* Сalled when the user has stopped touching
*
* @param {Point} pos - Touch end position in coordinates relative to the book
* @param {boolean} isSwipe - true if there was a mobile swipe event
*/
userStop(t, i = !1) {
this.isUserTouch && (this.isUserTouch = !1, i || (this.isUserMove ? this.flipController.stopMove() : this.flipController.flip(t)));
}
}
export {
z as PageFlip
};