Vue实现购物车抛物线动画
前言抛物线动画应用场景较多,在购物车页面比较常见,那么,怎么来实现这样一个动画?先看一下Demo图。实现原理及步骤动态计算每一个加号到购物车的距离;// 加号到顶部的距离let iconTop = this.$refs.banner.$el.clientHeight + this.$refs['goods-' + id][0].offs...
·
前言
抛物线动画应用场景较多,在购物车页面比较常见,那么,怎么来实现这样一个动画?
先看一下Demo图。
实现原理及步骤
- 动态计算每一个加号到购物车的距离;
// 加号到顶部的距离
let iconTop = this.$refs.banner.$el.clientHeight + this.$refs['goods-' + id][0].offsetTop + this.$refs['goods-' + id][0].clientHeight - 6
// 商品列表滚动的距离
const scrollTop = this.$refs.list.scroll.wrapperOffset.top - this.$refs.list.scroll.y + RESERVED_HEIGHT
// 向上滚动
if (scrollTop > 0) {
iconTop = iconTop - scrollTop
}
// 加号到左边的距离
const iconLeft = window.innerWidth - this.$refs['add-' + id][0].clientWidth - 12
const x = iconLeft - this.$refs.cart.offsetLeft - this.$refs.cart.clientWidth / 2
const y = window.innerHeight - (this.$refs.cartView.clientHeight - this.$refs.cart.offsetTop - this.$refs.cart.clientHeight / 2) - iconTop + 10
- 利用css3 动画。translate来做位移,从加号图标按钮到购物车按钮的x、y方向发生的位移距离。rotate做图标旋转,让动画更加真实;
- 根据抛物线方程式y=a*x2,计算出每一个阶段加号图标应该出现的位置;
// 计算a的值
const a = y / (x * x)
- 利用create-keyframe-animation,把计算好的js代码转义成CSS动画代码,并绑定到对应document的node(加号图标)上。
- 动画结束后,进行相关操作。购物车放大缩小一下,价格以及数量增加。
// 取消选择商品
unselectGoods (id) {
this.goodsList.forEach(goods => {
if (goods.id === id && goods.selectCount > 0) {
if (goods.iconDisabled) {
return
}
goods.selectCount--
return 0
}
})
},
// 选择商品
selectGoods (id) {
this.goodsList.forEach(goods => {
if (goods.id === id && goods.selectCount < goods.surplus) {
if (goods.iconDisabled === true) {
return
}
goods.iconDisabled = true
const _self = this
this.paoAnimation(id, function () {
// 抛物线动画结束事件
animations.runAnimation(_self.$refs.cart, 'cartScale')
goods.selectCount++
goods.iconDisabled = false
})
return 0
}
})
},
// 抛物线动画
paoAnimation (id, callback) {
// 加号到顶部的距离
let iconTop = this.$refs.banner.$el.clientHeight + this.$refs['goods-' + id][0].offsetTop + this.$refs['goods-' + id][0].clientHeight - 6
// 商品列表滚动的距离
const scrollTop = this.$refs.list.scroll.wrapperOffset.top - this.$refs.list.scroll.y + RESERVED_HEIGHT
// 向上滚动
if (scrollTop > 0) {
iconTop = iconTop - scrollTop
}
// 加号到左边的距离
const iconLeft = window.innerWidth - this.$refs['add-' + id][0].clientWidth - 12
const x = iconLeft - this.$refs.cart.offsetLeft - this.$refs.cart.clientWidth / 2
const y = window.innerHeight - (this.$refs.cartView.clientHeight - this.$refs.cart.offsetTop - this.$refs.cart.clientHeight / 2) - iconTop + 10
const a = y / (x * x)
let animation = {}
for (let i = 0; i <= 10; i++) {
animation[(i * 10) + '%'] = {transform: `translate(${-i / 10 * x}px, ${(-i / 10 * x) * (-i / 10 * x) * a}px) rotateZ(${360 * (1 - i / 10)}deg)`}
}
animations.registerAnimation({
name: 'move-' + id,
animation,
presets: {
duration: 250,
easing: 'linear',
fillMode: 'forwards',
resetWhenDone: true
}
})
animations.runAnimation(this.$refs['add-' + id][0], 'move-' + id, callback)
},
// 缩放动画
registerScalAnimation () {
const animation = {
'0%': {transform: `scale(1)`},
'25%': {transform: `scale(1.1)`},
'50%': {transform: `scale(1.2)`},
'75%': {transform: `scale(1.1)`},
'100%': {transform: `scale(1)`}
}
animations.registerAnimation({
name: 'cartScale',
animation,
presets: {
duration: 300,
resetWhenDone: true
}
})
},
注意事项
更多推荐
已为社区贡献3条内容
所有评论(0)