视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
详解vue、css3如何实现交互特效
2020-11-27 20:10:07 责编:小OO
文档
 本文主要介绍了详解vue+css3做交互特效的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

1.前言

做项目就难免会开发交互效果或者特效,而我最近开发的项目一直在使用vue,开发技术栈方面,理所当然就使用了vue+css3开发,过程中发现使用vue+css3开发特效,和javascript/jquery+css3的思维方式不一样,但是比javascript/jquery+css3简单一点点。今天就分享三个简单的小实例,希望能起到拓展思维的作用,让大家明白vue+css3应该怎样开发交互效果!如果大家有什么好的建议,或者觉得我哪里写错了,欢迎指出!

1.文章上面的代码,虽然代码很简单,不难理解,但是也是建议大家边写边看,这样不会混乱。
2.文章所提及的小实例,都是很基础的,大家可以参照自己的想法进行扩展,或者修改,可能会有意想不到的效果。我写这类型的文章也是想授人以渔,不是授人以鱼!
3.这几个实例,摘自我自己的平常练习的项目,代码已经提到github上面了(vue-demos)。欢迎大家star。

2.开场小动画运行效果

gif图模糊效果看着跟实际效果不太一样!大家注意!

原理分析

说到原理分析,其实也没什么可以分析的,就是在页面是下面这个状态的时候,把文字替换掉。至于看到字体缩成一团,就是letter-spacing这个css属性的控制效果。字体模糊就是filter: blur()这个css属性的控制效果!看到有逐渐的变化,就是css3动画(animation)的效果

下面简单分析下,这个动画的几个步骤,从下面看到,这个动画一共8个步骤。

这下就清晰明了了,我们要在下图这个瞬间开始改变文字,也就是页面加载了两秒后,动画执行了两次后就开始改变文字。然后每隔两秒改变一次文字,直到最后!

下面给出vuejavascript两种方式的代码,看下哪种方式更加的简单!

vue方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<style>
 body{
 background: #ccc;
 }
 h1 {
 color: white;
 text-transform: uppercase;
 margin-top: 100px;
 text-align: center;
 font-size: 6rem;
 line-height: 1;
 animation: letterspacing 1s 7 alternate ease-in-out;
 display: block;
 letter-spacing: .5rem;
 }

 @keyframes letterspacing {
 0% {
 letter-spacing: -72px;
 filter: blur(20px);
 }

 40% {
 filter: blur(6px);
 }

 80% {
 letter-spacing: 8px;
 filter: blur(0);
 }
 }
</style>
<body>
<p id="text">
 <h1>{{testText}}</h1>
</p>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
 new Vue({
 el:'#text',
 data:{
 nowIndex:0,
 testText:'欢迎浏览'
 },
 mounted(){
 let _this=this;
 let timer = setInterval(function(){
 _this.nowIndex++;
 switch (_this.nowIndex) {
 case 1:
 _this.testText = '守候的文章';
 break;
 case 2:
 _this.testText = '愿您浏览愉快';
 break;
 case 3:
 _this.testText = '学到知识';
 break;
 }
 if (_this.nowIndex > 3) {
 setTimeout(() => {
 clearInterval(timer);
 }, 2000)
 }
 }, 2000)
 }
 })
</script>
</html>

javascript方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<style>
 body{
 background: #ccc;
 }
 h1 {
 color: white;
 text-transform: uppercase;
 margin-top: 100px;
 text-align: center;
 font-size: 6rem;
 line-height: 1;
 animation: letterspacing 1s 7 alternate ease-in-out;
 display: block;
 letter-spacing: .5rem;
 }

 @keyframes letterspacing {
 0% {
 letter-spacing: -6rem;
 filter: blur(1rem);
 }

 40% {
 filter: blur(.3rem);
 }

 80% {
 letter-spacing: .5rem;
 filter: blur(0rem);
 }
 }
</style>
<body>
<p id="text">
 <h1>欢迎浏览</h1>
</p>
</body>
<script>
 var oH1=document.querySelector('h1'),nowIndex=0;
 console.log(oH1)
 var timer = setInterval(function () {
 nowIndex++;
 switch (nowIndex) {
 case 1:
 oH1.innerHTML = '守候的文章';
 break;
 case 2:
 oH1.innerHTML = '愿您浏览愉快';
 break;
 case 3:
 oH1.innerHTML = '学到知识';
 break;
 }
 if (nowIndex > 3) {
 setTimeout(() => {
 clearInterval(timer);
 }, 2000)
 }
 }, 2000)
</script>
</html>

3.导航滑块运行效果

原理分析

首先,下面是页面初始化的时候,橙色滑块的位置

鼠标放到第二个tab上面,大家可以看到,橙色滑块就是向右偏移了一个tab的距离

鼠标放到第三个tab上面,大家可以看到,橙色滑块就是向右偏移了两个tab的距离

如果从第一个tab到第六个tab的索引是0,1,2,3,4,5。

那么滑块的公式就是(索引*tab的宽度)。大家看到有逐渐过去的效果,其实是css3过渡(transition)的效果。大家看下面的代码就行了,一看就懂!代码如下:

