Vue实现购物车小球动画
思路:
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实现购物车小球动画的更多相关文章
- 使用vue模拟购物车小球动画
使用vue模拟购物车小球动画 1.效果演示 2.相关代码 <!DOCTYPE html> <html lang="en"> <head> < ...
- vue.js加入购物车小球动画
生成一个动画小球的div,并且生成五个小球,五个是为了生成一定数量的小球来作为操作使用,按照小球动画的速度,一般来说五个也可以保证有足够的小球数量来运行动画 动画的内容分别是外层和内层,外层控制动画小 ...
- css贝塞尔曲线模仿饿了么购物车小球动画
在线观看贝塞尔曲线值:传送门 在线观看动画效果:传送门 代码: <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- Vue实现购物小球抛物线
.shop{ position: fixed; top: 300px; left: 40px; } .ball{ position: fixed; left: 32px; bottom: 22px; ...
- vue 2.0 购物车小球抛物线
备注:此项目模仿 饿了吗.我用的是最新的Vue, 视频上的一些写法已经被废弃了. 布局代码 <div class="ball-container"> <trans ...
- “完美”解决微信小程序购物车抛物动画,在连续点击时出现计算错误问题,定时器停不下来。
最近做,微信点餐小程序,遇到添加商品时出现抛物动画,参考借鉴了这位大神的方法 https://www.cnblogs.com/greengage/p/7815842.html 但出现了一个问题,连续点 ...
- 基于jquery fly插件实现加入购物车抛物线动画效果,jquery.fly.js
在购物网站中,加入购物车的功能是必须的功能,有的网站在用户点击加入购物车按钮时,就会出现该商品从点击出以抛物线的动画相似加入购物车,这个功能看起来非常炫,对用户体验也有一定的提高.下面介绍基于jque ...
- vue中使用js动画与velocity.js
一:vue中使用js动画 根据上一篇安装animate.css之后 vue中有动画的钩子函数,@before-enter是内容由无到有的时候自动监听触发的函数,函数会接收到参数el,这样可以动态设置样 ...
- 基于jQuery加入购物车飞入动画特效
基于jQuery加入购物车飞入动画特效.这是一款电商购物网站常用的把商品加入购物车代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div id="main& ...
随机推荐
- python使用suds调用webservice接口
最近做接口对接,遇到了.net开发的webservice接口,因为python第一次与webservice对接,连问带查,最后使用suds库来实现了 1.安装suds mac: sudo pip in ...
- Codeforces 455A - Boredom - [DP]
题目链接:https://codeforces.com/problemset/problem/455/A 题意: 给出一个 $n$ 个数字的整数序列 $a[1 \sim n]$,每次你可以选择一个 $ ...
- Redis的数据结构之List
存储list: ArrayList使用数组方式 LinkedList使用双向链接方式 双向链接表中增加数据 双向链接表中删除数据 存储list常用命令 两端添加 两端弹出 扩展命令 lpush 方式添 ...
- Open_stack 有虚拟机端口不通的问题
原因:流量表 解决办法:not修改流量表(容易出错,出错后果更严重):is迁移虚拟机这样会对应生成新的流量表,然后问题就解决了.
- 接口测试工具-Jmeter使用笔记(七:用户定义的变量)
使用场景:一组API根据业务流程制作成测试脚本,想要移植到其他测试环境时,由于数据库发生了变更,有些初始化数据也相应发生了变化,例如环境地址.请求路径等等.博主甚至把服务器地址和接口的部分共同请求路径 ...
- python tkinter button
"""小白随笔,大佬勿喷""" '''Button按钮 点击执行对应的命令''' import tkinter as tk #初始化窗口 w ...
- 关于${pageContext.request.contextPath}的理解 (转载)
${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> . 也就是取出部署的应用程 ...
- jQuery-form实现文件分步上传
分步上传:当你需要提交两个及以上的文件,在一个文件成功后再提交另一个文件,并且最后需要提交所有文件的地址组成的数据 HTML: <form id="uploadVideoForm&qu ...
- 数据库SQL的分组函数
分组函数:(五个) 1···max(expr):求expr的最大值 }\ 2···min(expr):求expr的最小值 }-- 数据类型是有规定的 3···sum(expr):求expr的总和 }- ...
- 【软件工程1916|W(福州大学)_助教博客】团队第一次作业成绩公示
题目 第一次作业 评分准则: 队名(最好能够体现项目内容,要求有亮点与个性):(1分) 拟作的团队项目描述:一句话(中英文不限):(1分) 队员风采:介绍每一名队员,包括成员性格.擅长的技术.编程的兴 ...