人生中第一次写博客,写的很差,各位大佬多多包涵。。。 话很少说,效果图以下:css
我是用一个游离的view标签来作的,这个view采用fixed定位,默认top: 0; left: 0;css3
注:文中的游离view均指动画播放发生运动的view,即下面的图片中红色箭头所指的元素git
当点击加号的时候,会发生如下操做:github
获取当前点击加号的位置信息,计算出top值和left值,并将这个游离的view定位到当前点击的位置,这是动画开始位置面试
计算出左下角购物车距离顶端的left, top值,这是动画结束位置小程序
而后使用css3动画,使其移动从开始位置移动到结束位置,left, top, opacity同时发生变化bash
Tips: 至于为何不用小程序自带的wx.createAnimation呢?是由于使用这个播放一次动画以后,不能清除样式,第二次加入购物车游离view不能正确设置top, left值,好苦恼。。。css3动画
这个飞入效果是css3实现的,因此其它的也能够用,不局限于小程序,就是获取top, left的地方各有不一样xss
接下来分布介绍:工具
步骤一: 获取当前点击加号的top, left值
获取当前点击加号的top, left值
加入购物车按钮绑定的点击事件为selectGoods
selectGoods(e) {
let that = this;
// 获取当前点击位置距离顶部的高度,即图中标出来的,红色字体写的top值,left值
// top值和left值分别减去40, 是为了使游离的view定位到当前点击位置的左上方,有一种先弹上去,再飞入购物车的感受,这里懒就不用动画了,哈哈
let top = e.detail.y - 40;
let left = e.detail.x - 40;
that.setData({
style: `top: ${top}px;left: ${left}px;`
})
that.playAnimation(e, left, top); // 播放动画
},
复制代码
游离的view样式以下:
<view class="animat" style="{{style}}">
<image class="icon" src="/resources/images/icon_add01.png"></image>
</view>
复制代码
.animat{
position: fixed;
top: 0px;
left: 0px;
}
复制代码
点击加号的时候动态设置style值设置top, left
这一步结束后的效果图以下:
步骤二: 计算出左下角购物车距离顶端的left, top值
小程序有提供获取元素位置的方法,我大概封装了只须要传id的一个方法,方便使用,以下:
quertElementSize(id, callback) {
let query = wx.createSelectorQuery();
query.select('#' + id).boundingClientRect((rect) => {
callback && callback(rect);
}).exec()
}
复制代码
/**
* 获取左下角购物车图标top, left值
*/
quertShoppingCarSize() {
let that = this;
this.quertElementSize('shoppingCar', function (rect) {
that.setData({
'shoppingCarSize.top': rect.top + (rect.height / 2),
'shoppingCarSize.left': rect.left + (rect.width / 2)
})
});
},
复制代码
以下图:
获取元素中心点距离顶部top值,和距离左边left值
因为这个图标的位置的固定的,因此这个位置信息能够提早获取,存储到data中,不用每次加入购物车的时候再算
步骤三: 使用css3动画,使其移动到左下角购物车的位置,left, top, opacity同时发生变化
步骤一和二已经拿到了动画初始位置的top,left值,和结束位置的top, left值
如今只须要用animation,将这个游离view从初始位置移动到结束位置就能够了,代码以下:
/**
* 小球飞入购物车动画
*/
playAnimation(e, left, top) {
let that = this;
this.aniTimer = setTimeout(function () {
that.setData({
style: `--startLeft: ${left}px;--startTop: ${top}px;
--endLeft: ${that.data.shoppingCarSize.left}px;
--endTop: ${that.data.shoppingCarSize.top}px;
animation: runTop .3s cubic-bezier(.66,.1,1,.41), runLeft .3s linear;`
})
}, 5);
that.setDataAddShoppingCar(e);
},
复制代码
这里解释一下:
setTimeout(function(){
console.log(1);
})
console.log(2);
// 输入结果为 2 1
复制代码
CSS代码: 动态获取开始位置top, left值和结束位置top,left值
@keyframes runTop {
0%{
top: var(--startTop);
opacity: 1;
}
90%{
opacity: 1;
}
100%{
top: var(--endTop);
opacity: 0;
}
}
@keyframes runLeft {
0%{
left: var(--startLeft);
opacity: 1;
}
90%{
opacity: 1;
}
100%{
left: var(--endLeft);
opacity: 0;
}
}
复制代码
/**
* 更新数据
*/
setDataAddShoppingCar(e) {
let that = this;
let index = e.currentTarget.dataset.index;
let data = that.data.nowShowData[index];
data.isSelect = true;
let nowSelectData = that.data.nowSelectData;
let tag = 'nowShowData[' + index + '].isSelect';
nowSelectData.push(data);
that.setData({
[tag]: true,
nowSelectData: nowSelectData
});
},
复制代码
到这里,飞入购物车效果就完成了,鼓掌👏
这里就使用的是wx.createAnimation
代码以下:
/**
* 购物车列表弹起
*/
transShoppingCar() {
let that = this;
if (this.data.nowSelectData.length === 0) {
wx.showToast({
title: '购物车内没有商品哦~',
icon: 'none',
duration: 1500
})
return;
}
let shoppingCarIsShow = that.data.shoppingCarIsShow;
shoppingCarIsShow = !shoppingCarIsShow;
var animation = wx.createAnimation({
duration: 500,//动画的持续时间 默认400ms 数值越大,动画越慢 数值越小,动画越快
timingFunction: 'ease',//动画的效果 默认值是linear
});
this.animation = animation;
if (shoppingCarIsShow) {
this.setData({
shoppingCarIsShow: shoppingCarIsShow
});
that.fadeIn();//调用显示动画
} else {
that.fadeDown();//调用隐藏动画
let time = setTimeout(function () {
this.setData({
shoppingCarIsShow: shoppingCarIsShow
});
clearTimeout(time);
}.bind(this), 500)//先执行下滑动画,再隐藏模块
}
},
//动画集
// 进入
fadeIn: function () {
this.animation.translateY(0).opacity(1).step()
this.setData({
animationData: this.animation.export()
})
},
fadeDown: function () {
this.animation.translateY(300).opacity(0).step()
this.setData({
animationData: this.animation.export(),
})
},
复制代码
WXML代码
<view class="goodsList" animation="{{animationData}}"></view>
复制代码
思路:
利用translateY实现,初始列表translateY(300),弹出动画使translateY变为0,隐藏时translateY又变为300
因此样式中要进行初始位置translateY(300),即:
.goodsList {
background-color: #fff;
transform: translateY(300px);
}
复制代码
代码github自取: github.com/orangleLi/o…
demo文件夹, 下载下来开发者工具直接导入就能够了