思路:  

1.因页面分组件分的比较细,由图可知是组件5到组件4的联动. 如果利用组件间通信需要 子组件5 -->组件3-->所有组件的父组件-->组件4, 层级略显复杂,所以使用了vuex状态管理管理数据.

2.动画处理:

利用vue的 transition 标签来处理动画.

小球运动的轨迹是一条抛物线, 可使X轴做匀速运动, Y轴贝塞尔曲线, 可以考虑设定两个嵌套的DOM来控制运行轨迹.外层控制Y轴动画, 内层控制X轴动画.

因小球落点是同一个位置, 可以将小球设定到落点位置, 动态获取初始值来决定小球的运动轨迹.

3.如果连续点击小球, 则页面上可能显示多个小球, 所以需要设置多个小球保证页面上可以显示多个小球.

结构图:

html (Ball.vue) :

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

css (Ball.vue):

      .ball-container
.ball
position fixed
left .64rem
bottom .44rem
z-index 200
width .32rem
height .32rem
border-radius 50%
// background rgb(0, 160, 220)
&.drop-enter-active
transition: all .4s cubic-bezier(0.49, -0.29, 0.75, 0.41)
.inner
width .32rem
height .32rem
border-radius 50%
background rgb(0, 160, 220)
transition: all .4s linear

