编辑
2020-06-17
前端
0
请注意,本文编写于 1487 天前,最后修改于 32 天前,其中某些信息可能已经过时。

目录

1.应用场景 电商类的小程序
2.遇到的问题
3.解决方案

1.应用场景 电商类的小程序

需求:在首页和分类页中,点击加入购物的小按钮之后,该商品的图片曲线运动至底部TabBar的购物车按钮中,运动时图片也在缩小

2.遇到的问题

1.曲线运动的路径 2.图片位置和点击区域的位置不一致 3.实现缩小动画

3.解决方案

1.用贝塞尔曲线获取运动的轨迹点,通过动画+setInterval来实现运动 在app.js中加入贝塞尔曲线计算方法
javascript
// 在app.js中加入贝塞尔曲线计算方法 /** * 贝塞尔曲线 */ bezier: function(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': bezier_points }; },

在组件中 js

javascript
// component/flyToCart/flyToCart.js const app = getApp() Component({ lifetimes: { attached: function () { // 获取屏幕宽度,以及TabBar数量,算出终点位置 this.endPos={}; this.endPos['x'] = (app.globalData.clientWidth / 10) * 6; this.endPos['y'] = app.globalData.clientHeight; }, detached: function () { // 在组件实例被从页面节点树移除时执行 }, }, /** * 组件的初始数据 */ data: { ani:null, flag:true,//防止连续点击 }, /** * 组件的方法列表 */ methods: { show(data) { app.debugInfo('传入值',data) if (!this.data.flag) return; this.setData({ flag:false }) let { startPos,//初始位置 img//图片路径 }=data this.setData({ imgUrl:img, startPos }) var topPoint = {}; // 计算最高点y坐标 if (startPos['y'] <= this.endPos['y']) { topPoint['y'] = startPos['y'] - 150; } else { topPoint['y'] = this.endPos['y'] - 150; } // 计算最高点x坐标 if(startPos['x'] <= this.endPos['x']){ topPoint['x'] = (this.endPos['x'] - startPos['x']) / 2 + startPos['x'] }else { topPoint['x'] = (startPos['x'] - this.endPos['x']) / 2 + this.endPos['x'] } this.linePos = app.bezier([startPos, topPoint, this.endPos], 30); // 缩小动画 this.scaleAnimation() // 贝塞尔曲线动画 this.startAnimation(); }, startAnimation: function() { var index = 0, that = this, bezier_points = that.linePos['bezier_points']; this.setData({ bus_x: that.data.startPos.x, bus_y: that.data.startPos.y }) this.timer = setInterval(function() { index++; that.setData({ bus_x: bezier_points[index]['x'], bus_y: bezier_points[index]['y'] }) if (index >= 28) { clearInterval(that.timer); app.debugInfo('time',index*33) that.setData({ flag:true, }) // 重置动画 that.scaleAnimation('originl') } }, 33); }, scaleAnimation:function(type){ var animation = wx.createAnimation({ duration: 924, // 33*28 timingFunction: 'linear' }) let that = this; if (type =='originl'){ animation.scale(1).step(); this.setData({ ani: animation.export() }) }else { animation.scale(0).step(); this.setData({ ani: animation.export() }) } } } })

wxml文件

wxml
<view class="flyBox" hidden="{{flag}}" style="left: {{bus_x}}px; top: {{bus_y}}px;" animation="{{ani}}"> <image src="{{imgUrl}}" class="img"></image> </view>

2.调用组件home.js中的加入购物车事件

javascript
//home.wxml <!--图片位置--> <view class="goods-image-tall" style="background-image:url('{{item.goodsListImg}}')" id="id{{item.goodsCode}}"></view> <!-- 加入购物的按钮--> <image catchtap="addGoods" data-goodsCode="{{item.goodsCode}}" data-type="RECOMEND_GOODS" data-goodsName="{{item.shopGoodsName}}" src='{{globalIcons.cart}}' data-goods="{{item}}" data-from-type='{{0}}' lazy-load data-id="id{{item.goodsCode}}" data-img="{{item.goodsListImg}}"></image> <!-- 飞入购物车动画 --> <fly-to-cart id="fly"></fly-to-cart> //home.js //添加商品到购物车 addGoods(e) { app.debugInfo('---加入购物车---',e) let { goodscode, goodsname, type, optionList, goods, fromType, id, img } = e.currentTarget.dataset let that = this; //判断用户是否登录 if (!app.globalData.token) { wx.navigateTo({ url: '/pages/login/login', }) } else { // 判断是否商品是否需要加工 if (optionList && optionList.length > 0) { app.globalData.byValue = goods; //传递商品信息 modalComponent = that.selectComponent('#cart-modal'); modalComponent.showCartAction(fromType); } else { this.setData({ dataType: type }) let event = "ADD_TO_CART" let data = { "type": type, "goodsCode": goodscode, "goodsName": goodsname } dataPoint(event, data) // 获取图片位置 fly = that.selectComponent('#fly'); // fly定义在home页面,页面卸载时记得清空 let query = that.createSelectorQuery(); query.select(`#${id}`).boundingClientRect(); query.exec(function (imgInfo) { if (imgInfo[0]) { app.debugInfo('图片位置信息', imgInfo) fly.show({ img, startPos:{ x: Number.parseInt(imgInfo[0].width / 2 + imgInfo[0].left), y: Number.parseInt(imgInfo[0].height / 2 + imgInfo[0].top) } }); } }) //不需要加工直接加入购物车 addToCart({ "goodsCode": goodscode, //商品编码 "num": 1 //商品数量 }).then(result => { wx.showToast({ title: '加入购物车成功', icon: 'none', duration: 2000 }) countCartGoods() }).catch(err => { app.debugInfo("------ addCart failure -----", err) }) } } },

最终效果:

参考:https://juejin.im/post/6844903921354293262

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:小智

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!