仿真翻书效果引入

This commit is contained in:
@fawn-nine
2023-03-21 17:52:42 +08:00
parent 262f2cf743
commit dfd3772cc5
6 changed files with 209 additions and 61 deletions

View File

@@ -39,6 +39,8 @@ import '@/plugins/wxJsSDK.js';
// #endif // #endif
//全局组件 //全局组件
// import jquery from "jquery";
// Vue.prototype.$ = jquery;
import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue"; import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue";
import config from 'uview-ui/libs/config/config' import config from 'uview-ui/libs/config/config'
Vue.component("mescroll-body", MescrollBody); Vue.component("mescroll-body", MescrollBody);

11
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"epubjs": "^0.3.93", "epubjs": "^0.3.93",
"jquery": "^2.2.4",
"qs": "^6.11.0", "qs": "^6.11.0",
"uview-ui": "^2.0.35" "uview-ui": "^2.0.35"
} }
@@ -199,6 +200,11 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
}, },
"node_modules/jquery": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
"integrity": "sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q=="
},
"node_modules/jszip": { "node_modules/jszip": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -509,6 +515,11 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
}, },
"jquery": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz",
"integrity": "sha512-lBHj60ezci2u1v2FqnZIraShGgEXq35qCzMv4lITyHGppTnA13rwR0MgwyNJh9TnDs3aXUvd1xjAotfraMHX/Q=="
},
"jszip": { "jszip": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",

View File

@@ -7,6 +7,7 @@
"dependencies": { "dependencies": {
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"epubjs": "^0.3.93", "epubjs": "^0.3.93",
"jquery": "^2.2.4",
"qs": "^6.11.0", "qs": "^6.11.0",
"uview-ui": "^2.0.35" "uview-ui": "^2.0.35"
}, },

View File

@@ -75,7 +75,6 @@
<script> <script>
import $http from '@/config/requestConfig.js'; import $http from '@/config/requestConfig.js';
// 引入翻页效果动画
import { import {
setPay, setPay,
setPayAssign setPayAssign

View File

@@ -562,7 +562,7 @@ import $http from '../../config/requestConfig';
this.initPage() this.initPage()
}, },
computed: { computed: {
progress() { //章节的阅读进度 progress() { //章节的阅读进度1
if (this.curChapter.totalPage === 1) { if (this.curChapter.totalPage === 1) {
return 0 return 0
} }

View File

@@ -7,7 +7,7 @@
--> -->
<template> <template>
<view style="height: 100%;"> <view style="height: 100%;">
<!-- 仅用于计算结构和样式请和阅读页一致 --> <!-- 仅用于计算结构和样式请和阅读页一致1 -->
<view class="container hidden"> <view class="container hidden">
<view class="chapter">章节名</view> <view class="chapter">章节名</view>
<view id="content" class="content"> <view id="content" class="content">
@@ -62,16 +62,17 @@
@scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" @scroll="scroll" > @scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" @scroll="scroll" >
<view class="content"> <view class="content">
<view class="inner-box" :style="{ height: `${innerHeight}px` }" v-if="verticalData.canRead"> <view class="inner-box" :style="{ height: `${innerHeight}px` }" v-if="verticalData.canRead">
<view> <view style="text-indent: 2em;" v-for="(item, index) in verticalData.text" :key="index" :class="highlight === index ? 'highlight' : ''">
<p <p
class="book-inner" :class="highlight === index ? 'highlight' : ''" class="book-inner"
v-for="(item, index) in verticalData.text" :key="index" v-html="item.picAndWord" v-html="item.content"
:style="{ :style="{
fontWeight: item.level == 2 ? 'bold' : item.level == 3 ? 'bold' : '', fontWeight: item.level == 2 ? 'bold' : item.level == 3 ? 'bold' : '',
fontSize: `${fontSize}px`, fontSize: `${fontSize}px`,
lineHeight: `${lineHeight * fontSize}px`, lineHeight: `${lineHeight * fontSize}px`,
color: `${colorList[background - 1]}` color: `${colorList[background - 1]}`
}"></p> }"></p>
<img style="max-width: 90%;" v-if="item.otherContent != '' && item.otherContent != null" :src="item.otherContent">
</view> </view>
</view> </view>
<view <view
@@ -97,8 +98,10 @@
<!-- 横向翻页 --> <!-- 横向翻页 -->
<view class="across" v-else > <view class="across" v-else >
<!-- 阅读页结构和样式请和仅用于计算元素一致 --> <!-- 阅读页结构和样式请和仅用于计算元素一致 -->
<view class="chantong" v-if="!isSimulation">
<!-- 上一页 --> <!-- 上一页 -->
<view class="container" :class="{ container0: background === 1, container1: background === 2 }" :style="{ <view class="container mypages" :class="{ container0: background === 1, container1: background === 2 }" :style="{
zIndex: turnType == 0 && pageBackRef.before ? 100: 102, zIndex: turnType == 0 && pageBackRef.before ? 100: 102,
transform: turnType == 0 && pageBackRef.before ? 'translate(0, 0)' : `translate${prePage.pageTranslate[turnType]}`, transform: turnType == 0 && pageBackRef.before ? 'translate(0, 0)' : `translate${prePage.pageTranslate[turnType]}`,
transition: `transform ${showAnimation ? turnPageTime : 0}s`, transition: `transform ${showAnimation ? turnPageTime : 0}s`,
@@ -140,7 +143,7 @@
</view> </view>
<!-- 本页 --> <!-- 本页 -->
<view ref="curPageRef" class="container" <view ref="curPageRef" class="container mypages"
:class="{ container0: background === 1, container1: background === 2 }" :style="{ :class="{ container0: background === 1, container1: background === 2 }" :style="{
zIndex: 101, zIndex: 101,
transform: `translate${curPage.pageTranslate[turnType]}`, transform: `translate${curPage.pageTranslate[turnType]}`,
@@ -186,7 +189,7 @@
</view> </view>
<!-- 下一页--> <!-- 下一页-->
<view class="container" :class="{ container0: background === 1, container1: background === 2 }" :style="{ <view class="container mypages" :class="{ container0: background === 1, container1: background === 2 }" :style="{
zIndex: 100, zIndex: 100,
transform: `translate${nextPage.pageTranslate[turnType]}`, transform: `translate${nextPage.pageTranslate[turnType]}`,
transition: `transform ${showAnimation ? turnPageTime : 0}s`, transition: `transform ${showAnimation ? turnPageTime : 0}s`,
@@ -221,7 +224,28 @@
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 仿真翻页 -->
<view v-show="isSimulation" class="flipbook-viewport"
:rect="rect"
:change:rect="updateRenderData"
:SimulationText="SimulationText"
:change:SimulationText="updateSimulationText"
@touchend="openEnd"
>
<view class="container across">
<view class="flipbook" id="flipbook">
<view style="background-color: #fff;" v-for="(item, index) in SimulationText" :key="index">
<view class="chapter">{{ curPage.chapterName }}</view>
<p v-for="(item1, index1) in item" :key="index1" v-html="item1.list"
:class="{'highlight': highlight == item1.paragraph ? true : false, 'jushou': item1.class == 'jushou' ? true : false}"
:style="{fontSize: `${fontSize}px`, lineHeight: `${lineHeight * fontSize}px`, color: `${colorList[background - 1]}`, transform: `translateY(0px)` }"
></p>
</view>
</view>
</view>
</view>
<!-- end -->
<!-- 模拟页面背景 --> <!-- 模拟页面背景 -->
<view class v-if='turnType == 0 && !pageBackRef.before' :style="[{ transition: `${pageBackRef.transition}`, <view class v-if='turnType == 0 && !pageBackRef.before' :style="[{ transition: `${pageBackRef.transition}`,
width: `${pageBackRef.width}`,right: `${pageBackRef.right}` }]" class="pageback_container"> width: `${pageBackRef.width}`,right: `${pageBackRef.right}` }]" class="pageback_container">
@@ -257,7 +281,6 @@
@touchend.stop> @touchend.stop>
<view :style="{ height: `${statusBarHeight}px` }"></view> <view :style="{ height: `${statusBarHeight}px` }"></view>
<view class="head"> <view class="head">
<image class="backiconfont" @click="back" src="../../static/icon/back.svg" mode="aspectFit"></image> <image class="backiconfont" @click="back" src="../../static/icon/back.svg" mode="aspectFit"></image>
</view> </view>
</view> </view>
@@ -269,8 +292,8 @@
<!-- 章节进度条 --> <!-- 章节进度条 -->
<view class="progress-box"> <view class="progress-box">
<text @click="goPreChapter">上一章</text> <text style="" @click="goPreChapter">上一章</text>
<view style="flex: 1;height: 100%;padding: 8px 0;"> <view style="flex: 1;height: 100%;padding: 8px 0; padding-left:3px;padding-right:3px; margin-top: 16px;">
<slider :value="curChapter.chapterIndex" activeColor="#000" :block-size="20" <slider :value="curChapter.chapterIndex" activeColor="#000" :block-size="20"
:max="directoryList.length - 1" @changing="slideChanging" @change="slideChange" /> :max="directoryList.length - 1" @changing="slideChanging" @change="slideChange" />
</view> </view>
@@ -327,6 +350,8 @@
@click="changeTurnType(2)">上下平移</view> @click="changeTurnType(2)">上下平移</view>
<view class="icon" :class="{ active: turnType === 3 }" style="padding: 5px 8px; margin-bottom: 6px;" <view class="icon" :class="{ active: turnType === 3 }" style="padding: 5px 8px; margin-bottom: 6px;"
@click="changeTurnType(3)">上下滑动</view> @click="changeTurnType(3)">上下滑动</view>
<view class="icon" :class="{ active: turnType === 4 }" style="padding: 5px 8px; margin-bottom: 6px;"
@click="changeTurnType(4)">仿真翻页</view>
</view> </view>
</view> </view>
<view class="item"> <view class="item">
@@ -358,23 +383,43 @@
<u-popup :show="imgsShow" :round="10" @close="imgsShow=false"> <u-popup :show="imgsShow" :round="10" @close="imgsShow=false">
<view class="tanchu" v-if="newchapterImgList"> <view class="tanchu" v-if="newchapterImgList">
<text class="chapterImgTitle">当前章节共 {{newchapterImgList.length}} 张图片</text> <text class="chapterImgTitle">当前章节共 {{newchapterImgList.length}} 张图片</text>
<scroll-view class="scroll-view_H" scroll-x="true" scroll-left="120" @scrolltolower="toRight"> <scroll-view class="scroll-view_H" scroll-x="true" @scrolltolower="toRight">
<view v-for="(item,index) in newchapterImgList" class="scroll-view-item_H"> <view v-for="(item,index) in newchapterImgList" class="scroll-view-item_H">
<view class="imgBox"> <view class="imgBox">
<view style="height:90%" @click="clickImg(newchapterImgList,index)"> <view style="height:90%" @click="clickImg(newchapterImgList,index)">
<img :src="item" alt="" height="100%"></view> <img :src="item" alt="" height="100%"></view>
<!-- <text class="nothingShow" v-if="index == newchapterImgList.length-1">已最后一张图片</text> --> <text style="font-size: 24rpx; color: #666;"> {{index + 1}} </text>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</u-popup> </u-popup>
<u-popup :show="setShow" :round="10" @close="setShow = false" >
<view class="setMenu">
<u-grid :border="false" col="2" @click="clickSet">
<u-grid-item v-for="(baseListItem,baseListIndex) in baseList"
:key="baseListIndex">
<u-icon
:customStyle="{paddingTop:20+'rpx'}"
:name="baseListItem.name"
:size="30"
></u-icon>
<text class="grid-text" style="color: #666;">{{baseListItem.title}}</text>
</u-grid-item>
</u-grid>
</view>
</u-popup>
</view> </view>
</template> </template>
<script> <script>
import battery from '../../components/battery/battery.vue' import battery from '../../components/battery/battery.vue'
import virtualList from '../../components/virtualList/virtualList.vue' import virtualList from '../../components/virtualList/virtualList.vue'
// 引入翻页效果动画
//import $ from 'jquery'
import { import {
dateToStr dateToStr
} from '../../utils/utils.js' } from '../../utils/utils.js'
@@ -382,6 +427,7 @@
mapState mapState
} from 'vuex'; } from 'vuex';
import $http from '../../config/requestConfig'; import $http from '../../config/requestConfig';
let copyBookText = [] let copyBookText = []
let preText = [] let preText = []
let nextText = [] let nextText = []
@@ -395,6 +441,15 @@
}, },
data() { data() {
return { return {
baseList: [{
name: 'photo',
title: '章节图片'
},
{
name: 'setting',
title: '阅读器设置'
}
],
imgsShow:false, imgsShow:false,
nothingShow:false, nothingShow:false,
// 本章图片列表 // 本章图片列表
@@ -546,7 +601,7 @@
biaodian : ['',':','、',';','。','.'], //匹配的标点 biaodian : ['',':','、',';','。','.'], //匹配的标点
maxFontSize: 30, //最大字体大小px maxFontSize: 30, //最大字体大小px
minFontSize: 14, //最小字体大小px minFontSize: 14, //最小字体大小px
turnType: 0, //翻页方式 turnType: 4, //翻页方式
NumCol: '', // 一章多少行 NumCol: '', // 一章多少行
colSize: '', // 一行多少字 colSize: '', // 一行多少字
fontSize: '', //字体大小, fontSize: '', //字体大小,
@@ -593,7 +648,15 @@
}, },
topChange:0, topChange:0,
scroll_end: false, scroll_end: false,
musicPlaying: false // 正在播放音频 musicPlaying: false, // 正在播放音频
// 仿真翻页参数
width: uni.getSystemInfoSync().windowWidth,
height: '800px',
text: 'hello',
isSimulation: true, // 仿真翻页模式
SimulationText:[], // 仿真翻页内容数组
hasSimulationText:false,
setShow:true,
} }
}, },
@@ -612,6 +675,14 @@
this.setStorage() this.setStorage()
}, },
onReady() {
// console.log('------------------------------')
// 单页禁止测滑返回
// #ifdef APP-PLUS
let currentWebview = this.$mp.page.$getAppWebview() //获取当前页面的webview对象
currentWebview.setStyle({ popGesture: 'none' })
// #endif
},
onHide() { onHide() {
this.setStorage() this.setStorage()
}, },
@@ -626,8 +697,30 @@
return this.currentPage / (this.curChapter.totalPage - 1) return this.currentPage / (this.curChapter.totalPage - 1)
}, },
...mapState(['userInfo']), ...mapState(['userInfo']),
rect() {
return {
width: this.width,
height: this.height,
}
},
}, },
methods: { methods: {
openStart(e){
// console.log(4444,e)
},
openEnd(e){
let delta = 0
let that = this
delta = e.changedTouches[0].clientX - this.touchStartX;
if (e.changedTouches[0].clientX <= this.windowWidth / 3 * 2 && e.changedTouches[0].clientX >=this.windowWidth / 3) { //点击屏幕中间1/3为呼出菜单
// this.showMenu()
this.setShow = true
//this.menuShow = true
// console.log(this.menuShow)
}
},
clickImg(item,index){ clickImg(item,index){
// 点击图片 // 点击图片
let imgarr = this.newchapterImgList.map(item => item) let imgarr = this.newchapterImgList.map(item => item)
@@ -638,36 +731,24 @@
urls: imgarr urls: imgarr
}) })
}, },
clickSet(name){
// 点击图片
if(name == 0){
this.imgsShow = true
}else if(name == 1){
this.showMenu()
}
this.setShow = false
// this.$refs.uToast.success(`点击了第${name}个`)
// console.log(name,'imgarr')
},
toRight(){ toRight(){
this.nothingShow = true this.nothingShow = true
}, },
showImgHandle(){ showImgHandle(){
this.imgsShow = true this.imgsShow = true
}, },
scroll: function(e) {
// this.oldType = "Vertical"
// setTimeout(() => {
// //console.log(e.detail)
// this.topChange = e.detail.scrollTop
// },2000)
// this.scrollTop = e.detail.scrollTop
// this.scrollTop1 = e.detail.scrollTop
// 计算当前的page
// this.page = parseInt(e.detail.scrollTop / (this.NumCol * this.lineHeight * this.fontSize))
// this.scroll_end = false;
// const that = this;
// this.scrollTop = e.detail.scrollTop;
// clearTimeout(timer);
// var timer = setTimeout(function(){
// if( e.detail.scrollTop === that.scrollTop ){
// that.scroll_end = true;
// console.log(that.scroll_end,"是否结束",e.detail.scrollTop, "data", that.scrollTop )
// clearTimeout(timer);
// timer = null; // 处理回收
// }
// }, 500)
},
bookMessage() { bookMessage() {
this.$http this.$http
.post('book/book/appinfo/' + this.bookId_mark + '/' + this.userInfo.id) .post('book/book/appinfo/' + this.bookId_mark + '/' + this.userInfo.id)
@@ -772,7 +853,7 @@
this.newchapterImgList = arr3 this.newchapterImgList = arr3
// console.log(this.newchapterImgList, 'newchapterImgList') // console.log(this.newchapterImgList, 'newchapterImgList')
copyBookText = arr copyBookText = arr
// console.log(copyBookText,'copyBookText') // console.log(this.SimulationText,'SimulationText')
this.getSizePage(NumCol) this.getSizePage(NumCol)
}, },
mpforGet(colSize, NumCol) { mpforGet(colSize, NumCol) {
@@ -907,7 +988,9 @@
} }
arr.push(newArr) arr.push(newArr)
copyBookText = arr // 每一页显示的内容 copyBookText = arr // 每一页显示的内容
console.log(copyBookText,'copyBookText') this.SimulationText = arr
this.hasSimulationText = true
console.log(this.SimulationText,'SimulationText')
}, },
setStorage() { setStorage() {
@@ -2489,6 +2572,12 @@
this.turnType = turnType; this.turnType = turnType;
uni.setStorageSync('turnType', this.turnType) uni.setStorageSync('turnType', this.turnType)
} }
if (turnType == 4) {
// 逼真翻页方式
this.isSimulation = true
}else{
this.isSimulation = false
}
if (turnType == 3) { if (turnType == 3) {
this.isVerticalHua = true this.isVerticalHua = true
// 如果正在播放音频 则暂停掉 // 如果正在播放音频 则暂停掉
@@ -2783,7 +2872,7 @@
* 购买书籍接口 * 购买书籍接口
**/ **/
buyBook() { buyBook() {
//在回调中调用this.initPage()刷新本页 //在回调中调用this.initPage()刷新本页1
uni.showToast({ uni.showToast({
title: '跳转至购买页面,如果未登陆则跳转登陆', title: '跳转至购买页面,如果未登陆则跳转登陆',
icon: 'none' icon: 'none'
@@ -2802,10 +2891,54 @@
} }
} }
</script> </script>
<script lang="renderjs" module="turnjs">
import '@/utils/jquery.min.1.7.js';
import turn from '@/utils/turn.js';
export default {
data() {
return {
width: '',
height: '',
SimulationText:[],
}
},
mounted() {
// this.onTurn();
},
methods: {
updateRenderData(newVal, oldVal) {
let {
width,
height
} = newVal;
this.width = width;
this.height = height;
},
updateSimulationText(newVal, oldVal){
//this.onTurn();
this.SimulationText = newVal
console.log('更新数组',newVal)
if(newVal.length > 0) this.onTurn();
},
onTurn() {
$("#flipbook").turn({
autoCenter: true,
display: 'single',
height: this.height,
width: this.width,
elevation: 50,
gradients: true,
});
}
}
}
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import url("@/pages/yRead/iconfont.css"); @import url("@/pages/yRead/iconfont.css");
#flipbook{
view{ p{padding:0 10px;}}
}
.setMenu{text-align: center; padding:20px 10px}
.showImgs{ float: right; padding-right: 3px; margin-right: 10px; .showImgs{ float: right; padding-right: 3px; margin-right: 10px;
width: 30px; font-size: 15px; width: 30px; font-size: 15px;
border: 1px solid #6aa84f; border: 1px solid #6aa84f;
@@ -2813,6 +2946,8 @@
line-height: 30px; line-height: 30px;
/* color: red; */ /* color: red; */
border-radius: 15px;} border-radius: 15px;}
.chapterImgTitle{display: block; ;color: #636363; text-align: center; font-size: 30rpx; margin: 10px 0;} .chapterImgTitle{display: block; ;color: #636363; text-align: center; font-size: 30rpx; margin: 10px 0;}
.scroll-view_H { .scroll-view_H {
white-space: nowrap; white-space: nowrap;
@@ -2855,7 +2990,7 @@
height: 100%; height: 100%;
} }
} }
.nothingShow{display: block; height: 10%; font-size: 24rpx; color: #636363; margin: 10px 0; text-align: center;} .nothingShow{display: block;font-size: 24rpx; color: #666; margin: 10px 0; text-align: center;}
.listenitem { .listenitem {
width: 150rpx; width: 150rpx;
height: 150rpx; height: 150rpx;
@@ -2950,7 +3085,7 @@
padding: 0px 0; padding: 0px 0;
height: 96%; height: 96%;
width: 100%; width: 100%;
background-color: #fff; background-color: #f7faf9;
overflow: hidden; overflow: hidden;
.chapter { .chapter {
@@ -3000,7 +3135,7 @@
} }
.container0 { .container0 {
background-color: #fff; background-color: #f7faf9;
background-size: 100% 100%; background-size: 100% 100%;
} }