前言
用Vue来写了 移动端 3D轮播 带缩略图 ,在加 动画翻卡效果 ,其实也不是太难吧,也就做了一下午,哈哈,
船到桥头自然直,这样才可以,
首先看下做好的效果图
可以 点击 滑动 ,可以触摸滑动, 可以点击 缩略图滑动, 最后 在点击那个 选中的 翻卡的 那个有翻卡 的3D效果
代码:
<template> <section class="container"> <div id="slide" class="slide index-slide"> <!-- 轮播图片数量可自行增减 --> <div class="img back" v-for="(item,index) in imgsList" :key="index + '-img'" :class="'img'+ (index+1) " :ref="'imgs'+(index)" :id="'img'+(index)" > <img :src="item.img" :ref="'innderImgs'+(index)"> </div> <div class="img front" v-for="(item,index) in imgFront" :key="index" :class="'img'+ (index+1) " :ref="'img'+(index)" :id="(index)" @click="clickFan(index) " > <img :src="item" :ref="'innderImg'+(index)"> </div> </div> <div class="slide-bt"> <img :src="item.img" v-for="(item,index) in imgsList" :key="index" @click="smallPhotoClick(index)" :ref="'li'+(index)" > </div> </section> </template> <script> import reverse_card from "../../assets/images/card/reverse_card.png"; export default { name: "error", data() { return { imgsList: [ { img: "http://img1.qq.com/news/pics/16678/16678931.jpg", isSelect: false }, { img: "http://img1.gtimg.com/comic/pics/25615/25615217.jpg", isSelect: false }, { img: "http://img1.gtimg.com/comic/pics/25615/25615214.jpg", isSelect: false }, { img: "https://quickbassdev.oss-cn-shanghai.aliyuncs.com/saas/merchant/2645/191120143413l2DQIkYV", isSelect: false }, { img: "https://quickbassdev.oss-cn-shanghai.aliyuncs.com/saas/merchant/2645/1911181823465btd9sxZ", isSelect: false }, { img: "https://cdndaily.quickbass.com/o2o/merchant/2645/190912152050_JPjFgap!s200", isSelect: false } ], imgFront: [], slideNub: 6, isTurm: false }; }, beforeCreate() { this.$loading.open(); }, mounted() { let vm = this; this.$nextTick(() => {}); setTimeout(() => { this.$loading.close(); }, 300); this.getImg(); // this.slideLi(); // this.k_touch(); }, methods: { getImg() { // if (this.slideNub > 5) { // this.$refs.img5[0].className = "img back img5"; // } for (var i = 0; i < this.slideNub; i++) { this.imgFront.push(reverse_card); } setTimeout(() => { if (this.slideNub > 5) { console.log(this.$refs.img5); this.$refs.img5[0].className = "img front img5"; this.slideLi(); this.k_touch(); } }, 200); }, //右滑动 right() { let _this = this; var fy = new Array(); for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; fy[i] = this.$refs[gv][0].className; } for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; if (i == 0) { this.$refs[gv][0].className = fy[this.slideNub - 1]; } else { this.$refs[gv][0].className = fy[i - 1]; } } this.slideLi(); }, //左滑动 left() { let _this = this; var fy = new Array(); for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; fy[i] = this.$refs[gv][0].className; } for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; if (i == this.slideNub - 1) { this.$refs[gv][0].className = fy[0]; } else { this.$refs[gv][0].className = fy[i + 1]; } } this.slideLi(); }, //轮播图片左右图片点击翻页 imgClickFy() { let _this = this; let slideList = 0; }, clickFan(id) { let _this = this; let slideList = 0; for (var i = 0; i < this.slideNub; i++) { this.$refs["innderImg" + i][0].className = ""; let gv = "img" + i; if (this.$refs[gv][0].className == "img front img3") { slideList = parseInt(this.$refs[gv][0].id); // 点击选中那个 if (slideList == id) { this.$refs[gv][0].className = "img front img3 fan-front"; this.$refs["imgs" + slideList][0].className = "img back img3 fan-back"; //this.$refs["innderImg" + slideList][0].className = "img-fan"; setTimeout(() => { // 还原 图片初始 this.$refs[gv][0].className = "img front img3"; this.$refs["imgs" + slideList][0].className = "img back img3"; }, 2000); } } } var tzcs = id - slideList; if (tzcs > 0) { for (var i = 0; i < tzcs; i++) { setTimeout(function() { _this.right(); }, 1); } } if (tzcs < 0) { tzcs = -tzcs; for (var i = 0; i < tzcs; i++) { setTimeout(function() { _this.left(); }, 1); } } this.isTurm = !this.isTurm; }, //轮播按钮点击翻页 smallPhotoClick(id) { let _this = this; let slideList = 0; for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; console.log(this.$refs[gv][0].className); if (this.$refs[gv][0].className == "img front img3") { slideList = parseInt(this.$refs[gv][0].id); } } var tzcs = id - slideList; if (tzcs > 0) { for (var i = 0; i < tzcs; i++) { setTimeout(function() { _this.right(); }, 1); } } if (tzcs < 0) { tzcs = -tzcs; for (var i = 0; i < tzcs; i++) { setTimeout(function() { _this.left(); }, 1); } } _this.slideLi(); }, //修改当前最中间图片对应按钮选中状态 slideLi() { var slideList = 0; for (var i = 0; i < this.slideNub; i++) { let gv = "img" + i; if (this.$refs[gv][0].className == "img front img3") { slideList = parseInt(this.$refs[gv][0].id); // slideList = parseInt(this.$refs[gv][0].id) + 1; } } for (var i = 0; i < this.slideNub; i++) { let gv = "li" + i; this.$refs[gv][0].className = ""; } if (slideList == 6) { slideList = 0; } this.$refs["li" + slideList][0].className = "on"; }, //触摸滑动模块 k_touch() { let _this = this; var _start = 0, _end = 0, _content = document.getElementById("slide"); _content.addEventListener("touchstart", touchStart, false); _content.addEventListener("touchmove", touchMove, false); _content.addEventListener("touchend", touchEnd, false); function touchStart(event) { var touch = event.targetTouches[0]; _start = touch.pageX; } function touchMove(event) { var touch = event.targetTouches[0]; _end = _start - touch.pageX; } function touchEnd(event) { if (_end < -100) { _this.left(); _end = 0; } else if (_end > 100) { _this.right(); _end = 0; } } } } }; </script> <style lang="scss" scoped> .container { width: 100%; } .slide { width: 100%; overflow: hidden; position: relative; height: 9.38rem; perspective: 500; -webkit-perspective: 500; // 3D } .back { transform: rotateY(-180deg); } .fan-front { transform: rotateY(-180deg); } .fan-back { transform: rotateY(-360deg); } .slide .img { overflow: hidden; position: absolute; transition: width 0.4s, height 0.4s, top 0.4s, left 0.4s, z-index 0.4s; -webkit-perspective: 10000; backface-visibility: hidden; transition: all 1s; } .slide .img img { width: calc(100% - 14px); height: calc(100% - 14px); margin: 7px; } .slide .img1 { width: 40%; height: 40%; top: 30%; left: -110%; z-index: 1; opacity: 0.4; } .slide .img2 { width: 60%; height: 60%; top: 20%; left: -50%; z-index: 2; opacity: 0.4; } .slide .img3 { width: 80%; height: 80%; top: 10%; left: 10%; z-index: 3; } .slide .img4 { width: 60%; height: 60%; top: 20%; left: 90%; z-index: 2; opacity: 0.4; } .slide .img5 { width: 40%; height: 40%; top: 30%; left: 150%; z-index: 1; opacity: 0.4; } button { width: 50px; margin: 20px; } .slide-bt { position: absolute; left: 0%; bottom: -30%; z-index: 10; img { width: 1.2rem; height: 1.5rem; margin-top: .2rem; margin-left: 0.05rem; border-radius: 0.02rem; } .on { border: 0.04rem solid red; //background: #ffd200; } } .slide-bt span { width: 24px; height: 8px; background: #c9caca; float: left; margin: 5px; border-radius: 4px; } .slide .slide-bt .on { background: #ffd200; } .img-fan { // animation:play 1s linear infinite; animation: play 1.5s ease-in-out; transform: translate3d(0, 0, 0); } @keyframes play { 0% { transform: rotateY(0deg); } 100% { transform: rotateY(360deg); } } </style>View Code
翻卡:
原理:这个卡片翻转效果是利用背面的内容一开始就先翻转180度,等正面翻转的时候背面再翻转360度,这样子背面翻转到面对屏幕的时候内容却是正的而不是反的
代码解析:
这里主要用到了CSS3的一些新的属性:perspective;
backface-visibility:hidden;
transition:all 2s;
transform:rotateY(Ndeg);
下面对这些属性进行详细的说明.
1.perspective:number|none(默认)
主要用来表示3D元素距离视图的距离,单位是像素,定义在父元素上,子元素就会获得透视效果,目前浏览器都在不支持,chrom和safari支持扩展的-webkit-perspectiv.
这个属性能查到的资料上基本上都是这么讲的,感觉不是很理解什么事透视效果,在我看来,使用这个属性就是在3D转换的时候能够看到立体的3D效果,可以配合perspective-origion来使用,可惜的是目前只有chrom和safari支持带有浏览器属性前缀的该属性.
2.backface-visibility:visiale|hidden
该属性用来定义当元素不面向屏幕的时候是否可见,可用来设置旋转元素是否希望用来看到背面.IE10+和Firefox支持该属性,Opera 15+、Safari 和 Chrome 支持替代的 -webkit-backface-visibility 属性
3.transition:css属性名称 完成动画的时间 规定速度效果的速度曲线 定义过渡效果何时开始
transition是一个简写属性,用来设置四个属性:transition-property, transition-duration, transition-timing-function, transition-delay,一般为了省事直接就会写作transition:all 2s。过渡时间必须设置,否则不会产生过渡效果。IE10+,chrome,opera,Firefox支持transition属性,Safari支持替代的-webkit-transition属性
transition-timing-function:linear(匀速)|ease(默认.慢速开始,加快,慢速结束)|ease-in(慢速开始)|ease-out(慢速结束)|ease-in-out(慢速开始,慢速结束)|cubic-bezier(n,n,n,n)贝赛尔曲线
4.transform:rotateY(Ndeg)
兼容性不说那么多了,感觉反正用的时候全部加上浏览器前缀好啦.
主要是用来定义各种变换的,translate,scale,rotate,skew,可惜熟悉使用一下,用的还是比较多的
这就是 2019年最后一遍博客啦,
来年咱们继续加油呀 ,奋斗的少年
永远在路上