rate/www/src/components/3DHandler.svelte
2022-10-28 15:24:39 +02:00

118 lines
2.5 KiB
Svelte

<script lang="ts">
import { beforeUpdate, afterUpdate, onMount, onDestroy } from 'svelte';
import * as Three from 'three';
export let width: number;
export let height: number;
//#region variables
let container: HTMLElement;
let canvas: HTMLCanvasElement;
let maxInnerWidth: number = 0;
let maxInnerHeight: number = 0;
let portrait: boolean = true;
let focalLength: number = 540 / Math.atan((70 * Math.PI) / 180);
let fov = 75;
//let baseHorizontalFOV: number = 2.0*Math.atan(baseAspectRation*Math.tan(baseVerticalFOV*0.5));
let scene: Three.Scene = new Three.Scene();
let camera: Three.PerspectiveCamera = new Three.PerspectiveCamera(
75,
1,
0.1,
1000,
);
let renderer: Three.WebGLRenderer = new Three.WebGLRenderer();
let box: Three.BoxGeometry = new Three.BoxGeometry(1, 1, 1);
let mat: Three.MeshBasicMaterial = new Three.MeshBasicMaterial({
color: 0x00ff00,
});
let cube = new Three.Mesh(box, mat);
//#endregion
//#region functions
function updateVerticalFOV() {
fov = (180 / Math.PI) * Math.tan(innerHeight / (focalLength * 2));
}
function resetMaxDimensions() {
maxInnerWidth = 0;
maxInnerHeight = 0;
}
function updateMaxInnerDimensions() {
if (maxInnerWidth < width) {
maxInnerWidth = width;
}
if (maxInnerHeight < height) {
maxInnerHeight = height;
}
}
function checkOrientation(oldPortrait: boolean) {
if (innerWidth > height) {
portrait = false;
} else {
portrait = true;
}
if (oldPortrait != portrait) {
resetMaxDimensions();
}
}
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.05;
cube.rotation.y += 0.05;
renderer.render(scene, camera);
}
//#endregion
onMount(() => {
canvas = container.appendChild(renderer.domElement);
scene.add(cube);
camera.position.z = 5;
animate();
});
beforeUpdate(() => {
checkOrientation(portrait);
updateMaxInnerDimensions();
updateVerticalFOV();
camera.aspect = width / height;
camera.fov = fov;
camera.setViewOffset(width, height, 0, 0, width, height);
renderer.setSize(width, height);
renderer.setClearColor(0x000000, 0.1);
});
afterUpdate(() => {});
onDestroy(() => {
container.removeChild(canvas);
});
</script>
<div class="Container" bind:this={container} />
<style>
.Container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>