最近群里有几个人问,如何把echarts的图表贴在three.js的模型上。这个问题其实很简单,因为二者都是渲染成canvas的,直接用echarts生成的canvas当作贴图就可以了。
方法确定可行,那么我们就直接开始撸代码。
先搭建一个three的基本场景起来,这里不在复述。
然后新建一个平面,我们把图片贴在这个平面上即可。
【相关课程推荐:JavaScript视频教程】
addPlane() { var geometry = new THREE.PlaneGeometry(10,10); var material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, // transparent:true }); this.plane = new THREE.Mesh(geometry, material); this.scene.add(this.plane);}
摆好相机的角度,此时场景中是一个白板。
然后打开echarts的官网,找到案例,来个仪表盘吧。代码拷贝下来。跑起来。
为了方便演示,我在body中创建了2个div,分别作为three和图表的容器。实际开发中图表的容器不需要显示出来的,也不需要添加到body中的。
<div id="webgl" style="width:512px;height: 512px;float: left;"></div><div id="echart" style="width:512px;height: 512px;margin-left: 620px;"></div>
var myChart = echarts.init(document.getElementById('echart'));option = { tooltip: { formatter: "{a} <br/>{b} : {c}%" }, //toolbox会在右上角生成两个功能按钮,咱们不需要,直接干掉。 // toolbox: { // feature: { // restore: {}, // saveAsImage: {} // } // }, series: [ { name: '业务指标', type: 'gauge', detail: { formatter: '{value}%' }, data: [{ value: 50, name: '完成率' }] } ]};option.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0;myChart.setOption(option, true);const dom = document.getElementById("webgl");const scene = new Basescene(dom);scene.addPlane();
此时看到下面页面:
方法一:CanvasTexture
three.js有一个api:CanvasTexture。可以传入一个canvas对象,用这个方法可以完成上面的任务。
CanvasTexture( canvas : HTMLElement, mapping : Constant, wrapS : Constant, wrapT : Constant, magFilter : Constant, minFilter : Constant, format : Constant, type : Constant, anisotropy : Number )
changeTextureT(texture){ this.plane.material.map = new THREE.CanvasTexture(texture) this.plane.material.needsUpdate = true var thiscancas = document.getElementById("echart").getElementsByTagName('canvas')[0] scene.changeTextureT(thiscancas)}
运行结果如下,确实不清晰,和他们遇到的问题的一样。尝试把echarts绘制大点,但是这个是自适应的,导致仪表板很丑,不是想象的样子,如果是自己绘制的表格,就可以这样处理了。
方法二:getDataURL
既然echarts也是渲染canvas,看看api,应该有方法导出图片。就是下面的api,而且有可选参数,可以设置分辨率。
changeTextureE(texture){ this.plane.material.map = new THREE.TextureLoader().load(texture) this.plane.material.needsUpdate = true }var texture = myChart.getDataURL({ pixelRatio: 4, backgroundColor: '#fff'}); scene.changeTextureE(texture)