aether-shards/src/game-viewport.js

80 lines
2 KiB
JavaScript
Raw Normal View History

2025-12-16 23:14:39 +00:00
import {
LitElement,
html,
css,
} from "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js";
import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js";
// --- 1. Define the Game Viewport Component using Lit ---
class GameViewport extends LitElement {
static styles = css`
:host {
display: block;
width: 100%;
height: 100%;
overflow: hidden;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
`;
firstUpdated() {
// Initialize Three.js scene after the component renders
this.initThreeJS();
}
initThreeJS() {
const container = this.shadowRoot.getElementById("canvas-container");
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0b10); // Void Black
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true }); // Enable AA for smoother edges
// Set initial size
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// Add a rotating Voxel (Cube)
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({
color: 0x00f0ff,
wireframe: true,
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
// Handle Resize
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
render() {
return html` <div id="canvas-container"></div> `;
}
}
// Register the web component
customElements.define("game-viewport", GameViewport);