作者:牛咖
小池是一款具有吸引力的预算应用程序,允许用户通过轻松录入,享受记账的幸福,并为用户提供大量非凡的记录输入!
在这篇文章中,会详细介绍如何做出如图的交互效果,我们将根据 canvas 画布渲染圆球所需的步骤进行讲解。
如 GIF 图中所展示的效果,黏糊糊的粘连的路径是由 metaball 函数来创建出的,然后根据返回的路径坐标值,再基于贝塞尔曲线使用 canvas 画布绘制而成。
实现原理
可以看到,这个交互效果主要由两个圆球组成,它们之间存在三种情况:完全重合,完全分离和有交叠部分。
在两圆完全重合时,小圆不会出现;当两圆之间距离超出设置的最大连接距离时,两圆会完全分离不接触;而重点在于第三种情况,两圆有接触但没有完全重合。
当第三种情况发生时,我们就需要考虑以下几点:
左:图 1-1,右:图 1-2
图 1-3
实现方法
下表为 metaball 函数的参数与返回值信息:
了解 metaball 函数的实现原理后,下面讲解使用 canvas 来绘制图形的步骤:
1. 引入 metaball 函数
import metaball from 'utils/metaball.js'
2. 设置大圆/小圆的半径和中心点坐标
radius1 = r1
radius2 = r2
center1 = { x: x1, y: y1 }
center2 = { x: x2, y: y2 }
3. 设置两圆分离的最大距离
maxDist = radius1 + radius2 * 2;
4. 创建 canvas 绘图上下文(传入定义在 <canvas/> 的 canvas-id)
ctx = wx.createCanvasContext('canvas');
值得在注意的是,在手指触摸动作开始事件 touchstart 触发的事件回调函数中:
center2.x = e.touches[0].x
center2.y = e.touches[0].y
setInterval(() => {
ctx.clearRect(0, 0, width, height);
a = metaball(
radius1,
radius2,
[center1.x, center1.y],
[center2.x, center2.y],
maxDist
);
if (a.length <= 1) {} if (a.length >= 2) {
ctx.beginPath()
ctx.setFillStyle('#ffffff')
ctx.arc(center2.x,center2.y,radius2,0,Math.PI * 2,true)
ctx.fill()
}
if (a.length > 2) {
ctx.beginPath()
ctx.setFillStyle('#ffffff')
// [p1, h1, h3, p3, p4, h4, h2, p2]
ctx.moveTo(a[7][0], a[7][1])
ctx.lineTo(a[0][0], a[0][1])
ctx.bezierCurveTo(
a[1][0],
a[1][1],
a[2][0],
a[2][1],
a[3][0],
a[3][1]
)
ctx.lineTo(a[4][0], a[4][1])
ctx.bezierCurveTo(
a[5][0],
a[5][1],
a[6][0],
a[6][1],
a[7][0],
a[7][1]
)
ctx.fill()
}
ctx.draw()
}, 20)
center2.x = e.touches[0].x center2.y = e.touches[0].y
center2.x = center1.x center2.y = center1.y
以上就是「小池记账」小程序的主页交互效果制作,当你认真去思考去完善一个小程序时,你会发现,原来小程序也可以很美。
「小池记账」小程序使用链接
https://minapp.com/miniapp/6042/
相关阅读