做为一款2C下单小程序,产品老总说要搞一个加入购物车的动画,第一习惯是网上找解决方案:贝塞尔算法+setInterval=>setData。html
上线一段时间就出现了加入购物车总价计算负数状况,以及计算不许,嗯。包括动画频繁setData期间丢失关键动做setData,以及添加剧复商品等bug。算法
WXS响应事件的基础库要求有些高,直接放弃了。小程序
贝塞尔曲线算法 + setInterval=>setDataapi
function bezier(points, part) {
let sx = points[0]['x'];
let sy = points[0]['y'];
let cx = points[1]['x'];
let cy = points[1]['y'];
let ex = points[2]['x'];
let ey = points[2]['y'];
var bezier_points = [];
// 起始点到控制点的x和y每次的增量
var changeX1 = (cx - sx) / part;
var changeY1 = (cy - sy) / part;
// 控制点到结束点的x和y每次的增量
var changeX2 = (ex - cx) / part;
var changeY2 = (ey - cy) / part;
//循环计算
for (var i = 0; i <= part; i++) {
// 计算两个动点的坐标
var qx1 = sx + changeX1 * i;
var qy1 = sy + changeY1 * i;
var qx2 = cx + changeX2 * i;
var qy2 = cy + changeY2 * i;
// 计算获得此时的一个贝塞尔曲线上的点
var lastX = qx1 + ((qx2 - qx1) * i) / part;
var lastY = qy1 + ((qy2 - qy1) * i) / part;
// 保存点坐标
var point = {};
point['x'] = lastX;
point['y'] = lastY;
bezier_points.push(point);
}
//console.log(bezier_points)
return {
bezier_points
};
}
复制代码
而后 setInterval (坑)网络
综合贝塞尔曲线和wx.createAnimationide
method:{
touchOnGoods(e) {
// 若是good_box正在运动
if (!this.data.hide_good_box) return;
const { touches } = e;
const topPoint = {};
this.finger = {
x: touches[0].clientX,
y: touches[0].clientY
};
topPoint['y'] =
this.finger['y'] < this.busPos['y']
? this.finger['y'] - 150
: this.busPos['y'] - 150;
topPoint['x'] =
this.finger['x'] > this.busPos['x']
? (this.finger['x'] - this.busPos['x']) / 2 + this.busPos['x']
: (this.busPos['x'] - this.finger['x']) / 2 + this.finger['x'];
const result = bezier([this.finger, topPoint, this.busPos], 25);
this.startAnimation(result);
},
startAnimation(linePos) {
const { bezier_points } = linePos;
const len = bezier_points.length - 1;
const first = bezier_points.shift();
//防止动画不生效
//同一个按钮动画,动画开始前先归位元素位置
this.setData(
{
hide_good_box: false,
initLeft:first.x,
initTop:first.y,
animationData: this.animation.export()
},
() => {
bezier_points.forEach((i, idx) => {
this.animation
.left(i.x)
.top(i.y)
.rotate(50)
.step({ duration: 25 });
});
this.setData({
animationData: this.animation.export()
});
}
);
//有个bug,就是连续点击,动画不出来
setTimeout(() => {
this.setData({ hide_good_box: true });
}, len * 20 + 100);
}
},
ready() {
this.busPos = { x: 50, y: 601 };
//调用同步接口 略有问题
this.busPos.y = util.getSysInfo().windowHeight - 66;
this.animation = wx.createAnimation({
timingFunction: 'ease-in',
delay: 0,
duration: 1000
});
}
//有点懒,直接贴源代码了
复制代码
<view class="good_box" hidden="{{hide_good_box}}" style="left:{{initLeft}}px;top:{{initTop}}px" animation="{{animationData}}"></view>
<view bindtap="touchOnGoods">
<slot></slot>
</view>
复制代码
其实好的解决方案,应该是排除低端手机,尤为是安卓机子来启用动画。 暂时没有其余好的idea了,由于不多搞动画,缺少经验。有同行仁兄多多指交。优化