Vue项目结合Turn.js制作翻页动画,从零到1
⭐项目说明
- 书籍翻页项目 - 翻页动画,页码跳转
- 语言 vue 2.0 ,软件 Webstorm
- 引入了 turn.js ,用到 jquery
- 主要:翻页、触屏放大缩小、视频首页面显示、移动端与ipad适配
**Gitee 项 目下 载 **
1.turnpage-one,步骤1 至 4 - https://gitee.com/fightinghh/turnpage-one
2.turnpage-two,步骤1 至 8 - https://gitee.com/fightinghh/turnpage-two
1.创建 vue 2.0 项目
学习链接 – 创建简单vue项目 / Webpack创建vue项目
我采用的 Webstorm 界面创建项目
1. 左上角 File -> New -> Project
2. 弹出的 ' New Project ' 界面 左侧选择 ' Vue.js ',见图1
3. 在 ' Terminal ' 面板,选择,见图2,不清楚选项含义的码友点上方链接
4. ' Terminal '面板,输入 ' npm install ' 命令,加载依赖
5. 运行命令 ' npm run serve '
(package.json文件的scripts设置了运行和打包命令)
2.翻页动画 - 基本样式
学习链接 – 主看安装 ♥ – vue2.x中使用翻书效果turn.js
学习链接 – 主看安装配置 – VUE翻书效果(turn.js,仿真折角过渡)
学习链接 – 主看属性说明与案例 – turn.js (翻页效果)总结
学习链接 – 主看属性说明 – turn.js
学习链接 – 主看属性说明 – turn.js教程与总结
学习链接 – 简单了解 – configureWebpack 与 chainWebpack的区别
① 样式展示
1.turn,js 下载
[ 官方网站 -> 点击DownLoad ] ( http://www.turnjs.com/ )
2.下载的压缩包解压,将 lib -> turn.js 复制到 项目 src/utils 里
3.Turn.js是使用了jquery书写的,使用vue中要引入jquery
安装命令 ' npm install --save jquery '
4.修改 vue.config.js 文件
const webpack = require('webpack');
module.exports = defineConfig({
... ...
//配置webpack选项的内容
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
})
]
},
})
5. 使用翻页的页面引入 turn.js
<script>
import turn from '@/utils/turn.js' // 引入
export default {
name: "TurnPage" //翻页的页面
}
</script>
③ 页面代码
更改图片路径即可
<template>
<div class="home" >
<div class="turnClass">
<div id="flipbook" class="flipbookClass" ref="flipbookref">
<div v-for="(item) in imgUrlOne" :key="item.index" class="flipbook__item"
:style="`background-image:url(${item.imgurl})`">
</div>
<img :src="lastImgUrl" class="flipbook__img"/>
</div>
</div>
</div>
</template>
<script>
import turn from '@/utils/turn'
export default {
name: "TurnPage", //翻页
data(){
return {
imgUrlOne:[
{imgurl: require('../assets/img/1.jpg'),index:1}, //首页
{imgurl: require('../assets/img/2.jpg'),index:2},
{imgurl: require('../assets/img/3.jpg'),index:3},
{imgurl: require('../assets/img/4.jpg'),index:4},
],
lastImgUrl:require('../assets/img/6.jpg'), //最后一页
}
},
methods:{
onTurn(){
var that = this;
that.$nextTick(()=>{
$("#flipbook").turn({
acceleration: true, //启用硬件加速,移动端有效
display:"single", // 显示:single=单页,double=双页,默认双页
duration: 800, // 翻页速度,撒开鼠标,页面的延迟
page: 1, // 默认显示第几页
gradients: true, // 折叠处的光泽渐变,主要体现翻页的立体感、真实感
pages: $("#flipbook").children().length,
turnCorners: "bl,br,tl,tr,l.r", //翻页动画开始的起始位置bl,br (左下,右下)tl,tr(左上,右上) or bl,tr(左下,右上)
elevation: 300,
autoCenter: true,
peel:"tr",// 在右上角显示角
width:318,
height:450,
when: {},
});
$("#flipbook").bind("first", function(event) { //卷叶
console.log('当前页面是第一页');
$("#flipbook").turn("peel","tr"); // 右上
});
$("#flipbook").bind("last",function(event){
console.log('当前页面是最后一页');
$("#flipbook").turn("peel","bl"); //左下
});
})
}
},
mounted(){
const that = this;
that.onTurn();
},
}
</script>
<style lang="less" scoped>
*{
touch-action: pan-y; // 启用单指垂直平移手势
}
.home{
background-color: rgba(199,252,255,0.55);
position:relative;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0; //固定元素,不被挤压
.turnClass{
display: flex;
flex-direction: column;
align-items: center;
.flipbookClass{
position: relative;
box-shadow: 5px 0px 5px 2px rgba(0, 0, 0, 0.16); // 阴
.flipbook__item{
background-repeat: no-repeat; // 不重复
background-size: cover; // 铺满
background-position: center center; //中心
transform-origin: 50% 50%;
}
}
}
}
</style>
3.翻页动画 - 在某页加入视频
学习链接 – 主看事件 – video标签的控制栏组件(隐藏、显示、播放等)
学习链接 – 主看实例(虽是组件封装,但方法可学习)-- Vue 使用 video 标签实现视频播放
① 样式说明
说明 :插入视频后,视频开始前有个显示图,翻页时视频暂停。
② 页面代码
不能直接复制运行,在上面的基础上,添加对应内容
1. poster属性:设置视频播放前显示图,不设置的话,视频未加载完时会显示黑屏
2. pause():视频暂停的方法
<template>
<div class="home" >
<div class="turnClass">
<div id="flipbook" class="flipbookClass" ref="flipbookref">
... ...
<div class="flipbook__item" v-for="(item) in videoImg" :style="`background-image:url(${item.imgurl})`">
<video :src="item.video" :poster="item.poster" class="item__11" controls preload :ref="'ref' + item.index"></video>
</div>
... ...
</div>
</div>
</div>
</template>
<script>
import turn from '@/utils/turn'
export default {
name: "TurnPage", //翻页
data(){
return {
... ...
videoImg:[ //index ref 相关 不要随意更改
{imgurl: require('../assets/img/5.jpg'),index:5,video: require('../assets/video/5.mp4'),poster: require('../assets/img/5.jpg')},
],
}
},
methods:{
onTurn(){
var that = this;
that.$nextTick(()=>{
$("#flipbook").turn({
... ...
when: {
turning: function(event, page, view) {
that.currentPage = page;
if(page == 5){ //注意index 与 页面顺序
that.$refs.ref5[0].pause(); // 翻页时视频暂停
}
},
},
});
})
}
},
... ...
}
</script>
<style lang="less" scoped>
... ...
.flipbook__item{
background-repeat: no-repeat; // 不重复
background-size: cover; // 铺满
background-position: center center; //中心
transform-origin: 50% 50%;
.item__11{
border: 1px solid yellow;
background-color: rgba(144,141,162,0.55);
width: 72%;
height: 80%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0px;
margin: auto;
}
video::-webkit-media-controls-play-button {
visibility: hidden;
}
}
}
... ...
</style>
4.翻页动画 - 添加页码
① 样式展示
② 页面代码
不能直接复制运行,在上面的基础上,添加对应内容
<template>
<div class="home" >
<div class="turnClass">
... ...
<div class="bookpage">
<div class="bookpage__num">
<div class="page__start" @click="toStartPage"/>
<div class="page__prev" @click="pred"/>
<div class="page__num">{{currentPage}}/{{pages}}</div>
<div class="page__next" @click="next"/>
<div class="page__end" @click="toEndPage"/>
</div>
</div>
</div>
</div>
</template>
<script>
import turn from '@/utils/turn'
export default {
name: "TurnPage", //翻页
... ...
methods:{
... ...
//第一页
toStartPage(){
var that = this;
$("#flipbook").turn("page",1);
that.currentPage = 1;
},
//最后一页
toEndPage(){
var that = this;
$("#flipbook").turn("page",that.pages );
that.currentPage = that.pages;
},
//上一页
pred(){
var that = this;
that.currentPage = $("#flipbook").turn("page");
if (that.currentPage > 1) {
that.currentPage--;
$("#flipbook").turn('page', that.currentPage);
} else {
//提示
}
},
//下一页
next(){
var that = this;
that.currentPage = $("#flipbook").turn("page");
that.pages = $("#flipbook").turn("pages");
if (that.currentPage < that.pages) {
that.currentPage++;
$("#flipbook").turn('page', that.currentPage);
} else {
//提示
}
},
},
}
</script>
<style lang="less" scoped>
.home{
... ...
.turnClass{
... ...
.flipbookClass{
... ...
}
/*分页样式*/
.bookpage{
margin-top: 25px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
.bookpage__num{
display: flex;
align-items: center;
.page__start {
margin-right: 30px;
display: block;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-right: 17px solid rgba(38,41,36,0.55);
}
.page__end {
margin-left: 30px;
display: block;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 17px solid rgba(38,41,36,0.55);
}
.page__prev{
width: 15px;
height: 15px;
border-bottom: 4px solid;
border-left: 4px solid;
border-color: rgba(38,41,36,0.55);
content: '';
transform: rotate(45deg);
margin-right: 32px;
}
.page__next{
margin-left: 32px;
width: 15px;
height: 15px;
border-top: 4px solid;
border-right: 4px solid;
border-color: rgba(38,41,36,0.55);
content: '';
transform: rotate(45deg);
}
.page__num{
width: 120px;
height: 36px;
border-radius: 20px;
border: 1px solid rgba(38,41,36,0.55);
background-color: rgba(38,41,36,0.2);
text-align: center;
line-height: 38px;
font-size: 26px;
}
}
}
}
}
</style>
5.翻页动画 - 横屏竖屏翻页区域动态适应
学习链接 – 监听事件 – H5 + vue 监听手机屏幕旋转及判断横竖屏
上方设置 $("#flipbook") 宽高 是固定值 ,如果横屏观看,内容会超出
假设我需要翻页的区域A4 大小,百度说宽高比1.414
① 样式展示
② 相关代码
在上方代码中添加到对应位置,即可运行
<script>
import turn from '@/utils/turn'
export default {
name: "TurnPage", //翻页
data(){
return {
sysWidth:0,
sysHeight:0,
... ...
}
},
created(){
this.getSystem();
this.setWidthHeigth();
},
mounted(){
const that = this;
// 监听 resize 方法
window.addEventListener("resize", that.renderResize, false);
that.onTurn();
},
beforeDestroy () {
var that =this;
// 移除监听
window.removeEventListener("resize", that.renderResize, false)
},
methods:{
//监听到横竖屏调用对应方法
renderResize() {
var that = this;
that.getSystem();
that.setWidthHeigth();
that.$nextTick(() => {
$("#flipbook").height(that.sysHeight);
$("#flipbook").width(that.sysWidth);
that.$forceUpdate;
});
// 做页面适配
// 注意:renderResize 方法执行时虚拟 dom 尚未渲染挂载,如果要操作 vue 实例,最好在this.$nextTick()里进行。
},
//设置翻页宽高
setWidthHeigth(){
var that = this;
var num = 1.414 * that.sysWidth;
var ableHeight = Math.floor(that.sysHeight) - 65;
if (num < ableHeight) {
that.sysHeight = num;
} else {
that.sysHeight = ableHeight;
that.sysWidth = Math.floor(that.sysHeight / 1.414);
}
},
//获取系统信息 - 这个看需求,我这里希望手机看时候,翻页区域横向与显示屏大小一致
getSystem(){
var that = this;
var u = navigator.userAgent;
if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {//安卓手机
} else if (u.indexOf('iPhone') > -1) {//苹果手机
//屏蔽ios下上下弹性
$(window).on('scroll.elasticity', function (e) {
e.preventDefault();
}).on('touchmove.elasticity', function (e) {
e.preventDefault();
});
} else if (u.indexOf('Windows Phone') > -1) {//winphone手机
}
that.sysWidth = $(window).width();
that.sysHeight = $(window).height();
},
//turn,js设置
onTurn(){
var that = this;
that.$nextTick(()=>{
$("#flipbook").turn({
... ...
width:that.sysWidth,
height:that.sysHeight,
... ...
});
})
}
},
}
</script>
6.移动端与ipad适配
学习链接 – 主看组件安装配置 – vue移动端适配
学习链接 – 主看ipad / ipadPro 适配Js – flexible.js不适配ipad和ipad pro
① 样式展示
② 依赖安装配置
有的链接还安装了 lib-flexible ,稍微微百度了下,有人说这个已经不维护了
1. 安装amfe-flexible依赖,设置 rem 基准值
命令 :" npm install amfe-flexible "
2.安装postcss-pxtorem依赖,一款 postcss 插件,用于将 px单位转化为 rem
命令 :" npm install postcss-pxtorem@5.1.1 --save-dev "
3.项目的main.js 引入 amfe-flexible
命令 :" import 'amfe-flexible' "
4.项目根目录,创建postcss.config.js,写入下面内容,运行项目自动执行
module.exports = {
plugins: {
// postcss-pxtorem 插件的版本需要 >= 5.0.0
// 适用版本 5.1.1
// npm install postcss-pxtorem@5.1.1 -D
'postcss-pxtorem': {
rootValue({ file }) { // 判断是否是vant的文件 如果是就使用 37.5为根节点字体大小
// 否则使用75 因为vant使用的设计标准为375 但是市场现在的主流设置尺寸是750
return file.indexOf('vant') !== -1 ? 37.5 : 75;
},
// 配置哪些文件中的尺寸需要转化为rem *表示所有的都要转化
propList: ['*'],
},
},
};
不想转换单位的地方,将单位px写成Px 或者 写为行内样式(行内样式中的px单位不会转换)
5.以上对ipad ipadPro无效,在index.html里面添加下面的代码
<script>
// 用于适配ipad以及ipad pro
/(iPhone|iPad|iPhone OS|Phone|iPod|iOS)/i.test(navigator.userAgent) &&
((head = document.getElementsByTagName('head')),
(viewport = document.createElement('meta')),
(viewport.name = 'viewport'),
(viewport.content ='target-densitydpi=device-dpi, width=480px, user-scalable=no'),
head.length > 0 && head[head.length - 1].appendChild(viewport));
</script>
7.翻页区域 - 触屏操作hammer.js插件
① 配置步骤
1. 安装hammer.js插件
命令: ' npm install hammerjs --save '
2.翻页区域的设置ref
' <div id="flipbook" class="flipbookClass" ref="flipbookref"> '
3.zoom.js 放utils文件夹,js内容见上方 学习链接
4.页面设置
<script>
import {zoomElement} from '@/utils/zoom.js';
export default {
name: 'zoom',
mounted() {
//获取需要缩放的dom元素
let zoomEl = that.$refs.flipbookref;
zoomElement(zoomEl);
}
}
</script>
8.翻页动画 - 资源加载过慢导致空屏
问题: 项目包含很多资源加载,如果直接访问,资源还没有加载完成,页面会空屏,用户体验感差
解决:链接进入后,加一个loading页面,判断页面资源都加载完成(状态 ' complete '),再显示翻页动画,这样翻页时候就不会一卡一卡的
但是这样解决也有个问题,资源太大,加载时间过久,还没想到更好方式,业务不等人啊,码友有好想法,欢迎评论区
// html 部分没有放,根据自己需求加 页面 和 页面样式 吧,主要是js,如下:
data(){
return {
timer: null, // 定时器
... ...
},
mounted(){
const that = this;
... ...
//定义,确定页面图片
that.timer = setInterval(function () {
console.log("document.readyState===2",document.readyState)
if (document.readyState === 'complete') { //如果资源加载完成
that.isMask = false; //控制遮罩层,就是加载层显示
window.clearInterval(that.timer) /
//获取需要缩放的dom元素
let zoomEl = that.$refs.flipbookref;
console.log("zoomEl:"+zoomEl);
zoomElement(zoomEl);
}
}, 2000);
},
9.Nginx部署发布
学习链接 – ♥vue项目前缀配置 – nginx配置同一域名同一端口下部署多个vue项目
学习链接 – 主看前端项目的代理 – nginx配置反向代理,负载均衡
学习链接 – 前端项目部署 – vue项目发布到服务器
步骤
前言 : 同一个域名www.aaa.com,一个端口号下面,需要部署多个项目
root根目录已经指向一个项目了,现在需要再指向这个项目
解决 : 路径不同分别代理访问不同项目
① 部署
Vue项目
1.vue.config.js文件中修改publicPath路径
module.exports = defineConfig({
publicPath: "/turnpage-two/",
... ...
})
2.router文件夹中index.js文件中修改base
const router = new VueRouter({
// mode: "history", //历史路由
base: "/turnpage-two/",
routes
})
服务器的nginx
3.nginx 上面配置, 如果vue项目用的历史路由,需要加上try_files
-- alias 别名的意思,一个server不能有多个root
location /turnpage-two {
alias /usr/share/nginx/html/turnpage-two;
index index.html index.htm;
#try_files $uri $uri/ /turnpage-two/index.html;
}
② 发布
1.Vue 项目打包,命令 ' npm run build ' , 生成 dist 文件夹
2.进入服务器,nginx的html下面,
- 创建turnpage-two文件夹,命令 ' mkdir turnpage-two '
- 将打包的dist文件内容拖到turnpage-two文件夹下
- 重启nginx容器,命令 'docker restart nginx容器ID '
10. 其他学习链接
1. 主看动画参数说明 – 如何在前端项目中对页面元素进行放大缩小操作?
2. css 背景图片自适应属性整理
3. JavaScript 中的四舍五入
4. DOM - - 获取元素的某个子元素
5. position定位属性 以及 元素居中方式
6. 如何在CSS中设置背景模糊