|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>Recursive Polygons in 3D with Snowflakes</title> |
|
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> |
|
<script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js"></script> |
|
<style> |
|
#canvas { |
|
height: 500px; |
|
width: 800px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<a-scene> |
|
<a-entity environment="preset: forest"></a-entity> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a-entity camera position="0 1.6 0" look-controls wasd-controls></a-entity> |
|
</a-scene> |
|
|
|
<script> |
|
AFRAME.registerComponent('snowflake', { |
|
init: function() { |
|
this.el.setAttribute('geometry', { |
|
primitive: 'sphere', |
|
radius: 0.05 |
|
}); |
|
this.el.setAttribute('material', { color: '#FFF' }); |
|
|
|
|
|
this.el.object3D.position.set( |
|
Math.random() - 0.5, |
|
Math.random() - 0.5, |
|
Math.random() - 0.5 |
|
); |
|
|
|
|
|
this.velocity = new THREE.Vector3(0, -0.05, 0); |
|
}, |
|
tick: function() { |
|
this.el.object3D.position.add(this.velocity); |
|
if (this.el.object3D.position.y <= -0.5) { |
|
this.el.parentNode.removeChild(this.el); |
|
} |
|
} |
|
}); |
|
|
|
function createSnowflakeCloud(x, y, z) { |
|
let cloud = document.createElement('a-entity'); |
|
cloud.object3D.position.set(x, y, z); |
|
|
|
setInterval(() => { |
|
let snowflakeEl = document.createElement('a-entity'); |
|
snowflakeEl.setAttribute('snowflake', ''); |
|
cloud.appendChild(snowflakeEl); |
|
}, 100); |
|
|
|
document.querySelector('a-scene').appendChild(cloud); |
|
} |
|
|
|
|
|
for (let x = -10; x <= 10; x += 10) { |
|
for (let z = -10; z <= 10; z += 10) { |
|
createSnowflakeCloud(x, 5, z); |
|
} |
|
} |
|
|
|
|
|
createSnowflakeCloud(0, 8, 0); |
|
|
|
</script> |
|
</body> |
|
</html> |
|
|