zoukankan      html  css  js  c++  java
  • vue.js加入购物车小球动画

    • 生成一个动画小球的div,并且生成五个小球,五个是为了生成一定数量的小球来作为操作使用,按照小球动画的速度,一般来说五个也可以保证有足够的小球数量来运行动画

    • 动画的内容分别是外层和内层,外层控制动画小球的轨道和方向,内层控制动画小球的运行状态

    • 动画使用vue的js钩子实现

    • 因为小球动画只有一个方向(只执行单方向从上到下滚落),所以只用了before-enter,enter,after-enter

    • 用v-show控制小球的可见性,在动画执行期间可见,其余时候隐藏

    • <div class="ball-container">
      <transition name="fade" v-for="ball in balls"
      :key="ball.show"
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter">
      <div class="ball" v-show="ball.show">
      <div class="inner inner-hook"></div>
      </div>
      </transition>
      </div>
      • 设置了balls数组来代表五个小球

      • 设置了dropBalls数组正在运行的小球

    data() {
    return {
    bar: '',
    balls: [
    {
    show: false
    },
    {
    show: false
    },
    {
    show: false
    },
    {
    show: false
    }
    ],
    dropBalls: []
    }
    }
        • 只要触发了drop事件,不止是drop事件里面的代码会执行,另外几个vue的js监听钩子也会一起按顺序执行

          • 触发了drop事件

          • beforeEnter开始执行

          • enter开始执行

          • afterEnter开始执行

        • drop事件的触发可以通过点击cartcontrol组件的添加小球按钮addCart事件触发使用$emit,也可以父组件this.$refs.shopcart.drop(target);直接触发

          • 这么做的目的是实现,在子组件cartcontrol点击之后,可以将该dom传给父组件goods然后再传给子组件shopcart,(因为目前他们之间的通道就是这样,shopcart子组件并没有导入cartcontrol子组件,所以没有直接通讯)这样就实现了多个组件之间的通讯,从而可以实现需求,例如这里就是实现点击子组件cartcontrol后添加一个动画,将小球滑落到另外一个组件shopcart

        • $emit是触发当前实例上的事件。附加参数都会传给监听器回调。

    methods: {
    drop(el) {
    console.log('子组件检测到了', el)
    for (let i = 0; i < this.balls.length; i++) {
    let ball = this.balls[i]
    if (!ball.show) { // 将false的小球放到dropBalls
    ball.show = true
    ball.el = el // 设置小球的el属性为一个dom对象
    this.dropBalls.push(ball)
    return
    }
    }
    },
    beforeEnter(el) { // 这个方法的执行是因为这是一个vue的监听事件
    console.log('小球进入以前', 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) // 负数,因为是从左上角往下的的方向
    console.log(x, y)
    el.style.display = '' // 清空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-hook类来单纯被js操作
    inner.style.webkitTransform = `translate3d(${x}px,0,0)`
    inner.style.transform = `translate3d(${x}px,0,0)`
    }
    }
    },
    enter(el, done) { // 这个方法的执行是因为这是一个vue的监听事件
    console.log('小球进入中', el)
    /* eslint-disable no-unused-vars */
    let rf = el.offsetHeight // 触发重绘html
    this.$nextTick(() => { // 让动画效果异步执行,提高性能
    el.style.webkitTransform = 'translate3d(0,0,0)'
    el.style.transform = 'translate3d(0,0,0)'
    // 处理内层动画
    let inner = el.getElementsByClassName('inner-hook')[0] // 使用inner-hook类来单纯被js操作
    inner.style.webkitTransform = 'translate3d(0,0,0)'
    inner.style.transform = 'translate3d(0,0,0)'
    el.addEventListener('transitionend', done) // Vue为了知道过渡的完成,必须设置相应的事件监听器。
    })
    },
    afterEnter(el) { // 这个方法的执行是因为这是一个vue的监听事件
    console.log('小球进入完成', el)
    let ball = this.dropBalls.shift() // 完成一次动画就删除一个dropBalls的小球
    if (ball) {
    ball.show = false
    el.style.display = 'none' // 隐藏小球
    }
    }
    }
    • 关于transitionend

    • 关于drop方法,是实现每一个ball的show属性和el属性处理,并且点击一次会自动将一个小球放到dropBalls数组里面,放到里面就代表的是一个小球已经被开始执行动画,但是由于动画是异步的,所以先主动设置.

    • 关于getBoundingClientRect(位移的计算是从左上角开始)

      • 使用getBoundingClientRect获取到当前元素的坐标,然后需要位移的left减去元素的宽获取真正的最终位移x坐标

      • 使用getBoundingClientRect获取到当前元素的坐标,然后需要当前屏幕的高度减去元素的top再减去元素本身的高度获取到真正的最终位移y坐标,并且这个是负数,因为是从左上角往下的方向

    • 关于html重绘

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

    关于cubic-bezier(0.49, -0.29, 0.75, 0.41),是动画抛物曲线(贝塞尔曲线)的配置,基于css3实现,http://cubic-bezier.com/#.17,.67,.83,.67,参考贝塞尔曲线与CSS3动画、SVG和canvas的基情 ,至于抛物线放在外层就是为了控制内层的元素的轨道和方向的.

    原文地址:http://www.cnblogs.com/yuxingyoucan/p/7063881.html

  • 相关阅读:
    这两天又是一次巨大的飞跃
    防范式编程:
    泛型那点儿事儿 泛型概述 简单样例代码
    FindPrivateKey X509
    Remoting Generic Async Queue (Release 3) 不受 Remoting 对象生存期过期约束
    AntiXSS Library v3.0
    X509 static RSACryptoServiceProvider 高并发加解密
    EncodingHelper Identify Encoding by BOM
    NetStatTool
    EditPlus 于 20090602 升级到 v3.11(340)
  • 原文地址:https://www.cnblogs.com/karila/p/7601807.html
Copyright © 2011-2022 走看看