js (Ball.vue)

  computed: {
...mapState({
balls: state => state.balls.balls,
dropBall: state => state.balls.dropBall
})
},
methods: {
...mapMutations(['changeShow', 'changeDropBall']),
beforeEnter (el) {
let count = this.balls.length
while (count--) {
let ball = this.balls[count]
if (ball.show) {
//getBoundingClientRect返回值是一个 DOMRect 对象, 此包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。
//除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
let rect = ball.el.getBoundingClientRect()
let x = rect.left - 32
let y = -(window.innerHeight - rect.top - 22)
//小球外层控制y轴的运动轨迹,translate3d()可以开启硬件加速
el.style.display = ''
el.style.webkitTransform = `translate3d(0, ${y}px, 0)`
el.style.transform = `translate3d(0, ${y}px, 0)`
//内层小球控制x轴运动轨迹,内外层运动方式是不一样的, y轴贝塞尔曲线, x轴匀速.
let inner = el.getElementsByClassName('inner-hook')[0]
inner.style.webkitTransform = `translate3d(${x}px, 0, 0)`
inner.style.transform = `translate3d(${x}px, 0, 0)`
}
}
},
enter (el) {
// 触发浏览器重绘
/* 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)`
})
},
afterEnter (el) {
// 删除数组第一个元素, 并返回第一个元素,因对象都是指向地址,所以操作dropBall数组也就操作了balls数组
let ball = this.dropBall.shift()
if (ball) {
ball.show = false
el.style.display = 'none'
}
}
}

store里面的moudle (balls.js):

const balls = {
state: {
balls: [{
show: false
}, {
show: false
}, {
show: false
}, {
show: false
}, {
show: false
}],
dropBall: []
},
mutations: {
changeShow (state, {index, isShow, el}) {
state.balls[index].show = isShow
state.balls[index].el = el
},
changeDropBall (state, ball) {
state.dropBall.push(ball)
}
}
} export default balls

增加商品数量(即点击+号)触发小球动画的页面 (Cartcontrol.vue):

  computed: {
...mapState({
balls: state => state.balls.balls
})
},
methods: {
...mapMutations(['changeShow', 'changeDropBall']),
addCart (event) {
for (let i = 0; i < this.balls.length; i++) {
if (!this.balls[i].show) {
this.changeShow({index: i, isShow: true, el: event.target})
this.changeDropBall(this.balls[i])
return
}
}
}
}

此DOME是根据参考黄轶老师的仿饿了吗课程改编而来~

Vue实现购物车小球动画的更多相关文章

  1. 使用vue模拟购物车小球动画

    使用vue模拟购物车小球动画 1.效果演示 2.相关代码 <!DOCTYPE html> <html lang="en"> <head> < ...

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

    生成一个动画小球的div,并且生成五个小球,五个是为了生成一定数量的小球来作为操作使用,按照小球动画的速度,一般来说五个也可以保证有足够的小球数量来运行动画 动画的内容分别是外层和内层,外层控制动画小 ...

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

    在线观看贝塞尔曲线值:传送门 在线观看动画效果:传送门 代码: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  4. Vue实现购物小球抛物线

    .shop{ position: fixed; top: 300px; left: 40px; } .ball{ position: fixed; left: 32px; bottom: 22px; ...

  5. vue 2.0 购物车小球抛物线

    备注:此项目模仿 饿了吗.我用的是最新的Vue, 视频上的一些写法已经被废弃了. 布局代码 <div class="ball-container"> <trans ...

  6. “完美”解决微信小程序购物车抛物动画,在连续点击时出现计算错误问题,定时器停不下来。

    最近做,微信点餐小程序,遇到添加商品时出现抛物动画,参考借鉴了这位大神的方法 https://www.cnblogs.com/greengage/p/7815842.html 但出现了一个问题,连续点 ...

  7. 基于jquery fly插件实现加入购物车抛物线动画效果,jquery.fly.js

    在购物网站中,加入购物车的功能是必须的功能,有的网站在用户点击加入购物车按钮时,就会出现该商品从点击出以抛物线的动画相似加入购物车,这个功能看起来非常炫,对用户体验也有一定的提高.下面介绍基于jque ...

  8. vue中使用js动画与velocity.js

    一:vue中使用js动画 根据上一篇安装animate.css之后 vue中有动画的钩子函数,@before-enter是内容由无到有的时候自动监听触发的函数,函数会接收到参数el,这样可以动态设置样 ...

  9. 基于jQuery加入购物车飞入动画特效

    基于jQuery加入购物车飞入动画特效.这是一款电商购物网站常用的把商品加入购物车代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div id="main& ...

随机推荐

  1. gitlab提交代码

    cd existing_foldergit initgit remote add origin http://10.26.1.9/root/yunlian.gitgit add .git commit ...

  2. nvm 淘宝镜像

    找到里面的settings.txt node_mirror: https://npm.taobao.org/mirrors/node/npm_mirror: https://npm.taobao.or ...

  3. MAC OS X&Vmware

    推出共享文件恢复解决办法: 将/Volumes/VMware shared Folders 文件删除(此时这个文件中的内容为乱码) ,生成一个 VMware shared Folders文件夹,重新设 ...

  4. 【JVM】-NO.115.JVM.1 -【JDK11 HashMap详解-4-伸展树、B树】

    .Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...

  5. XMLHttpRequest请求被劫持

    十几个请求中随机一个转到 <html><head><script language="javascript">setTimeout(" ...

  6. PHP----------用curl方式请求接口在同一个项目里面的时候不能请求的情况

    1.环境是wnmp 2.NGINX中,看PHP文件块fastcig-pass的设置值(127.0.0.1:9000).设置都是以keepalive方式请求,接收到PHP文件时,交于后端过程PHPCGI ...

  7. 发布自己的npm包、开源项目

    背景:由于最近在做项目之余想做一些其他的事,所以东找找西找找的,最后决定写一个封装一些常用原型方法的NPM包,但不仅限于此.话不多说,说一下实践过程. 一.注册NPM及如何上传NPM包参考连接:htt ...

  8. 【转】python虚拟环境--virtualenv

    virtualenv 是一个创建隔绝的Python环境的工具.virtualenv创建一个包含所有必要的可执行文件的文件夹,用来使用Python工程所需的包. 安装 pip install virtu ...

  9. python SyntaxError: Non-ASCII character '\xe6' in file

    [1]python程序执行报错 报错:SyntaxError: Non-ASCII character '\xe6' in file /tmp/788580473/main.py on line 7, ...

  10. flask_mail发送163邮件,报553错误的原因

    最近在练习用flask_mail发送163邮件时报错: reply: '553 authentication is required,163 smtp9,DcCowAD3eEQZ561caRiaBA- ...