微信小程序 canvas 层级过高 解决方案
问题描述:先看bug:解决方案:baidu上 关于小程序canvas层级过高 的的解决方案,大致分为两种:将canvas标签替换为图片:setTimeout(() => {wx.canvasToTempFilePath({x: 0,y: 0,width: 168,height: 168,canvasId: 'Canvas',success: (res) =>
问题描述:
先看bug:
思路:
baidu上 关于小程序canvas层级过高 的的解决方案,大致分为两种:
- 将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);
- 使用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);
}
}
完成效果:
完美解决,看起来就很“大数据”
更多推荐
所有评论(0)