仿真翻书效果引入

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
//全局组件
// import jquery from "jquery";
// Vue.prototype.$ = jquery;
import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue";
import config from 'uview-ui/libs/config/config'
Vue.component("mescroll-body", MescrollBody);

11
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"dependencies": {
"animate.css": "^4.1.1",
"epubjs": "^0.3.93",
"jquery": "^2.2.4",
"qs": "^6.11.0",
"uview-ui": "^2.0.35"
}
@@ -199,6 +200,11 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"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": {
"version": "3.10.1",
"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",
"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": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
-->
<template>
<view style="height: 100%;">
<!-- 仅用于计算结构和样式请和阅读页一致 -->
<!-- 仅用于计算结构和样式请和阅读页一致1 -->
<view class="container hidden">
<view class="chapter">章节名</view>
<view id="content" class="content">
@@ -62,16 +62,17 @@
@scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" @scroll="scroll" >
<view class="content">
<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
class="book-inner" :class="highlight === index ? 'highlight' : ''"
v-for="(item, index) in verticalData.text" :key="index" v-html="item.picAndWord"
class="book-inner"
v-html="item.content"
:style="{
fontWeight: item.level == 2 ? 'bold' : item.level == 3 ? 'bold' : '',
fontSize: `${fontSize}px`,
lineHeight: `${lineHeight * fontSize}px`,
color: `${colorList[background - 1]}`
}"></p>
<img style="max-width: 90%;" v-if="item.otherContent != '' && item.otherContent != null" :src="item.otherContent">
</view>
</view>
<view
@@ -95,10 +96,12 @@
</view>
<!-- 横向翻页 -->
<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,
transform: turnType == 0 && pageBackRef.before ? 'translate(0, 0)' : `translate${prePage.pageTranslate[turnType]}`,
transition: `transform ${showAnimation ? turnPageTime : 0}s`,
@@ -140,7 +143,7 @@
</view>
<!-- 本页 -->
<view ref="curPageRef" class="container"
<view ref="curPageRef" class="container mypages"
:class="{ container0: background === 1, container1: background === 2 }" :style="{
zIndex: 101,
transform: `translate${curPage.pageTranslate[turnType]}`,
@@ -185,8 +188,8 @@
</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,
transform: `translate${nextPage.pageTranslate[turnType]}`,
transition: `transform ${showAnimation ? turnPageTime : 0}s`,
@@ -221,7 +224,28 @@
</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}`,
width: `${pageBackRef.width}`,right: `${pageBackRef.right}` }]" class="pageback_container">
@@ -257,7 +281,6 @@
@touchend.stop>
<view :style="{ height: `${statusBarHeight}px` }"></view>
<view class="head">
<image class="backiconfont" @click="back" src="../../static/icon/back.svg" mode="aspectFit"></image>
</view>
</view>
@@ -269,8 +292,8 @@
<!-- 章节进度条 -->
<view class="progress-box">
<text @click="goPreChapter">上一章</text>
<view style="flex: 1;height: 100%;padding: 8px 0;">
<text style="" @click="goPreChapter">上一章</text>
<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"
:max="directoryList.length - 1" @changing="slideChanging" @change="slideChange" />
</view>
@@ -327,6 +350,8 @@
@click="changeTurnType(2)">上下平移</view>
<view class="icon" :class="{ active: turnType === 3 }" style="padding: 5px 8px; margin-bottom: 6px;"
@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 class="item">
@@ -358,23 +383,43 @@
<u-popup :show="imgsShow" :round="10" @close="imgsShow=false">
<view class="tanchu" v-if="newchapterImgList">
<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 class="imgBox">
<view style="height:90%" @click="clickImg(newchapterImgList,index)">
<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>
</scroll-view>
</view>
</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>
</template>
<script>
import battery from '../../components/battery/battery.vue'
import virtualList from '../../components/virtualList/virtualList.vue'
// 引入翻页效果动画
//import $ from 'jquery'
import {
dateToStr
} from '../../utils/utils.js'
@@ -382,6 +427,7 @@
mapState
} from 'vuex';
import $http from '../../config/requestConfig';
let copyBookText = []
let preText = []
let nextText = []
@@ -395,6 +441,15 @@
},
data() {
return {
baseList: [{
name: 'photo',
title: '章节图片'
},
{
name: 'setting',
title: '阅读器设置'
}
],
imgsShow:false,
nothingShow:false,
// 本章图片列表
@@ -546,7 +601,7 @@
biaodian : ['',':','、',';','。','.'], //匹配的标点
maxFontSize: 30, //最大字体大小px
minFontSize: 14, //最小字体大小px
turnType: 0, //翻页方式
turnType: 4, //翻页方式
NumCol: '', // 一章多少行
colSize: '', // 一行多少字
fontSize: '', //字体大小,
@@ -593,7 +648,15 @@
},
topChange:0,
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()
},
onReady() {
// console.log('------------------------------')
// 单页禁止测滑返回
// #ifdef APP-PLUS
let currentWebview = this.$mp.page.$getAppWebview() //获取当前页面的webview对象
currentWebview.setStyle({ popGesture: 'none' })
// #endif
},
onHide() {
this.setStorage()
},
@@ -626,8 +697,30 @@
return this.currentPage / (this.curChapter.totalPage - 1)
},
...mapState(['userInfo']),
rect() {
return {
width: this.width,
height: this.height,
}
},
},
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){
// 点击图片
let imgarr = this.newchapterImgList.map(item => item)
@@ -638,36 +731,24 @@
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(){
this.nothingShow = true
},
showImgHandle(){
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() {
this.$http
.post('book/book/appinfo/' + this.bookId_mark + '/' + this.userInfo.id)
@@ -772,7 +853,7 @@
this.newchapterImgList = arr3
// console.log(this.newchapterImgList, 'newchapterImgList')
copyBookText = arr
// console.log(copyBookText,'copyBookText')
// console.log(this.SimulationText,'SimulationText')
this.getSizePage(NumCol)
},
mpforGet(colSize, NumCol) {
@@ -907,7 +988,9 @@
}
arr.push(newArr)
copyBookText = arr // 每一页显示的内容
console.log(copyBookText,'copyBookText')
this.SimulationText = arr
this.hasSimulationText = true
console.log(this.SimulationText,'SimulationText')
},
setStorage() {
@@ -2489,6 +2572,12 @@
this.turnType = turnType;
uni.setStorageSync('turnType', this.turnType)
}
if (turnType == 4) {
// 逼真翻页方式
this.isSimulation = true
}else{
this.isSimulation = false
}
if (turnType == 3) {
this.isVerticalHua = true
// 如果正在播放音频 则暂停掉
@@ -2783,7 +2872,7 @@
* 购买书籍接口
**/
buyBook() {
//在回调中调用this.initPage()刷新本页
//在回调中调用this.initPage()刷新本页1
uni.showToast({
title: '跳转至购买页面,如果未登陆则跳转登陆',
icon: 'none'
@@ -2802,10 +2891,54 @@
}
}
</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>
@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;
width: 30px; font-size: 15px;
border: 1px solid #6aa84f;
@@ -2813,6 +2946,8 @@
line-height: 30px;
/* color: red; */
border-radius: 15px;}
.chapterImgTitle{display: block; ;color: #636363; text-align: center; font-size: 30rpx; margin: 10px 0;}
.scroll-view_H {
white-space: nowrap;
@@ -2855,7 +2990,7 @@
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 {
width: 150rpx;
height: 150rpx;
@@ -2950,7 +3085,7 @@
padding: 0px 0;
height: 96%;
width: 100%;
background-color: #fff;
background-color: #f7faf9;
overflow: hidden;
.chapter {
@@ -3000,7 +3135,7 @@
}
.container0 {
background-color: #fff;
background-color: #f7faf9;
background-size: 100% 100%;
}