以前、Three.jsでCanvasをテクスチャーに設定した場合、material.map.needsUpdateをtrueに設定すれば動的に更新できることを調べました。
今回は、それのA-Frame版です。
A-Frameも内部はThree.jsを使っているので、material.map.needsUpdateをtrueにしなければならないことは火を見るよりも明らかなのですが、どうやって渡すか試行錯誤しました。
結果、A-Frameのオブジェクトには、getObject3Dたるメソッドがあり、getObject3D('mesh')でメッシュを取得できるようです。
メッシュさえ取得してしまえば、
object.getObject3D('mesh').material.map.needsUpdate = true;
という感じで、material.map.needsUpdateにtrueを入れることは楽々です。
ただ、毎フレーム設定する必要があるので、
<a-scene> <a-assets> <canvas id="canvas"></canvas> </a-assets> </a-scene> <script> AFRAME.registerComponent('plane', { init: function () { this.canvas = document.getElementById('canvas'); this.ctx = canvas.getContext('2d'); }, tick: function () { const material = this.el.getObject3D('mesh').material; const fontSize = 24; this.canvas.width = this.canvas.width; this.canvas.height = this.canvas.height; this.ctx.save(); this.ctx.font = `${fontSize}px sans-serif`; this.ctx.fillText(Date.now(), 0, fontSize); this.ctx.restore(); if (!material.map) { return; } material.map.needsUpdate = true; } }); const plane = document.createElement('a-plane'); plane.setAttribute('plane', 'plane'); plane.setAttribute('material', 'shader: flat; src: #canvas;'); document.getElementsByTagName('a-scene')[0].appendChild(plane); </script>
という感じで、tickをうまく使うと良いと思われます。