首頁  >  文章  >  web前端  >  詳解vue、css3如何實現互動特效

詳解vue、css3如何實現互動特效

小云云
小云云原創
2017-12-18 14:59:481610瀏覽

本文主要介紹了詳解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:&#39;#text&#39;,
    data:{
      nowIndex:0,
      testText:&#39;欢迎浏览&#39;
    },
    mounted(){
      let _this=this;
      let timer = setInterval(function(){
        _this.nowIndex++;
        switch (_this.nowIndex) {
          case 1:
            _this.testText = &#39;守候的文章&#39;;
            break;
          case 2:
            _this.testText = &#39;愿您浏览愉快&#39;;
            break;
          case 3:
            _this.testText = &#39;学到知识&#39;;
            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(&#39;h1&#39;),nowIndex=0;
  console.log(oH1)
  var timer = setInterval(function () {
    nowIndex++;
    switch (nowIndex) {
      case 1:
        oH1.innerHTML = &#39;守候的文章&#39;;
        break;
      case 2:
        oH1.innerHTML = &#39;愿您浏览愉快&#39;;
        break;
      case 3:
        oH1.innerHTML = &#39;学到知识&#39;;
        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="{&#39;transform&#39;:&#39;translate3d(&#39;+nowIndex*100+&#39;px,0,0)&#39;}"></p>
</p>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
  new Vue({
    el:&#39;#nav&#39;,
    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=&#39;translate3d(0,0,0)&#39;;
  })
  for(var i=0;i<oLi.length;i++){
    oLi[i].index=i;
    oLi[i].addEventListener("mouseenter",function (e) {
      oSlider.style.transform=&#39;translate3d(&#39;+this.index*100+&#39;px,0,0)&#39;;
    })
  }
</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="{&#39;width&#39;:(listWidth*list.length)+&#39;px&#39;,&#39;transform&#39;:&#39;translate3d(-&#39;+(listWidth*nowIndex)+&#39;px,0,0)&#39;}">
    <!--遍历出来的图片-->
    <li v-for="(li,index) in list" :style="{&#39;width&#39;:listWidth+&#39;px&#39;}">
      <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="{&#39;active&#39;:index===nowIndex}"></span>
  </p>
  <p class="slide-arrow">
    <p class="arrow-left" @click.stop="switchDo(&#39;reduce&#39;)"></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: &#39;#slide-img&#39;,
    data: {
      nowIndex: 0,
      listWidth: &#39;1000&#39;,
      list: [&#39;./images/timg1.jpg&#39;, &#39;./images/timg2.jpg&#39;, &#39;./images/timg3.jpg&#39;, &#39;./images/timg4.jpg&#39;],
      timer:null
    },
    methods: {
      //滑动操作
      switchDo(reduce){
        clearInterval(this.timer);
        //根据reduce判断this.nowIndex的增加或者减少!
        if(reduce===&#39;reduce&#39;){
          //如果是第一张,就返回最后一张
          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(&#39;#slide-img-ul&#39;);
    var oLi=oUl.querySelectorAll(&#39;li&#39;);
    var oSpan=document.querySelector(&#39;.slide-option&#39;).querySelectorAll(&#39;span&#39;);
    var oArrowLeft=document.querySelector(&#39;.arrow-left&#39;);
    var oArrowRight=document.querySelector(&#39;.arrow-right&#39;);
    oUl.style.width=&#39;4000px&#39;;
    oArrowLeft.addEventListener(&#39;click&#39;,function () {
      switchDo(&#39;reduce&#39;);
    })
    oArrowRight.addEventListener(&#39;click&#39;,function () {
      switchDo();
    })
    var timer=null,nowIndex=0;
    function switchDo(reduce){
      clearInterval(timer);
      //设置样式
      oUl.style.transform=&#39;translate3d(-&#39;+(1000*nowIndex)+&#39;px,0,0)&#39;;
      for (var i=0;i<oSpan.length;i++){
        if(i===nowIndex){
          oSpan[i].className=&#39;active&#39;;
        }
        else{
          oSpan[i].className=&#39;&#39;;
        }
      }
      //根据reduce判断this.nowIndex的增加或者减少!
      if(reduce===&#39;reduce&#39;){
        //如果是第一张,就返回最后一张
        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开发特效的。

相关推荐:

vue项目的构建,打包,发布详解

vue数组更新方法详解

实用的vue.js项目中小技巧汇总

以上是詳解vue、css3如何實現互動特效的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn