问题描述:

先看bug:
在这里插入图片描述

思路:

baidu上 关于小程序canvas层级过高 的的解决方案,大致分为两种

  1. 将canvas标签替换为图片:
setTimeout(() => {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 168,
        height: 168,
        canvasId: 'Canvas',
        success: (res) => {
          this.setData({ canvasImg: res.tempFilePath });
          console.log('canvasImg',this.data.canvasImg)
        }
      });
    },1000);
  1. 使用cover-view(小程序层级最高的标签)去覆盖canvas标签:
    关于cover-view的小程序官方文档

两种方案的不足:

方案1需要等待canvas渲染完成后再生成图片去替换,且canvas标签不能使用display:none;或 opacity: 0;去隐藏,所以这会导致在canvas渲染完成后仍然会闪动一下再切换成图片显示。

方案2要修改被覆盖的标签,将其层级提到最高。在阅读官方文档后,我就把页面底部的tab栏的view标签替换成了cover-view,结果导致icon消失了…这又是一个bug?

“所以这就结束了?哦,不!,乔治,我们不能就这样放弃!”

“有时候,生活会出其不意地带给我们灵感” ——鲁迅

灵感来源:

在午饭后刷b站时,我刷到一个关于游戏开发的视频,里面提到这样一件事:游戏开发者通常会提前将模型加载好 并放在玩家不可见的区域,等需要用到它的时候再把他挪到玩家眼前。

解决方案:

所以我可以将canvas标签挪到用户不可见的区域,在渲染时用loading动画代替,渲染完成后再将loading动画替换成图片!!

1、首先绘制canvas并生成图片

initCanvasFun(caseTypeList) {
    var context = wx.createCanvasContext('Canvas', this);
    var array = caseTypeList.map(t => t.count);
    var colors = ["#8E92F4", "#ECD67D", "#E77E7F", "#6AE29D", "#6644ff"];
    var total = 0;
    for (var val = 0; val < array.length; val++) {
      total += array[val];
    }
    var point = { x: 84, y: 84 };
    var radius = 84;
    for (var i = 0; i < array.length; i++) {
      context.beginPath();
      var start = 0;
      if (i > 0) {
        for (var j = 0; j < i; j++) {
          start += array[j] / total * 2 * Math.PI;
        }
      }
      var end = start + array[i] / total * 2 * Math.PI;
      context.arc(point.x, point.y, radius, start, end);
      context.lineTo(point.x, point.y);
      context.setStrokeStyle('transparent');
      context.setFillStyle(colors[i]);
      context.fill();
      context.closePath();
      context.stroke();
    }
    context.draw();

    setTimeout(() => {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 168,
        height: 168,
        canvasId: 'Canvas',
        success: (res) => {
          this.setData({ canvasImg: res.tempFilePath });
          console.log('canvasImg',this.data.canvasImg)
        }
      });
    },1000);
  },

2、在canvas标签的style属性中设置绝对定位,将其放到视口外

<canvas canvas-id="canvascrime" wx:if="{{!canvasImg2}}" style="width:168px;height:168px; opacity: 0;position:absolute;left:-1000rpx;"></canvas>

3、随便写一个加载动画占位,在图片url生成后被图片标签替换

<view class="loading-box" wx:if="{{!canvasImg2}}">
	<view class="loading-left"></view>
	<view class="loading-right"></view>
</view>
.loading-box{
  position: absolute;
  width: 260rpx;
  height: 260rpx;
  /* background-color: rebeccapurple; */
}
.loading-left{
  position: absolute;
  left: 50%;
  top: 50%;
  height: 50rpx;
  width: 50rpx;
  border: 8rpx solid rgba(0, 0, 0, 0);
  border-left: 8rpx solid rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  transform: translate(-50%,-50%);
  animation: clockwise 2.2s infinite;

  /* z-index: 10; */
}
.loading-right{
  position: absolute;
  left: 50%;
  top: 50%;
  height: 50rpx;
  width: 50rpx;
  border: 8rpx solid rgba(0, 0, 0, 0);
  border-right: 8rpx solid rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  transform: translate(-50%,-50%);
  animation: clockwise 2s infinite;
  
}
@keyframes clockwise{
  from{
    transform: translate(-50%,-50%) rotate(0deg);
  }
  to{
    /* width: 200rpx; */
    transform: translate(-50%,-50%) rotate(720deg);
  }
}

完成效果:

请添加图片描述
完美解决,看起来就很“大数据”

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