详解vue+css3做交互特效的方法


Posted in Javascript onNovember 20, 2017

1.前言

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

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

2.开场小动画运行效果

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

详解vue+css3做交互特效的方法

原理分析

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

详解vue+css3做交互特效的方法

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

详解vue+css3做交互特效的方法

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

详解vue+css3做交互特效的方法

下面给出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>
<div id="text">
  <h1>{{testText}}</h1>
</div>
</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>
<div id="text">
  <h1>欢迎浏览</h1>
</div>
</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.导航滑块运行效果

详解vue+css3做交互特效的方法

原理分析

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

详解vue+css3做交互特效的方法

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

详解vue+css3做交互特效的方法

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

详解vue+css3做交互特效的方法

如果从第一个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>
<div 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>
  <div class="slider" :style="{'transform':'translate3d('+nowIndex*100+'px,0,0)'}"></div>
</div>
</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>
<div 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>
  <div class="slider"></div>
</div>
</body>
<script type="text/javascript">
  var oDiv=document.querySelector("#nav"),oLi=oDiv.querySelectorAll("li"),oSlider=document.querySelector(".slider");
  oDiv.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.轮播图运行效果

详解vue+css3做交互特效的方法

原理分析

蓝框的是li,黑框的是div

初始化状态

详解vue+css3做交互特效的方法

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

详解vue+css3做交互特效的方法

看到上面,其实也就是控制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 div {
      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>
<div 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>
  <div class="slide-option">
    <span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
  </div>
  <div class="slide-arrow">
    <div class="arrow-left" @click.stop="switchDo('reduce')"></div>
    <div class="arrow-right" @click.stop="switchDo"></div>
  </div>
</div>
</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 div {
      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>
<div 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>
  <div class="slide-option">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>
  <div class="slide-arrow">
    <div class="arrow-left"></div>
    <div class="arrow-right"></div>
  </div>
</div>
</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开发特效的。今天讲这三个小实例不是说给大家代码,让大家复制粘贴使用,而是希望能起到一个抛砖引玉的作用,拓展思维的作用!就像我之前写文章说得那样,我写文章是希望能起到一个授人以渔的作用,而不是授人以鱼!最后,如果大家觉得有什么地方我写错了,写错不好,或者有其它什么建议,欢迎指出!让大家相互学习,共同进步!也希望大家多多支持三水点靠木!!!

Javascript 相关文章推荐
js实现可拖动DIV的方法
Dec 17 Javascript
JavaScript检查数字是否为整数或浮点数的方法
Jun 09 Javascript
JavaScript和jQuery获取input框的绝对位置实现方法
Oct 13 Javascript
微信公众号支付H5调用支付解析
Nov 04 Javascript
微信小程序 wx.uploadFile无法上传解决办法
Dec 14 Javascript
浅析JS中常用类型转换及运算符表达式
Jul 23 Javascript
原生js FileReader对象实现图片上传本地预览效果
Mar 27 Javascript
微信小程序ajax实现请求服务器数据及模版遍历数据功能示例
Dec 15 Javascript
微信小程序实现图片上传功能实例(前端+PHP后端)
Jan 10 Javascript
jquery实现联想词搜索框和搜索结果分页的示例
Oct 10 jQuery
使用JQuery自动完成插件Auto Complete详解
Jun 18 jQuery
微信小程序 生成携带参数的二维码
Oct 23 Javascript
解读ES6中class关键字
Nov 20 #Javascript
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
Nov 20 #Javascript
Node.js 中使用 async 函数的方法
Nov 20 #Javascript
利用three.js画一个3D立体的正方体示例代码
Nov 19 #Javascript
IE11下使用canvas.toDataURL报SecurityError错误的解决方法
Nov 19 #Javascript
使用DataTable插件实现异步加载数据
Nov 19 #Javascript
原生JavaScript实现Ajax异步请求
Nov 19 #Javascript
You might like
浅析使用Turck-mmcache编译来加速、优化PHP代码
2013/06/20 PHP
php判断手机访问还是电脑访问示例分享
2014/01/20 PHP
详谈PHP文件目录基础操作
2014/11/11 PHP
tp5框架内使用tp3.2分页的方法分析
2019/05/05 PHP
JavaScript中各种编码解码函数的区别和注意事项
2010/08/19 Javascript
Javascript获取HTML静态页面参数传递值示例
2013/08/18 Javascript
js关于命名空间的函数实例
2015/02/05 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
2016/07/12 Javascript
JSON格式的时间/Date(2367828670431)/格式转为正常的年-月-日 格式的代码
2016/07/27 Javascript
详解nodejs 文本操作模块-fs模块(四)
2016/12/22 NodeJs
JS与HTML结合实现流程进度展示条思路详解
2017/09/03 Javascript
Three.js基础学习教程
2017/11/16 Javascript
JS实现图片居中悬浮效果
2017/12/25 Javascript
微信小程序修改swiper默认指示器样式的实例代码
2018/07/18 Javascript
JS数据类型STRING使用实例解析
2019/12/18 Javascript
vue项目打包后请求地址错误/打包后跨域操作
2020/11/04 Javascript
Vue中避免滥用this去读取data中数据
2021/03/02 Vue.js
[00:12]2018DOTA2亚洲邀请赛 Somnus丶M出阵单挑
2018/04/06 DOTA
使用Python制作获取网站目录的图形化程序
2015/05/04 Python
python使用Image处理图片常用技巧分析
2015/06/01 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
利用python画出折线图
2018/07/26 Python
浅谈python 导入模块和解决文件句柄找不到问题
2018/12/15 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
Python使用ElementTree美化XML格式的操作
2020/03/06 Python
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
俄罗斯最大的隐形眼镜销售网站:Ochkov.Net
2021/02/07 全球购物
国贸专业自荐信范文
2014/03/02 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
机关中层领导干部群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
西柏坡观后感
2015/06/08 职场文书
公司处罚决定书
2015/06/24 职场文书
教师教育教学随笔
2015/08/15 职场文书
如何用threejs实现实时多边形折射
2021/05/07 Javascript