vue方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
 .nav{
 margin: 40px;
 position: relative;
 }
.nav li{
 float: left;
 width: 100px;
 height: 40px;
 line-height: 40px;
 color: #fff;
 text-align: center;
 background: #09f;
 cursor: pointer;
}
 .nav span{
 position: relative;
 z-index: 2;
 }
 .nav .slider{
 position: absolute;
 transition: all .5s cubic-bezier(0.4, -0.3, 0.57, 1.38);
 width: 100px;
 height: 40px;
 background: #f90;
 top: 0;
 left: 0;
 z-index: 1;
 }
</style>
<body>
<p class="nav clear" id="nav" @mouseleave="nowIndex=0">
 <ul>
 <li @mouseenter.stop="nowIndex=0"><span>Tab One</span></li>
 <li @mouseenter.stop="nowIndex=1"><span>Tab Two</span></li>
 <li @mouseenter.stop="nowIndex=2"><span>Tab Three</span></li>
 <li @mouseenter.stop="nowIndex=3"><span>Tab four</span></li>
 <li @mouseenter.stop="nowIndex=4"><span>Tab five</span></li>
 <li @mouseenter.stop="nowIndex=5"><span>Tab six</span></li>
 </ul>
 <p class="slider" :style="{'transform':'translate3d('+nowIndex*100+'px,0,0)'}"></p>
</p>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
 new Vue({
 el:'#nav',
 data:{
 nowIndex:0
 }
 })
</script>
</html>

javascript方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
 .nav{
 position: relative;
 }
.nav li{
 float: left;
 width: 100px;
 height: 40px;
 line-height: 40px;
 color: #fff;
 text-align: center;
 background: #09f;
 cursor: pointer;
}
 .nav span{
 position: relative;
 z-index: 2;
 }
 .nav .slider{
 position: absolute;
 transition: all .5s cubic-bezier(0.4, -0.3, 0.57, 1.38);
 width: 100px;
 height: 40px;
 background: #f90;
 top: 0;
 left: 0;
 z-index: 1;
 }
</style>
<body>
<p class="nav clear" id="nav">
 <ul>
 <li><span>Tab One</span></li>
 <li><span>Tab Two</span></li>
 <li><span>Tab Three</span></li>
 <li><span>Tab four</span></li>
 <li><span>Tab five</span></li>
 <li><span>Tab six</span></li>
 </ul>
 <p class="slider"></p>
</p>
</body>
<script type="text/javascript">
 var op=document.querySelector("#nav"),oLi=op.querySelectorAll("li"),oSlider=document.querySelector(".slider");
 op.addEventListener("mouseleave",function () {
 oSlider.style.transform='translate3d(0,0,0)';
 })
 for(var i=0;i<oLi.length;i++){
 oLi[i].index=i;
 oLi[i].addEventListener("mouseenter",function (e) {
 oSlider.style.transform='translate3d('+this.index*100+'px,0,0)';
 })
 }
</script>
</html>

4.轮播图运行效果

原理分析

蓝框的是li,黑框的是p

初始化状态

处于显示第二张图片的时候

看到上面,其实也就是控制ul的偏移量(transform:translate3d)。计算公式和上面的滑块相似,索引(0|1|2|3)*li的宽度。不同的就是,ul的偏移量是取负数,因为ul是想左偏,上面的滑块是向右偏!
当第一张图片的时候,ul偏移量设置(transform: translate3d(0px, 0px, 0px))。
当第二张图片的时候,ul偏移量设置(transform: translate3d(-1000px, 0px, 0px))。
当第二张图片的时候,ul偏移量设置(transform: translate3d(-2000px, 0px, 0px))。以此类推,偏移量很简单的就能计算出来!

可能我说的大家有点懵,但是,看下面的代码,就不会懵了,因为代码也很简单!

vue方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
 <style>
 .slide-img {
 width: 1000px;
 height: 500px;
 overflow: hidden;
 position: relative;
 margin: 20px auto;
 }

 ul {
 transition: all .5s ease;
 }

 li {
 float: left;
 }

 .slide-arrow p {
 width: 50px;
 height: 100px;
 position: absolute;
 margin: auto;
 top: 0;
 bottom: 0;
 background: url("http://i1.bvimg.com/1949/4d860a3067fab23b.jpg") no-repeat;
 }

 .arrow-right {
 transform: rotate(180deg);
 right: 0;
 }

 .arrow-left {
 left: 0;
 }
 .slide-option{
 position: absolute;
 bottom: 10px;
 width: 100%;
 left: 0;
 text-align: center;
 }
 .slide-option span{
 display: inline-block;
 width: 14px;
 height: 14px;
 border-radius: 100%;
 background: #ccc;
 margin: 0 10px;
 }
 .slide-option .active{
 background: #09f;
 }
 </style>
