From c861603b066201a4da3739c0972ac01320508ab0 Mon Sep 17 00:00:00 2001 From: T-A-H-prog Date: Wed, 15 Apr 2026 21:25:37 +0200 Subject: [PATCH] 3d tv --- src/components/sections/MonitorModel.vue | 31 ++++++++++++-- src/components/sections/TextSection.vue | 48 +++++++++++----------- src/components/sections/WelcomeSection.vue | 41 ++++++++++++------ 3 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/components/sections/MonitorModel.vue b/src/components/sections/MonitorModel.vue index 429f8a5..e9fb7b8 100644 --- a/src/components/sections/MonitorModel.vue +++ b/src/components/sections/MonitorModel.vue @@ -5,9 +5,10 @@ import gsap from "gsap"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; +import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; const canvasRef = ref(null); -let renderer, scene, camera, model; +let renderer, scene, camera, model, controls; function initThree(canvas) { renderer = new THREE.WebGLRenderer({ @@ -18,13 +19,20 @@ function initThree(canvas) { renderer.outputColorSpace = THREE.SRGBColorSpace; scene = new THREE.Scene(); - camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100); + camera = new THREE.PerspectiveCamera(45, 2, 0.1, 100); camera.position.set(0, 0, 5); const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(2, 2, 5); scene.add(light); + controls = new OrbitControls(camera, renderer.domElement); + controls.enableDamping = true; + + controls.minDistance = 5; + controls.maxDistance = 5; + controls.maxPolarAngle = Math.PI / 2; + scene.add(new THREE.AmbientLight(0xffffff, 0.5)); loadModel(); @@ -53,6 +61,10 @@ function loadModel() { const box = new THREE.Box3().setFromObject(model); const center = box.getCenter(new THREE.Vector3()); const size = box.getSize(new THREE.Vector3()); + + controls.target.copy(center); + controls.update(); + model.position.set(0, 0, 0); scene.add(model); @@ -72,11 +84,14 @@ function loadModel() { function render() { if (!renderer) return; + + controls.update(); + renderer.render(scene, camera); } function onResize() { if (!renderer || !canvasRef.value) return; - const r = canvasRef.getBoundingClientRect(); + const r = canvasRef.value.getBoundingClientRect(); const dpr = Math.min(window.devicePixelRatio || 1, 2); const width = canvasRef.value.clientWidth; @@ -89,21 +104,26 @@ function onResize() { camera.updateProjectionMatrix(); } +const resizeObserver = new ResizeObserver(onResize); + onMounted(() => { initThree(canvasRef.value); onResize(); + + resizeObserver.observe(canvasRef.value); window.addEventListener("resize", onResize); }); onUnmounted(() => { gsap.ticker.remove(render); window.removeEventListener("resize", onResize); + resizeObserver.disconnect(); renderer?.dispose(); });