提交 7b325fcf authored 作者: 搞事情's avatar 搞事情

1、修复快速来回翻页CSS动画一直播放的问题

2、load状态导致vue响应问题
上级 6265f8f0
......@@ -4,9 +4,6 @@
<!-- <flip-book /> -->
</div>
</template>
<script setup>
import FlipBook from "@/components/FlipBook/index.vue";
</script>
<style>
* {
......
......@@ -14,8 +14,6 @@ declare module 'vue' {
ElCol: typeof import('element-plus/es')['ElCol']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElRow: typeof import('element-plus/es')['ElRow']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
FileUpload: typeof import('./components/FileUpload.vue')['default']
......@@ -30,9 +28,7 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SvgIcon: typeof import('./components/SvgIcon/index.vue')['default']
Test: typeof import('./components/Test/index.vue')['default']
VanCell: typeof import('vant/es')['Cell']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanNavBar: typeof import('vant/es')['NavBar']
VanPopup: typeof import('vant/es')['Popup']
......
......@@ -3,7 +3,8 @@
class="book-reader"
@touchstart="handleTouchStart"
@touchend="handleTouchEnd"
v-loading="loading"
v-loading="loading && initialLoading"
element-loading-text="正在加载图书..."
>
<div class="magazine-viewport">
<div ref="magazine" class="magazine">
......@@ -55,14 +56,14 @@
</div>
<!-- <div
class="left-button mobile-page-button"
@click="previous"
@click="previousPage"
v-if="isMobile"
>
<van-icon name="arrow-left" />
</div>
<div
class="right-button mobile-page-button"
@click="next"
@click="nextPage"
v-if="isMobile"
>
<van-icon name="arrow" />
......@@ -135,11 +136,11 @@
<svg-icon name="to-first" size="30" @click="toFirst"></svg-icon>
</el-tooltip>
<el-tooltip content="跳转上一页" placement="top" effect="dark">
<svg-icon name="to-left" size="22" @click="previous"></svg-icon>
<svg-icon name="to-left" size="22" @click="previousPage"></svg-icon>
</el-tooltip>
<div class="page-count" v-if="!isMobile">{{ currentPage }}</div>
<el-tooltip content="跳转下一页" placement="top" effect="dark">
<svg-icon name="to-right" size="22" @click="next"></svg-icon>
<svg-icon name="to-right" size="22" @click="nextPage"></svg-icon>
</el-tooltip>
<el-tooltip content="跳转到最后一页" placement="top" effect="dark">
<svg-icon name="to-end" size="30" @click="toEnd"></svg-icon>
......@@ -162,7 +163,6 @@ import VueEasyLightbox from "vue-easy-lightbox";
import GuideMobile from "../GuideMobile/index.vue";
import audioFlip from "@/assets/audio/flip.mp3";
import throttle from "lodash/throttle";
import debounce from "lodash/debounce";
const props = defineProps({
pages: {
type: Array,
......@@ -189,6 +189,10 @@ const isMobile = ref(false);
const touchStartX = ref(0);
const touchStartY = ref(0);
// 简化状态管理,只保留必要的状态
const preloadingPages = ref(new Set()); // 正在预加载的页面集合
const initialLoading = ref(true); // 初始加载状态
// 修改预览相关的状态
const showViewer = ref(false);
const currentImageIndex = ref(0);
......@@ -232,9 +236,9 @@ const handleTouchEnd = throttle((e) => {
// 如果水平滑动距离大于垂直滑动距离,且大于50px,则触发翻页
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 50) {
if (deltaX > 0) {
previous();
previousPage();
} else {
next();
nextPage();
}
}
});
......@@ -254,7 +258,9 @@ const processPages = (pages) => {
const loadImage = async (pageIndex) => {
const page = processedPages.value[pageIndex];
if (!page || page.isLoaded) return true;
if (!page || page.isLoaded || preloadingPages.value.has(pageIndex)) {
return true;
}
const src = page.url;
if (imageCache.value.has(src)) {
......@@ -268,9 +274,12 @@ const loadImage = async (pageIndex) => {
return loadImage(pageIndex);
}
preloadingPages.value.add(pageIndex); // 标记正在预加载
loadingQueue.value.add(pageIndex);
const timeoutId = setTimeout(() => {
loadingQueue.value.delete(pageIndex);
preloadingPages.value.delete(pageIndex);
loadingTimeouts.value.delete(pageIndex);
}, 5000);
loadingTimeouts.value.set(pageIndex, timeoutId);
......@@ -309,41 +318,40 @@ const loadImage = async (pageIndex) => {
return false;
} finally {
loadingQueue.value.delete(pageIndex);
preloadingPages.value.delete(pageIndex); // 清除预加载标记
}
};
// 修改加载可见页面的函数
const loadVisiblePages = async (currentPage) => {
// 修改加载可见页面的函数,完全移除loading状态管理
const loadVisiblePages = async (currentPageNum) => {
if (!magazine.value) return;
const $magazine = $(magazine.value);
const totalPages = $magazine.turn("pages");
// 加载当前页、上一页、下一页和下下页
const startPage = Math.max(1, currentPage - 2);
const endPage = Math.min(totalPages, currentPage + 2);
const highPriority = [currentPage, currentPage + 1]; // 优先加载当前和下一页
// const loadTasks = [];
// for (let i = startPage; i <= endPage; i++) {
// const pageIndex = i - 1;
// if (
// pageIndex >= 0 &&
// pageIndex < processedPages.value.length &&
// !processedPages.value[pageIndex].isLoaded
// ) {
// loadTasks.push(loadImage(pageIndex));
// }
// }
// 加载当前页、上一页、下一页
const startPage = Math.max(1, currentPageNum - 1);
const endPage = Math.min(totalPages, currentPageNum + 1);
const highPriority = [currentPageNum, currentPageNum + 1]; // 优先加载当前和下一页
console.log(`预加载页面: ${currentPageNum}, 范围: ${startPage}-${endPage}`);
try {
loading.value = true;
await Promise.all(highPriority.map(loadImage));
// 静默加载,不显示loading状态
await Promise.allSettled(
highPriority.map((pageIndex) => loadImage(pageIndex - 1))
);
// 后台加载其他页面,不阻塞UI
Promise.allSettled(
Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i)
.filter((page) => !highPriority.includes(page))
.map((pageIndex) => loadImage(pageIndex - 1))
);
} catch (error) {
console.error("加载页面失败:", error);
} finally {
loading.value = false;
}
// 完全移除finally块中的loading状态管理
};
// 修改初始化函数
......@@ -413,7 +421,7 @@ const initBook = async () => {
width: isMobile.value ? pageWidth : pageWidth * 2,
height: pageHeight,
display: isMobile.value ? "single" : "double",
acceleration: false,
acceleration: true,
gradients: true,
elevation: 80,
duration: 800,
......@@ -421,28 +429,32 @@ const initBook = async () => {
turnCorners: "bl,br",
page: 1,
when: {
turning: async (event, page) => {
await loadVisiblePages(page);
// 确保加载完成后才继续翻页
setTimeout(() => {
event.preventDefault();
$magazine.turn("page", page);
}, 100);
turning: (event, page) => {
// 不阻塞翻页动画,只更新当前页码
currentPage.value = page;
},
turned: async (event, page) => {
currentPage.value = page; // 更新当前页码
await loadVisiblePages(page);
loading.value = false;
// 添加这行 - 在手动翻页时播放声音
turned: (event, page) => {
currentPage.value = page;
// 翻页完成后异步预加载,不影响动画,不设置翻页锁
setTimeout(() => {
loadVisiblePages(page);
}, 50);
// 播放声音
playPageTurnSound().catch(() => {});
},
},
});
isInitialized.value = true;
// 初始化完成后关闭loading
loading.value = false;
initialLoading.value = false;
await loadVisiblePages(1);
} catch (error) {
console.error("Turn.js initialization error:", error);
loading.value = false;
initialLoading.value = false;
}
};
// 修改加载图片函数
......@@ -517,37 +529,20 @@ const handleImageError = async (index) => {
}
};
const next = throttle(() => {
if (magazine.value && isInitialized.value && !loading.value) {
// 移除节流限制,恢复正常翻页速度
const nextPage = () => {
if (magazine.value && isInitialized.value) {
const $magazine = $(magazine.value);
const currentPage = $magazine.turn("page");
const nextPage = currentPage + 1;
// 预加载下一页
loadVisiblePages(nextPage);
// 延迟执行翻页,确保图片已加载
setTimeout(() => {
$magazine.turn("next", { duration: 1500 });
}, 100);
$magazine.turn("next");
}
});
};
const previous = throttle(() => {
if (magazine.value && isInitialized.value && !loading.value) {
const previousPage = () => {
if (magazine.value && isInitialized.value) {
const $magazine = $(magazine.value);
const currentPage = $magazine.turn("page");
const prevPage = currentPage - 1;
// 预加载上一页
loadVisiblePages(prevPage);
// 延迟执行翻页,确保图片已加载
setTimeout(() => {
$magazine.turn("previous", { duration: 1500 });
}, 100);
$magazine.turn("previous");
}
});
};
const toFirst = () => {
const firstPage = props.pages[0].page_num;
......@@ -636,10 +631,10 @@ const updateZoom = () => {
const handleKeyDown = (e) => {
switch (e.key) {
case "ArrowRight":
next();
nextPage();
break;
case "ArrowLeft":
previous();
previousPage();
break;
case "Escape":
showExitMessage.value = true;
......@@ -775,8 +770,14 @@ onUnmounted(() => {
// 清除所有超时
loadingTimeouts.value.forEach((timeoutId) => clearTimeout(timeoutId));
loadingTimeouts.value.clear();
// 清除所有状态
imageCache.value.clear();
loadingQueue.value.clear();
preloadingPages.value.clear();
// 重置状态
initialLoading.value = true;
if (imageObserver.value) {
imageObserver.value.disconnect();
......@@ -784,6 +785,11 @@ onUnmounted(() => {
destroyTurn();
window.removeEventListener("keydown", handleKeyDown);
window.removeEventListener("resize", handleResize);
// 清理resize监听器
if (typeof window !== "undefined" && window.removeEventListener) {
clearTimeout(resizeTimeout);
}
});
// 修改小图点击事件处理函数
......
<template>
<div class="back"></div>
<div id="canvas">
<div class="previousPage" @click="previousPage"></div>
<div class="nextPage" @click="nextPage"></div>
<div class="magazine-viewport">
<div class="container">
<div class="magazine"></div>
</div>
</div>
</div>
</template>
<script>
import { onMounted, ref, onBeforeUnmount } from "vue";
// import $ from "jquery";
import { isChrome, addPage, disableControls } from "./magazine";
// import "/js/modernizr.2.5.3.min.js";
// import "/js/hash.js";
// import "/js/turn.js";
// import "/js/turn.html4.min.js";
// import "/js/zoom.min.js";
// import "/js/magazine.js";
const $ = window.$;
export default {
name: "Flipbook",
setup() {
const magazine = ref(null);
// Initialize the flipbook once the component is mounted
onMounted(() => {
setTimeout(() => {
loadApp();
}, 1000);
});
// Clean up on component unmount
onBeforeUnmount(() => {
if (magazine.value) {
$(magazine.value).turn("destroy");
}
});
const nextPage = () => {
$(magazine.value).turn("next");
};
const previousPage = () => {
$(magazine.value).turn("previous");
};
// Function to load the flipbook app
function loadApp() {
debugger;
$("#canvas").fadeIn(1000);
const flipbook = $(".magazine");
if (flipbook.width() === 0 || flipbook.height() === 0) {
setTimeout(loadApp, 10);
return;
}
console.log(window.screen.width);
console.log(window.screen.height);
let w, h;
if (window.screen.width > window.screen.height) {
w = $(".magazine-viewport").parent().width();
h = $(window).height();
if (w === 0) {
w = ((2482 * 2) / 3368) * h;
}
const w1 = ((2482 * 2) / 3368) * h;
const h1 = (3368 / (2482 * 2)) * w;
if (w1 > w) {
h = h1;
} else {
w = w1;
}
$(".magazine-viewport").width(w).height(h);
$(".magazine").width(w).height(h);
$(window).resize(() => {
let w = $(".magazine-viewport").parent().width();
let h = $(window).height();
if (w === 0) {
w = ((2482 * 2) / 3368) * h;
}
const w1 = ((2482 * 2) / 3368) * h;
const h1 = (3368 / (2482 * 2)) * w;
if (w1 > w) {
h = h1;
} else {
w = w1;
}
$(".magazine-viewport").width(w).height(h);
$(".magazine").width(w).height(h);
});
initBook("double");
} else {
w = $(".magazine-viewport").parent().width();
h = $(window).height();
if (w === 0) {
w = (2482 / 3368) * h;
}
const w1 = (2482 / 3368) * h;
const h1 = (3368 / 2482) * w;
if (w1 > w) {
h = h1;
} else {
w = w1;
}
$(".magazine-viewport").width(w).height(h);
$(".magazine").width(w).height(h);
$(window).resize(() => {
const w = $(".magazine-viewport").parent().width();
const h = $(window).height();
if (w === 0) {
w = (2482 / 3368) * h;
}
const w1 = (2482 / 3368) * h;
const h1 = (3368 / 2482) * w;
if (w1 > w) {
h = h1;
} else {
w = w1;
}
$(".magazine-viewport").width(w).height(h);
$(".magazine").width(w).height(h);
});
initBook("single");
}
}
// Function to initialize the flipbook
function initBook(display) {
const flipbook = $(".magazine");
flipbook.turn({
width: $(".magazine-viewport").parent().width(),
height: $(window).height(),
duration: 1000,
display,
acceleration: !isChrome(),
gradients: true,
autoCenter: true,
elevation: 50,
pages: 73,
when: {
turning: function (event, page, view) {
const book = $(this);
const currentPage = book.turn("page");
const pages = book.turn("pages");
Hash.go(`page/${page}`).update();
disableControls(page);
},
turned: function (event, page, view) {
disableControls(page);
$(this).turn("center");
if (page === 1) {
$(this).turn("peel", "br");
}
},
missing: function (event, pages) {
for (let i = 0; i < pages.length; i++) addPage(pages[i], $(this));
},
},
});
}
return {
magazine,
nextPage,
previousPage,
};
},
};
</script>
<style scoped>
/* Add your custom styles for the flipbook here */
@import "./magazine.css";
</style>
body {
overflow: hidden;
/* background: url('../pics/wood.png'); */
margin: 0;
padding: 0;
}
.back {
width: 100vw;
height: 100vh;
position: absolute;
left: 0;
top: 0;
z-index: 55;
/* background: url('../pics/wood.png'); */
background: rgba(2, 0, 34, 0.986);
}
#canvas {
position: absolute;
background: url('@/assets/images/bg4.png') repeat-x bottom center;
}
/*上一页*/
.previousPage {
width: 33%;
height: 60%;
position: absolute;
bottom: 0%;
left: 17%;
z-index: 999999;
/* background-color: aqua; */
background: transparent !important;
}
/*下一页*/
.nextPage {
width: 33%;
height: 60%;
position: absolute;
bottom: 0%;
left: 50%;
z-index: 999999;
/* background-color: aqua; */
background: transparent !important;
}
.magazine-viewport {
position: absolute;
}
.magazine-viewport .container {
z-index: 666;
position: absolute;
top: 54%;
left: 50%;
width: 1400px;
height: 781px;
margin: auto;
}
.magazine-viewport .magazine {
width: 1400px;
height: 781px;
left: -661px;
top: -300px;
}
.magazine-viewport .page {
width: 700px;
height: 781px;
background-color: white;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.magazine-viewport .zoomer .region {
display: none;
}
.magazine .region {
position: absolute;
overflow: hidden;
background: #0066FF;
opacity: 0.2;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
cursor: pointer;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
.magazine .region:hover {
opacity: 0.5;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
}
.magazine .region.zoom {
opacity: 0.01;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=1)";
filter: alpha(opacity=1);
}
.magazine .region.zoom:hover {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
.magazine .page {
-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
-ms-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
-o-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}
.magazine-viewport .page img {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin: 0;
}
.magazine .even .gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: -webkit-gradient(linear, left top, right top, color-stop(0.95, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0.2)));
background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.2) 100%);
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.2) 100%);
background-image: -ms-linear-gradient(left, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.2) 100%);
background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.2) 100%);
background-image: linear-gradient(left, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.2) 100%);
}
.magazine .odd .gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: -webkit-gradient(linear, right top, left top, color-stop(0.95, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0.15)));
background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.15) 100%);
background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.15) 100%);
background-image: -ms-linear-gradient(right, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.15) 100%);
background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.15) 100%);
background-image: linear-gradient(right, rgba(0, 0, 0, 0) 95%, rgba(0, 0, 0, 0.15) 100%);
}
.magazine-viewport .zoom-in .even .gradient,
.magazine-viewport .zoom-in .odd .gradient {
display: none;
}
.magazine-viewport .loader {
/* background-image: url(../pics/loader.gif); */
width: 22px;
height: 22px;
position: absolute;
top: 280px;
left: 219px;
}
.magazine-viewport .shadow {
-webkit-transition: -webkit-box-shadow 0.5s;
-moz-transition: -moz-box-shadow 0.5s;
-o-transition: -webkit-box-shadow 0.5s;
-ms-transition: -ms-box-shadow 0.5s;
-webkit-box-shadow: 0 0 20px #000;
-moz-box-shadow: 0 0 20px #000;
-o-box-shadow: 0 0 20px #000;
-ms-box-shadow: 0 0 20px #000;
box-shadow: 0 0 20px #000;
}
.next-button {
width: 59px;
height: 59px;
position: absolute;
top: 50%;
/* background: url('../pics/arrows.png') -59px 0; */
right: 10px;
z-index: 10;
}
.previous-button {
width: 59px;
height: 59px;
position: absolute;
top: 50%;
/* background-image: url('../pics/arrows.png'); */
z-index: 10;
}
.magazine-viewport .previous-button-hover {
background-position: 0 -59px;
cursor: pointer;
}
.magazine-viewport .next-button-hover {
background-position: -59px -59px;
cursor: pointer;
}
.magazine-viewport .previous-button-hover,
.magazine-viewport .previous-button-down {}
.magazine-viewport .previous-button-down,
.magazine-viewport .next-button-down {}
.magazine-viewport .next-button-hover,
.magazine-viewport .next-button-down {}
.magazine-viewport .zoom-in .next-button,
.magazine-viewport .zoom-in .previous-button {
display: none;
}
.animated {
-webkit-transition: margin-left 0.5s;
-moz-transition: margin-left 0.5s;
-ms-transition: margin-left 0.5s;
-o-transition: margin-left 0.5s;
transition: margin-left 0.5s;
}
.exit-message {
position: absolute;
top: 10px;
left: 0;
width: 100%;
height: 40px;
z-index: 10000;
}
.exit-message>div {
width: 140px;
height: 30px;
margin: auto;
background: rgba(0, 0, 0, 0.5);
text-align: center;
font: 12px arial;
line-height: 30px;
color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
}
.zoom-icon {
position: absolute;
z-index: 1000;
width: 22px;
height: 22px;
top: 10px;
right: 10px;
/* background-image: url(../pics/zoom-icons.png); */
background-size: 88px 22px;
}
.zoom-icon-in {
background-position: 0 0;
cursor: pointer;
}
.zoom-icon-in.zoom-icon-in-hover {
background-position: -22px 0;
cursor: pointer;
}
.zoom-icon-out {
background-position: -44px 0;
}
.zoom-icon-out.zoom-icon-out-hover {
background-position: -66px 0;
cursor: pointer;
}
.bottom {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
\ No newline at end of file
/*
* Magazine sample
*/
// import window.$ from 'jquery'
export function setArrows() {
setTimeout(function () {
var width = window.$(window).width();
var bookWidth = window.$(".magazine").width();
var arrowSize = window.$(".next-button").width();
var magaLeft = window.$(".magazine").offset().left;
var nextLeft = (width - bookWidth - magaLeft - 60) / 2;
//alert("width "+width +"\nbookWidth :"+bookWidth +"\nmagaLeft:"+magaLeft+"\nnextLeft:"+nextLeft);
window.window.$('.next-button').animate({ "right": nextLeft }, 300);
window.window.$('.previous-button').animate({ "left": nextLeft }, 300);
}, 100);
}
export function addPage(page, book) {
var id, pages = book.turn('pages');
var element = window.window.$('<div />', {});
if (book.turn('addPage', element, page)) {
element.html('<div class="gradient"></div><div class="loader"></div>');
loadPage(page, element);
}
}
export function loadPage(page, pageElement) {
pageElement.find('.loader').remove();
const imgPath = new URL(`../../assets/book/img_window.window.${page}.jpg`, import.meta.url).href;
// Create an image element
var img = window.$('<img />');
img.mousedown(function (e) {
e.preventDefault();
});
img.load(function () {
// Set the size
window.$(this).css({
width: '100%',
height: '100%'
});
// Add the image to the page after loaded
window.$(this).appendTo(pageElement);
// Remove the loader indicator
pageElement.find('.loader').remove();
});
// Load the page
img.attr('src', imgPath);
}
export function zoomTo(event) { }
export function addRegion(region, pageElement) {
var reg = window.$('<div />', {
'class': 'region ' + region['class']
}),
options = window.$('.magazine').turn('options'),
pageWidth = options.width / 2,
pageHeight = options.height;
reg.css({
top: Math.round(region.y / pageHeight * 100) + '%',
left: Math.round(region.x / pageWidth * 100) + '%',
width: Math.round(region.width / pageWidth * 100) + '%',
height: Math.round(region.height / pageHeight * 100) + '%'
}).attr('region-data', window.$.param(region.data || ''));
reg.appendTo(pageElement);
}
// Process click on a region
export function regionClick(event) {
var region = window.$(event.target);
if (region.hasClass('region')) {
window.$('.magazine-viewport').data().regionClicked = true;
setTimeout(function () {
window.$('.magazine-viewport').data().regionClicked = false;
},
100);
var regionType = window.$.trim(region.attr('class').replace('region', ''));
return processRegion(region, regionType);
}
}
// http://code.google.com/p/chromium/issues/detail?id=128488
export function isChrome() {
return navigator.userAgent.indexOf('Chrome') != -1;
}
export function disableControls(page) {
if (page == 1) window.$('.previous-button').hide();
else window.$('.previous-button').show();
if (page == window.$('.magazine').turn('pages')) window.$('.next-button').hide();
else window.$('.next-button').show();
}
// Set the width and height for the viewport
export function resizeViewport() {
var width = window.$(window).width(),
height = window.$(window).height(),
options = window.$('.magazine').turn('options');
window.$('.magazine').removeClass('animated');
window.$('.magazine-viewport').css({
width: width,
height: height
}).zoom('resize');
setArrows();
if (window.$('.magazine').turn('zoom') == 1) {
var bound = calculateBound({
width: options.width,
height: options.height,
boundWidth: Math.min(options.width, width),
boundHeight: Math.min(options.height, height)
});
if (bound.width % 2 !== 0) bound.width -= 1;
if (bound.width != window.$('.magazine').width() || bound.height != window.$('.magazine').height()) {
window.$('.magazine').turn('size', bound.width, bound.height);
if (window.$('.magazine').turn('page') == 1) window.$('.magazine').turn('peel', 'br');
}
window.$('.magazine').css({
top: -bound.height / 2,
left: -bound.width / 2
});
}
var magazineOffset = window.$('.magazine').offset(),
boundH = height - magazineOffset.top - window.$('.magazine').height(),
marginTop = (boundH - window.$('.thumbnails > div').height()) / 2;
if (marginTop < 0) {
window.$('.thumbnails').css({
height: 1
});
} else {
window.$('.thumbnails').css({
height: boundH
});
window.$('.thumbnails > div').css({
marginTop: marginTop
});
}
if (magazineOffset.top < window.$('.made').height()) window.$('.made').hide();
else window.$('.made').show();
window.$('.magazine').addClass('animated');
}
// Number of views in a flipbook
export function numberOfViews(book) {
return book.turn('pages') / 2 + 1;
}
// Current view in a flipbook
export function getViewNumber(book, page) {
return parseInt((page || book.turn('page')) / 2 + 1, 10);
}
// Width of the flipbook when zoomed in
export function largeMagazineWidth() {
return 2214;
}
// Calculate the width and height of a square within another square
export function calculateBound(d) {
var bound = {
width: d.width,
height: d.height
};
if (bound.width > d.boundWidth || bound.height > d.boundHeight) {
var rel = bound.width / bound.height;
if (d.boundWidth / rel > d.boundHeight && d.boundHeight * rel <= d.boundWidth) {
bound.width = Math.round(d.boundHeight * rel);
bound.height = d.boundHeight;
} else {
bound.width = d.boundWidth;
bound.height = Math.round(d.boundWidth / rel);
}
}
return bound;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论