前言
老早之前就搞过sprite用canvas做材质然后更新canvas里的文本的案例,当时比较乱,还用了windows.requestAnimationFrame(),而且在html里加一个我感觉有点不整洁,再次总结提高一下
效果
核心代码
mounted(){
//温度值
this.tem1 = null
//预设一些需要的变量
this.canvas = document.createElement("canvas");
this.context = null;
this.sprite1 = null;
this.canvasTexture = null;
//预加载图片
this.img = new Image()
this.img.src="Images/biankuang.png"
}
methods:{
//绘制canvas
drawCanvas(){
this.canvas.setAttribute("width", 498);
this.canvas.setAttribute("height", 528); //两倍于图片高度
this.context = this.canvas.getContext("2d"); //获取画图环境,指明为2d
this.context.drawImage(this.img, 0, 0);
//文字
this.context.font = "60px Arial";
this.context.fillStyle = "#fff";
this.context.fillText("电机温度:" + this.tem1.toFixed(2) + "℃", 20, 85,450);
},
//利用绘制的canvas做成材质赋予sprite
initSprite() {
this.drawCanvas()
this.canvasTexture = new THREE.CanvasTexture(this.canvas);
let spriteMaterial = new THREE.SpriteMaterial({
map: this.canvasTexture,
transparent: true,
opacity: 1,
depthTest: true,
depthWrite: false,
});
this.sprite1 = new THREE.Sprite(spriteMaterial);
this.sprite1.scale.set(50, 50, 50);
this.sprite1.position.set(70, 20, 0);
this.scene.add(this.sprite1);
console.log(this.sprite1);
//模拟更新
let that =this
setInterval(() => {
that.tem1 = parseInt(21) + Math.random()
}, 2000);
},
animate: function () {
this.drawCanvas()
this.canvasTexture.needsUpdate = true;
this.sprite1.material.map = this.canvasTexture
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.animate);
},
}
注意点
- 最开始的优化后代码是在animate()中每帧new一个THREE.CanvasTexture(this.canvas)然后赋值给 this.sprite1.material.map,导致一个问题,页面有时候会运行一段时间突然三维场景就没了,控制台报错为
THREE.WebGLRenderer: Context Lost.
,原因是显存爆了,从任务管理器可以看到,专用GPU内存利用率会匀速上升,置到占满4.0GB,然后一会儿可能就报那个错并且场景就没了,然后显存会到很低的位置