基于vue的仿饿了么关于小球动画第一次出现

来源:互联网 发布:数据统计分析师证书 编辑:程序博客网 时间:2024/06/08 07:11
这几天看到了基于vue仿饿了么购物车小球动画这一章,我的项目是基于vue2.x写的,所以视频里基于vue1.x的写法不适合我,于是按照文档改成了2.x版本的写法,这个动画的方式采用两层,一层是.ball的运动,一层是.inner的运动,可以将其写成一层只有.ball运动的写法,只需改变部分代码就行了,代码在注释里,记得样式代码也要改。

刚开始将视频里的代码改成了如下格式:

<div class="ball-container">        <transition-group name="drop"           @before-enter="beforeEnter"          @enter="enter"          @after-enter="afterEnter">          <div class="ball"  v-for="(ball,index) in balls" v-bind:key="index" v-show="ball.show">            <div class="inner inner-hook"></div>          </div>        </transition-group>      </div>

transition-group是vue文档中用于列表过渡的,在这里的小球虽然是用v-for遍历出来的,但是运动时候还是单个单个的运动,用transition-group是可以写出来的,还是将它改成了如下代码,使之成为单个运动的方式:

<div class="ball-container" v-for="ball in balls">       <transition           v-on:before-enter="beforeEnter"          v-on:enter="enter"          v-on:after-enter="afterEnter"          name="drop">         <div class="ball" v-show="ball.show">             <div class="inner inner-hook">             </div>         </div>       </transition>    </div>

stylus代码如下:

.ball-container      .ball        position: fixed        left: 32px        bottom: 22px        z-index: 200        transition: all 0.4s linear        .inner          width: 16px          height: 16px          border-radius: 50%          background: rgb(0, 160, 220)          transition: all 0.4s linear

js代码如下,注意:
v-on:before-enter=”beforeEnter”
v-on:enter=”enter”
v-on:after-enter=”afterEnter”这是触发钩子函数的代码,必须要,具体的方法写在methods里:

drop(el) {       for (let i = 0; i < this.balls.length; i++) {         let ball = this.balls[i];         if (!ball.show) {           ball.show = true;           ball.el = el;           this.dropBalls.push(ball);           return;         }       }     },    beforeEnter: function (el) {      let count = this.balls.length;      while (count--) {        let ball = this.balls[count];        if (ball.show) {          /*获取加号的位置(小球动画开始的位置)*/          let rect = ball.el.getBoundingClientRect();                     let x = rect.left - 32;          let y = -(window.innerHeight - rect.top - 22);          /*注释部分为动画为一层时代码*/           /*el.style.display = '';*/           /*el.style.webkitTransform=`translate3d(${x}px,${y}px,0)`;*/           /*el.style.transform = `translate3d(${x}px, ${y}px, 0)`;*/          el.style.display = '';          el.style.webkitTransform = `translate3d(0, ${y}px, 0)`;          el.style.transform = `translate3d(0, ${y}px, 0)`;          /*内层动画(这个动画在这里被分成两层,也可以一层)*/          let inner = el.getElementsByClassName('inner-hook')[0];          inner.style.webkitTransform = `translate3d(${x}px, 0, 0)`;          inner.style.transform = `translate3d(${x}px, 0, 0)`;        }      }    },    enter: function (el, done) {      /* eslint-disable no-unused-vars */       let rf = el.offsetHeight;                 /*触发浏览器重绘;*/      this.$nextTick(() => {        el.style.webkitTransform = 'translate3d(0, 0, 0)';        el.style.transform = 'translate3d(0, 0, 0)';        let inner = el.getElementsByClassName('inner-hook')[0];        inner.style.webkitTransform = 'translate3d(0, 0, 0)';        inner.style.transform = 'translate3d(0, 0, 0)';        el.addEventListener('transitionend', done);      });    },    afterEnter: function (el) {       let ball = this.dropBalls.shift();       if (ball) {           ball.show = false;           el.style.display = 'none';       }    }
原创粉丝点击