Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pic-reader
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
龙菲
pic-reader
Commits
7b325fcf
提交
7b325fcf
authored
6月 24, 2025
作者:
搞事情
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1、修复快速来回翻页CSS动画一直播放的问题
2、load状态导致vue响应问题
上级
6265f8f0
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
78 行增加
和
767 行删除
+78
-767
App.vue
src/App.vue
+0
-3
components.d.ts
src/components.d.ts
+0
-4
index.vue
src/components/BookReader/index.vue
+78
-72
index.vue
src/components/FlipBook/index.vue
+0
-179
magazine.css
src/components/FlipBook/magazine.css
+0
-302
magazine.js
src/components/FlipBook/magazine.js
+0
-207
没有找到文件。
src/App.vue
浏览文件 @
7b325fcf
...
...
@@ -4,9 +4,6 @@
<!--
<flip-book
/>
-->
</div>
</
template
>
<
script
setup
>
import
FlipBook
from
"@/components/FlipBook/index.vue"
;
</
script
>
<
style
>
*
{
...
...
src/components.d.ts
浏览文件 @
7b325fcf
...
...
@@ -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'
]
...
...
src/components/BookReader/index.vue
浏览文件 @
7b325fcf
...
...
@@ -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=
"previous
Page
"
v-if=
"isMobile"
>
<van-icon
name=
"arrow-left"
/>
</div>
<div
class=
"right-button mobile-page-button"
@
click=
"next"
@
click=
"next
Page
"
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=
"previous
Page
"
></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=
"next
Page
"
></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
();
previous
Page
();
}
else
{
next
();
next
Page
();
}
}
});
...
...
@@ -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
(
currentPage
Num
)
=>
{
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
:
fals
e
,
acceleration
:
tru
e
,
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
previous
Page
=
()
=>
{
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
();
next
Page
();
break
;
case
"ArrowLeft"
:
previous
();
previous
Page
();
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
);
}
});
// 修改小图点击事件处理函数
...
...
src/components/FlipBook/index.vue
deleted
100644 → 0
浏览文件 @
6265f8f0
<
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
>
src/components/FlipBook/magazine.css
deleted
100644 → 0
浏览文件 @
6265f8f0
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
src/components/FlipBook/magazine.js
deleted
100644 → 0
浏览文件 @
6265f8f0
/*
* 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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论