</head>
<body>
<p class="slide-img clear" id="slide-img">
 <!--用tran这个class控制ul是否含有过渡效果,样式已经写好-->
 <ul :style="{'width':(listWidth*list.length)+'px','transform':'translate3d(-'+(listWidth*nowIndex)+'px,0,0)'}">
 <!--遍历出来的图片-->
 <li v-for="(li,index) in list" :style="{'width':listWidth+'px'}">
 <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
 <img :src="li" class="slider-img"/>
 </a>
 </li>
 </ul>
 <p class="slide-option">
 <span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
 </p>
 <p class="slide-arrow">
 <p class="arrow-left" @click.stop="switchDo('reduce')"></p>
 <p class="arrow-right" @click.stop="switchDo"></p>
 </p>
</p>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
 new Vue({
 el: '#slide-img',
 data: {
 nowIndex: 0,
 listWidth: '1000',
 list: ['./images/timg1.jpg', './images/timg2.jpg', './images/timg3.jpg', './images/timg4.jpg'],
 timer:null
 },
 methods: {
 //滑动操作
 switchDo(reduce){
 clearInterval(this.timer);
 //根据reduce判断this.nowIndex的增加或者减少!
 if(reduce==='reduce'){
 //如果是第一张,就返回最后一张
 if(this.nowIndex===0){
 this.nowIndex=this.list.length-1;
 }
 else{
 this.nowIndex--;
 }
 }
 else{
 //如果是最后一张,就返回第一张
 if(this.nowIndex===this.list.length-1){
 this.nowIndex=0;
 }
 else{
 this.nowIndex++;
 }
 }
 var _this=this;
 this.timer=setInterval(function () {
 _this.switchDo();
 },4000)

 },
 },
 mounted(){
 var _this=this;
 this.timer=setInterval(function () {
 _this.switchDo();
 },4000)
 }
 })
</script>
</html>

javascript方式

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
 <style>
 .slide-img {
 width: 1000px;
 height: 500px;
 overflow: hidden;
 position: relative;
 margin: 20px auto;
 }

 ul {
 transition: all .5s ease;
 }

 li {
 float: left;
 }

 .slide-arrow p {
 width: 50px;
 height: 100px;
 position: absolute;
 margin: auto;
 top: 0;
 bottom: 0;
 background: url("http://i1.bvimg.com/1949/4d860a3067fab23b.jpg") no-repeat;
 }

 .arrow-right {
 transform: rotate(180deg);
 right: 0;
 }

 .arrow-left {
 left: 0;
 }
 .slide-option{
 position: absolute;
 bottom: 10px;
 width: 100%;
 left: 0;
 text-align: center;
 }
 .slide-option span{
 display: inline-block;
 width: 14px;
 height: 14px;
 border-radius: 100%;
 background: #ccc;
 margin: 0 10px;
 }
 .slide-option .active{
 background: #09f;
 }
 </style>
</head>
<body>
<p class="slide-img clear" id="slide-img">
 <!--用tran这个class控制ul是否含有过渡效果,样式已经写好-->
 <ul id="slide-img-ul">
 <!--遍历出来的图片-->
 <li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg1.jpg" class="slider-img"/></a></li>
 <li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg2.jpg" class="slider-img"/></a></li>
 <li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg3.jpg" class="slider-img"/></a></li>
 <li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg4.jpg" class="slider-img"/></a></li>
 </ul>
 <p class="slide-option">
 <span></span>
 <span></span>
 <span></span>
 <span></span>
 </p>
 <p class="slide-arrow">
 <p class="arrow-left"></p>
 <p class="arrow-right"></p>
 </p>
</p>
</body>
<script type="text/javascript">
 window.onload=function () {
 var oUl=document.querySelector('#slide-img-ul');
 var oLi=oUl.querySelectorAll('li');
 var oSpan=document.querySelector('.slide-option').querySelectorAll('span');
 var oArrowLeft=document.querySelector('.arrow-left');
 var oArrowRight=document.querySelector('.arrow-right');
 oUl.style.width='4000px';
 oArrowLeft.addEventListener('click',function () {
 switchDo('reduce');
 })
 oArrowRight.addEventListener('click',function () {
 switchDo();
 })
 var timer=null,nowIndex=0;
 function switchDo(reduce){
 clearInterval(timer);
 //设置样式
 oUl.style.transform='translate3d(-'+(1000*nowIndex)+'px,0,0)';
 for (var i=0;i<oSpan.length;i++){
 if(i===nowIndex){
 oSpan[i].className='active';
 }
 else{
 oSpan[i].className='';
 }
 }
 //根据reduce判断this.nowIndex的增加或者减少!
 if(reduce==='reduce'){
 //如果是第一张,就返回最后一张
 if(nowIndex===0){
 nowIndex=oLi.length-1;
 }
 else{
 nowIndex--;
 }
 }
 else{
 //如果是最后一张,就返回第一张
 if(nowIndex===oLi.length-1){
 nowIndex=0;
 }
 else{
 nowIndex++;
 }
 }
 timer=setInterval(function () {
 switchDo();
 },4000)
 }
 switchDo();
 }
</script>
</html>

5.小结

好了,关于vue+css3开发的特效,以及和javascript+css3的对比,就说到这里了,希望这几个小实例,能帮到大家了解下应该怎么使用vue+css3开发特效的。

下载本文
显示全文
专题