小程序项目要求实现一个贝塞尔曲线的效果,网上搜了一下,是有算法代码的,然鹅都是原生的小程序,然后鼓弄了一番,终于可以在wepy搭建的小程序上跑起来了。话不多说,直接上
- 在app.wpy中定义screenSize函数,用户获取屏幕宽高
screenSize () {
var that = this
wx.getSystemInfo({
success: function (res) {
var ww = res.windowWidth
var hh = res.windowHeight
that.globalData.ww = ww
that.globalData.hh = hh
}
})
}
// 在onLaunch钩子里调用
onLaunch() {
this.screenSize()
this.testAsync()
}
- 在app.wpy中定义贝塞尔函数
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 bezierPoints = []
// 起始点到控制点的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
bezierPoints.push(point)
}
// console.log(bezierPoints)
return {
'bezierPoints': bezierPoints
}
}
- data对象中的数据
data = {
hide_good_box: true, // 隐藏运动的元素
bus_x: 370, // 移动球的x坐标
bus_y: 300, // 移动球的y坐标
finger: {}, // 手指点点击位置
busPos: {}, // 购物车位置
timer: null, // 定时器
linePos: null // 移动球运动轨迹
}
- onLoad时定义购物车的位置
async onLoad () {
// 购物车坐标
this.busPos = {}
this.busPos['x'] = this.$parent.globalData.ww - 90
this.busPos['y'] = this.$parent.globalData.hh - 60
}
- 在template中定义小球元素
<!-- 抛物线小球 -->
<view class="good_box" hidden="{{hide_good_box}}" style="left: {{bus_x}}px; top: {{bus_y}}px;">
</view>
- 一般通过点击事件调用
// 点触屏幕
touchOnGoods(e) {
// 如果good_box正在运动
if (!this.hide_good_box) return
this.finger = {}
var topPoint = {}
this.finger['x'] = e.touches['0'].clientX
this.finger['y'] = e.touches['0'].clientY
this.$apply()
if (this.finger['y'] < this.busPos['y']) {
topPoint['y'] = this.finger['y'] - 150
} else {
topPoint['y'] = this.busPos['y'] - 150
}
topPoint['x'] = Math.abs(this.finger['x'] - this.busPos['x']) / 2
if (this.finger['x'] > this.busPos['x']) {
topPoint['x'] = (this.finger['x'] - this.busPos['x']) / 2 + this.busPos['x']
} else {
topPoint['x'] = (this.busPos['x'] - this.finger['x']) / 2 + this.finger['x']
}
this.linePos = this.$parent.bezier([this.finger, topPoint, this.busPos], 20)
this.startAnimation()
}
// 加入购物车动画开始
startAnimation(e) {
var index = 0
var that = this
var bezierPoints = that.linePos['bezierPoints']
var len = bezierPoints.length - 1
that.hide_good_box = false
that.bus_x = that.finger['x']
that.bus_y = that.finger['y']
that.$apply()
this.timer = setInterval(function () {
index++
that.bus_x = bezierPoints[index]['x']
that.bus_y = bezierPoints[index]['y']
that.$apply()
if (index >= len) {
clearInterval(that.timer)
that.hide_good_box = true
that.$apply()
}
}, 20)
}
- 最后效果