微信小程序 Canvas 滑动抖动解决流程

Photo by raphaelle on Unsplash

为了完成产品中的环形进度条的动画,尝试了搜索引擎中能提供的所有方法,包括 Canvas 绘图,CSS 遮罩旋转,最后只有 Canvas 2D 能够完美实现动画效果。现把所有坑和能够实现的方法提供在此留给大家做参考。

无法完美实现或不能实现

本节归纳了所有不能实现的方法,包含小程序普通 Canvas 接口以及 CSS3 动画。

其中普通 Canvas 进行绘图,在页面发生滚动时会出现抖动,个人推测是没做优化在页面发生变化的时候不断触发重绘导致。

使用CSS3动画则坑更多,一般思路是通过控制两个半环的滚动,这里又有几个变种,无一例外都要在动画过程中改变半环的颜色或者旋转角度或者层级,这在动画过程中都会发生闪烁,也基本不能用。还有一个思路是通过 clip 来做圆环,通过 clip 起到遮罩的作用,无奈小程序上 clip 动画仍然不支持。

完美实现的 Canvas 2D

就在准备放弃的时候,看到小程序 IDE 提示使用 Canvas 2D 提高效率,这不,马上切换成 2D 接口,完美解决。不仅动画流畅,而且滑动屏幕不会导致抖动。注意一下参照官方文档更新 API 就行。(此时在 IDE 中仍然会有层叠的 BUG,不过真机没有)。

const query = wx.createSelectorQuery().in(this);
      query.select('#progress-canvas-bg').fields({
        node: true,
        size: true
      }).exec((res) => {
        // 使用 wx.createctx 获取绘图上下文 ctx
        const canvas = res[0].node;
        var ctx = canvas.getContext('2d');
        // console.log(canvas,ctx);
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = res[0].width * dpr
        canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr)
        ctx.lineWidth = lineWidth; // 设置圆环的宽度
        ctx.strokeStyle = '#EDE6E4'; // 设置圆环的颜色
        ctx.lineCap = 'round'; // 设置圆环端点的形状
        ctx.beginPath(); //开始一个新的路径
        ctx.arc(origin, origin, r, 0, 2 * Math.PI, false);
        ctx.stroke(); //对当前路径进行描边

})

发表评论

邮箱地址不会被公开。