小程序也能做这么精致的动效?看完我给大神献上了膝盖…… | 开发

作者:牛咖小池是一款具有吸引力的预算应用程序,允许用户通过轻松录入,享受记账的幸福,并为用户提供大量非凡的记录输入!在这篇文章中,会详细介绍如何做出如图的交互效果,我们将根据 canvas 画布渲染圆球所需的步骤进行讲解。如 GIF 图中所展示的效果,黏糊糊的粘连的路径是由 metaball 函数来创建出的,然后根据返回的路径坐标值,再基于贝塞尔曲线使用 canvas 画布绘制而成。实现原理可以看到,这个交互效果主要由两个圆球组成,它们之间存在三种情况:完全重合,完全分离和有交叠部分。在两圆完全重合时,小圆不会出现;当两圆之间距离超出设置的最大连接距离时,两圆会完全分离不接触;而重点在于第三种情况,两圆有接触但没有完全重合。当第三种情况发生时,我们就需要考虑以下几点:

  • 两圆有接触没有完全重叠,会出现两条弧形的轨迹,在这里称它为连接器。

  • 两圆之间的切线就是连接器的最宽处(如图1-1),通过 metaball 函数计算出四个切点位置,假设切点分别为 p1,p2,p3,p4。(考虑到图形效果,切点位置还与控制因子 v 相关,当 v=0.5 时效果最佳)

  • 把梯形形状的连接器转换为弧形轨迹(如图1-1),需要 metaball 函数计算出四个控制点位置,假设控制点分别为 h1,h2,h3,h4。

  • 当发生移动时,这八个点的状态如图 1-3 所示。

  • metaball 函数的功能就是通过计算出这八个点的坐标,并返回出来。

  • 左:图 1-1,右:图 1-2图 1-3实现方法下表为 metaball 函数的参数与返回值信息:了解 metaball 函数的实现原理后,下面讲解使用 canvas 来绘制图形的步骤:1. 引入 metaball 函数import metaball from "utils/metaball.js"2. 设置大圆/小圆的半径和中心点坐标radius1 = r1radius2 = r2center1 = { x: x1, y: y1 }center2 = { x: x2, y: y2 }3. 设置两圆分离的最大距离maxDist = radius1 + radius2 * 2;4. 创建 canvas 绘图上下文(传入定义在 <canvas/> 的 canvas-id)ctx = wx.createCanvasContext("canvas");值得在注意的是,在手指触摸动作开始事件 touchstart 触发的事件回调函数中:
  • 通过参数 e.touches[0].x/y 获取当前触摸点位置信息,并赋值给小圆的圆心位置变量。

  • 在定时器中,每次要先清除画布,然后调用 metaball 函数,使用数组变量 a 接收 metaball 函数的返回值,并对返回结果进行如下判断:

  • 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)
  • 手指触摸后移动事件 touchmove 触发的事件回调函数中监听手指移动事件,将当前的触摸点位置信息赋值给小圆的圆心位置变量。
  • center2.x = e.touches[0].x center2.y = e.touches[0].y
  • 手指触摸动作结束事件 touchend 触发的事件回调函数中把小圆的圆心位置重置到大圆的圆心位置。
  • center2.x = center1.x center2.y = center1.y以上就是「小池记账」小程序的主页交互效果制作,当你认真去思考去完善一个小程序时,你会发现,原来小程序也可以很美。「小池记账」小程序使用链接
    http://minapp.com/miniapp/6042/相关阅读/ 知晓程序微信,我小鸡忍你很久了…… | 开发/ 知晓程序开发 | 手把手,教你在小程序里做一个圆形进度条关注「知晓程序」微信公众号,回复「开发」,获取小程序开发技巧大全。

    ▽ 点击「阅读原文」,发现更多优质小程序。

    微信扫一扫 分享到朋友圈
    微口订阅号

    关注订阅号

    社交媒体运营经验交流
    流量电商行业动态讨论

    公众号流量变现
    热点事件
    微口订阅号

    关注订阅号

    社交媒体运营经验交流
    流量电商行业动态讨论

    阅读下一篇
    微口订阅号

    自媒体运营攻略
    行业经验交流

    关闭

    创建藏点

    藏点名称
    藏点说明
    藏点封面
    转藏至我的藏点 +新建藏点
      关闭
      确定 取消