前言
加入购物车动画最终效果
准备
准备一张购物车图片,如下
实现
实现这个效果主要就是用小程序提供的动画相关的API,如果你对小程序动画相关的API还不了解,可以移步官方教程:微信小程序动画官方教程
原理
- 右下角放一个购物车的icon,然后设置position为fixed,让购物车按钮浮动在content上。
- 页面上放置一个position为fixed的飞行点,也就是上图中的绿色点,默认隐藏。
- 在页面渲染完成之后获取购物车在页面中的坐标。
- 通过tap事件获取到tap点的坐标,将步骤2中的飞行点移动到点击处。
- 通过小程序动画相关的API(Animation.left和Animation.top)来执行动画到购物车处。
废话少说, 直接上代码
index.wxml布局
<view class="container">
<view wx:for='12345678901234567' class="item" bindtap="addshopcar" hover-class="hover">
商品{{index}}
</view>
</view>
<view class="dot" animation='{{ani}}' hidden="{{!showdot}}">+1</view>
<view class="count">{{count}}</view>
<view class="shopcar" id="shopcar">
<image src="/images/shopcar.png" class="shopcarimg"></image>
</view>
index.wxss样式
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
.item {
width: 720rpx;
height: 100rpx;
display: flex;
flex-direction: row;
align-items: center;
font-weight: bold;
padding-left: 30rpx;
border-bottom: 1rpx solid #efeff4;
}
.hover {
background: #d9d9db;
}
.dot {
top: 0;
left: 0;
position: fixed;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: #1dae01;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 24rpx;
color: white;
}
.shopcar {
position: fixed;
right: 40rpx;
bottom: 60rpx;
}
.shopcarimg {
width: 48rpx;
height: 48rpx;
}
.count {
color: red;
position: fixed;
font-weight: bold;
right: 30rpx;
bottom: 100rpx;
}
index.js逻辑实现
//方便引用自身
var that
Page({
data: {
//购物车x坐标
animationx: 0,
//购物车y坐标
animationy: 0,
//是否显示飞行物,默认不显示
showdot: false,
//动画对象
ani: {},
//商品记数
count: 0
},
onLoad(options) {
that = this
},
onReady() {
//页面渲染完后获取购物车在页面中的坐标
const query = wx.createSelectorQuery()
query.select('#shopcar').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function (res) {
let point = res[0]
//坐标修正,让飞行物可以正好落在购物车正中心,20是飞行物宽度一半然后转化成px
var xtemp = (point.left + point.right) / 2 - 20 / 750 * wx.getSystemInfoSync().windowWidth
var ytemp = (point.top + point.bottom) / 2 - 20 / 750 * wx.getSystemInfoSync().windowWidth
console.log('xtemp : ' + xtemp + ' ytemp : ' + ytemp)
that.setData({
//获取修正后坐标
animationx: xtemp,
animationy: ytemp
})
})
},
addshopcar(e) {
if (that.data.showdot == true) {
return
}
//获取点击点坐标
var touches = e.touches[0]
//坐标修正,同上,这么做是为了让飞行点落到点击的中心
let toptemp = touches.clientY - 20 / 750 * wx.getSystemInfoSync().windowWidth
let lefttemp = touches.clientX - 20 / 750 * wx.getSystemInfoSync().windowWidth
console.log('toptemp : ' + toptemp + ' lefttemp : ' + lefttemp)
var animation1 = wx.createAnimation({
duration: 0,
timingFunction: 'ease'
})
//通过极短的时间让飞行点移动到手指点击位置,同时让飞行点显示出来
animation1.left(lefttemp).top(toptemp).step()
that.setData({
ani: animation1.export(),
showdot: true
})
//然后让飞行点飞行到购物车坐标处,形成添加效果
setTimeout(function () {
const animation = wx.createAnimation({
duration: 500,
timingFunction: 'cubic-bezier(0,-0.66,.58,1)'
})
//通过Animation的left和top这两个API,将飞行点移动到购物车坐标处
animation.left(that.data.animationx).top(that.data.animationy).step()
that.setData({
ani: animation.export()
})
setTimeout(function () {
var counttemp = that.data.count + 1
that.setData({
showdot: false,
ani: null,
count: counttemp
})
}.bind(this), 520)//这里也是要稍微延后,后隐藏飞行点,然后清除动画,增加购物计数器
}, 5)//注意这里要稍微延后,保证前面移动到手指点击处的动画完成
}
})
网友评论