Vue项目结合Turn.js制作翻页动画,项目部署发布,从零到1

⭐项目说明

  1. 书籍翻页项目 - 翻页动画,页码跳转
  2. 语言 vue 2.0 ,软件 Webstorm
  3. 引入了 turn.js ,用到 jquery
  4. 主要:翻页、触屏放大缩小、视频首页面显示、移动端与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

创建页面

(图1 创建)
3. 在 ' Terminal ' 面板,选择,见图2,不清楚选项含义的码友点上方链接

4. ' Terminal '面板,输入 ' npm install ' 命令,加载依赖

5.  运行命令  ' npm run serve ' 
   (package.json文件的scripts设置了运行和打包命令)

项目配置

(图2 项目配置)

2.翻页动画 - 基本样式

学习链接 – 主看安装 ♥ – vue2.x中使用翻书效果turn.js
学习链接 – 主看安装配置 – VUE翻书效果(turn.js,仿真折角过渡)
学习链接 – 主看属性说明与案例 – turn.js (翻页效果)总结
学习链接 – 主看属性说明 – turn.js
学习链接 – 主看属性说明 – turn.js教程与总结
学习链接 – 简单了解 – configureWebpack 与 chainWebpack的区别

① 样式展示

在这里插入图片描述

(图3 翻页展示)
### ② turn.js 配置步骤
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.翻页动画 - 添加页码

① 样式展示

在这里插入图片描述

(图5 页码跳转)

② 页面代码

不能直接复制运行,在上面的基础上,添加对应内容

<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

① 样式展示

在这里插入图片描述

(图6 调整前)

横竖屏对比

(图7 调整后)

② 相关代码

在上方代码中添加到对应位置,即可运行

<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插件

学习链接 – 仔细看就对了 ❤ --vue手势缩放组件

① 配置步骤

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中设置背景模糊

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值