vue.js加入购物车小球动画

http://www.cnblogs.com/yuxingyoucan/p/7063881.html

  • 生成一个动画小球的div,并且生成五个小球,五个是为了生成一定数量的小球来作为操作使用,按照小球动画的速度,一般来说五个也可以保证有足够的小球数量来运行动画
  • 动画的内容分别是外层和内层,外层控制动画小球的轨道和方向,内层控制动画小球的运行状态
  • 动画使用vue的js钩子实现
  • 因为小球动画只有一个方向(只执行单方向从上到下滚落),所以只用了before-enter,enter,after-enter
  • 用v-show控制小球的可见性,在动画执行期间可见,其余时候隐藏
  • <div class="ball-container">
            <transition name="fade" v-for="ball in balls" :key="ball" @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 {
        balls: [
          {
            show: false
          },
          {
            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) {
      //触发一次事件就会将所有小球进行遍历
        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的监听事件
        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 = ‘‘; //清空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的监听事件
        /* 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的监听事件
        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的基情 ,至于抛物线放在外层就是为了控制内层的元素的轨道和方向的.

参考自https://segmentfault.com/a/1190000009294321

时间: 2024-08-25 11:16:13

vue.js加入购物车小球动画的相关文章

VUE.JS实现购物车功能

购物车是电商必备的功能,可以让用户一次性购买多个商品,常见的购物车实现方式有如下几种: 1. 用户更新购物车里的商品后,页面自动刷新. 2. 使用局部刷新功能,服务器端返回整个购物车的页面html 3. 服务器端返回JSON格式,使用模板引擎+dom操作更新页面 最近新学习了vue.js,一个轻量级的mvvm(Model-View-ViewModel),vue.js是数据驱动无须操作dom,它提供特殊的html语言,把dom和数据绑定在一起,一旦修改了数据,dom将会自动更新更新. 关于vue.

vue.js实战——购物车练习(包含全选功能)

vue.js实战第5章 54页的练习1 直接放代码好了,全选的部分搞了好久,代码好像有点啰嗦,好在实现功能了(*^▽^*) HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-sca

js加入购物车抛物线动画

天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo 一开始没有想到用抛物线函数去做,也已经忘记还有这么个函数了,想着抛物线本质上就是向右和向上方向各有一个速度(就上面的demo而言),向右的速度匀速,向上的速度递减,减到0后再反方向递增,元素的left和top值随时间递增而改变,元素运动轨迹就是抛物线,这个思路不具备通用性,实现也比较复杂,放弃了. 之后参考了张鑫旭用抛物线函数的实现方式和愚人码头的改进,豁然开朗

css贝塞尔曲线模仿饿了么购物车小球动画

在线观看贝塞尔曲线值:传送门 在线观看动画效果:传送门 代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> <style> html{ widt

Vue.js 简单购物车开发

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

vue.js 实现购物车加减方法

<template> <div class="coutter-wrapper"> <button type="button" @click="plus">+</button> <button type="button">{{ result }}</button> <button type="button" @click="

Vue.js 高仿饿了么外卖APP

第1章 课程简介介绍课程的学习目标和学习内容.1-1 课程简介1-2 课程安排 第2章 Vuejs介绍从前端开发趋势分析开始,引入 MVVM 开发框架和 Vue.js,接着对比流行框架Angular 和 React,最后详细介绍 Vue.js 的核心思想-数据驱动和组件化.2-1 Vuejs介绍-近年来前端开发趋势2-2 Vuejs介绍-MVVM框架2-3 Vuejs介绍-什么是Vuejs及Vuejs生态2-4 Vuejs介绍-对比Angular.React2-5 Vuejs介绍-Vuejs核心

Vue.js高仿饿了么外卖App 2016最火前端框架

第1章 课程导学(二期)-15号开放 包括课程概述.核心模块.核心技术.课程安排.课程收获.讲授方式.学习前提等方面的介绍,最后演示了整个外卖App的功能,让同学们对课程项目有一个直观的了解. 1-1 导学(必看) 第2章 项目准备工作(二期)-15号开放 包括项目需求分析.Vue-cli 3.0 脚手架介绍.cube-ui 介绍.目录模块分析.api 接口 mock 等. 2-1 Vue-cli 3.0 介绍 2-2 目录介绍 & cube-ui 安装 2-3 api 接口 mock 第3章

Vue.js高仿饿了么外卖App 前端框架Vue.js 1.0升级2.0

课程目录:第1章 课程简介介绍课程的学习目标和学习内容.第2章 Vuejs介绍从前端开发趋势分析开始,引入 MVVM 开发框架和 Vue.js,接着对比流行框架Angular 和 React,最后详细介绍 Vue.js 的核心思想-数据驱动和组件化.第3章 Vue-cli 开启 Vuejs 项目介绍 Vue 项目的脚手架,如何安装,对脚手架生成的目录文件做介绍,介绍 Vue 组件的编写方法,最后运行 demo 项目并介绍 webpack 构建脚本来说明 demo 的运行原理.第4章 项目实战-准