aframe - AFrame:如何以编程方式创建画布纹理平面网格
问题描述
我不太了解 aframe 如何在初始化时从 JavaScript 完成事情。我创建了一个网格组件来创建 NxM 平面,每个平面都有自己的纹理画布。但由于某种原因,即使画布是独一无二的,每架飞机 1 个,它们在每架飞机上被随机重复使用
我应该看到的是一个像这样的网格
+---+ +---+ +---+
| 6 | | 7 | | 8 |
+---+ +---+ +---+
+---+ +---+ +---+
| 3 | | 4 | | 5 |
+---+ +---+ +---+
+---+ +---+ +---+
| 0 | | 1 | | 2 |
+---+ +---+ +---+
我看到的是类似
我可能正在做一些愚蠢的事情。这是代码。注意:由于 aframe 的工作方式,它都停留在 HTML 部分。
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('grid', {
schema: {
across: {type: 'int', default: 3},
down: {type: 'int', default: 3},
},
init() {
const data = this.data;
const across = data.across;
const down = data.down;
const needed = across * down;
for (let i = 0; i < needed; ++i) {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
canvas.id = `c${Date.now()}`;
const ctx = canvas.getContext('2d');
ctx.fillStyle = `hsl(${i / needed * 360 | 0}deg,100%,50%)`;
ctx.fillRect(0, 0, 256, 256);
ctx.fillStyle = `hsl(${Math.random() * 360 | 0}deg,100%,80%)`;
ctx.fillStyle = 'black';
ctx.font = '200px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(i, 128, 128);
const elem = document.createElement('a-entity');
elem.setAttribute('geometry', {
primitive: 'plane',
height: 1,
width: 1,
});
elem.setAttribute('material', {
shader: 'flat',
src: canvas,
});
this.el.appendChild(elem);
const x = i % across;
const y = i / across | 0;
const u = x / (across - 1);
const v = y / (down - 1);
const px = across * (u - .5);
const py = down * (v - .5);
const pz = 0;
elem.setAttribute('position', {x: px, y: py, z: pz});
}
},
});
</script>
<a-scene>
<a-entity grid position="0 1.5 -4"></a-entity>
</a-scene>
我还尝试将画布添加到 DOM 并通过分配 id 进行引用。相关线路是
// make up an ID
canvas.id = `c${Date.now()}`;
// add to document
document.body.appendChild(canvas);
// make the src the id of the canvas
elem.setAttribute('material', {
shader: 'flat',
src: `#${canvas.id}`,
});
但它有同样的问题
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('grid', {
schema: {
across: {type: 'int', default: 3},
down: {type: 'int', default: 3},
},
init() {
const data = this.data;
const across = data.across;
const down = data.down;
const needed = across * down;
for (let i = 0; i < needed; ++i) {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
canvas.id = `c${Date.now()}`;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.fillStyle = `hsl(${i / needed * 360 | 0}deg,100%,50%)`;
ctx.fillRect(0, 0, 256, 256);
ctx.fillStyle = `hsl(${Math.random() * 360 | 0}deg,100%,80%)`;
ctx.fillStyle = 'black';
ctx.font = '200px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(i, 128, 128);
const elem = document.createElement('a-entity');
elem.setAttribute('geometry', {
primitive: 'plane',
height: 1,
width: 1,
});
elem.setAttribute('material', {
shader: 'flat',
src: `#${canvas.id}`,
});
this.el.appendChild(elem);
const x = i % across;
const y = i / across | 0;
const u = x / (across - 1);
const v = y / (down - 1);
const px = across * (u - .5);
const py = down * (v - .5);
const pz = 0;
elem.setAttribute('position', {x: px, y: py, z: pz});
}
},
});
</script>
<a-scene>
<a-entity grid position="0 1.5 -4"></a-entity>
</a-scene>
解决方案
我认为这是因为 a-frame 创建实体的速度如此之快,以至于 Date.now 不是唯一的。
在循环之外,尝试:
let id = 0;
然后对于 id:
canvas.id = `c${id++}`;
它似乎按预期工作。
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('grid', {
schema: {
across: {type: 'int', default: 3},
down: {type: 'int', default: 3},
},
init() {
const data = this.data;
const across = data.across;
const down = data.down;
const needed = across * down;
let id = 0;
for (let i = 0; i < needed; ++i) {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
canvas.id = `c${id++}`;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.fillStyle = `hsl(${i / needed * 360 | 0}deg,100%,50%)`;
ctx.fillRect(0, 0, 256, 256);
ctx.fillStyle = `hsl(${Math.random() * 360 | 0}deg,100%,80%)`;
ctx.fillStyle = 'black';
ctx.font = '200px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(i, 128, 128);
const elem = document.createElement('a-entity');
elem.setAttribute('geometry', {
primitive: 'plane',
height: 1,
width: 1,
});
elem.setAttribute('material', {
shader: 'flat',
src: `#${canvas.id}`,
});
this.el.appendChild(elem);
const x = i % across;
const y = i / across | 0;
const u = x / (across - 1);
const v = y / (down - 1);
const px = across * (u - .5);
const py = down * (v - .5);
const pz = 0;
elem.setAttribute('position', {x: px, y: py, z: pz});
}
},
});
</script>
<a-scene>
<a-entity grid position="0 1.5 -4"></a-entity>
</a-scene>
推荐阅读
- python - 我收到错误 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
- ios - ™在 App Store Connect 分阶段推出期间发布更新
- symfony - 错误:App\Kernel 类包含 1 个抽象方法,因此必须
- c# - 使用条件运算符?为了得到偶数
- sql-server - SQL Server 2012 和 2016 的 ODBC 连接
- python - 如何使用列表中每个项目中的数字对列表进行排序?Python
- dll - 有没有办法在 Inno Setup 的 [Code] 部分中使用 64 位 DLL?
- python - 字符串元素计数不起作用 [Python]
- python - 遍历列表列表
- c# - ServerManager 在 c# Winforms 应用程序中失败,出现 0x80040154 在 IIS 中创建简单的 Web 应用程序