three js con fideos
This commit is contained in:
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["Vue.volar"]
|
|
||||||
}
|
|
||||||
BIN
public/models/room-draco.glb
Normal file
BIN
public/models/room-draco.glb
Normal file
Binary file not shown.
BIN
public/vids/Aus_dem_wasser.mp4
Normal file
BIN
public/vids/Aus_dem_wasser.mp4
Normal file
Binary file not shown.
BIN
public/vids/TH-Video_Abgabe.mp4
Executable file
BIN
public/vids/TH-Video_Abgabe.mp4
Executable file
Binary file not shown.
BIN
public/vids/googleOR.mp4
Normal file
BIN
public/vids/googleOR.mp4
Normal file
Binary file not shown.
BIN
public/vids/ski.mp4
Normal file
BIN
public/vids/ski.mp4
Normal file
Binary file not shown.
BIN
public/vids/skitom.mp4
Executable file
BIN
public/vids/skitom.mp4
Executable file
Binary file not shown.
@@ -2,13 +2,29 @@
|
|||||||
import { onMounted, onUnmounted, ref } from "vue";
|
import { onMounted, onUnmounted, ref } from "vue";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import gsap from "gsap";
|
import gsap from "gsap";
|
||||||
|
import ScrollTrigger from "gsap/ScrollTrigger";
|
||||||
|
|
||||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
|
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
|
||||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
||||||
|
|
||||||
|
import surf_video from "/vids/Aus_dem_wasser.mp4";
|
||||||
|
import ski_video from "/vids/ski.mp4";
|
||||||
|
|
||||||
const canvasRef = ref(null);
|
const canvasRef = ref(null);
|
||||||
let renderer, scene, camera, model, controls;
|
let renderer, scene, camera, model, controls, gsapCtx;
|
||||||
|
let screen1, screen3, screen4;
|
||||||
|
|
||||||
|
const video_surf = document.createElement("video");
|
||||||
|
const video_ski = document.createElement("video");
|
||||||
|
|
||||||
|
video_surf.src = surf_video;
|
||||||
|
video_surf.loop = true;
|
||||||
|
video_surf.muted = true;
|
||||||
|
|
||||||
|
video_ski.src = ski_video;
|
||||||
|
video_ski.loop = true;
|
||||||
|
video_ski.muted = true;
|
||||||
|
|
||||||
function initThree(canvas) {
|
function initThree(canvas) {
|
||||||
renderer = new THREE.WebGLRenderer({
|
renderer = new THREE.WebGLRenderer({
|
||||||
@@ -17,21 +33,25 @@ function initThree(canvas) {
|
|||||||
alpha: true,
|
alpha: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
renderer.setPixelRatio(1); //TODO
|
||||||
|
|
||||||
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
||||||
scene = new THREE.Scene();
|
scene = new THREE.Scene();
|
||||||
camera = new THREE.PerspectiveCamera(45, 2, 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);
|
const light = new THREE.DirectionalLight(0xffe0b0, 0.9);
|
||||||
light.position.set(2, 2, 5);
|
light.position.set(-1, 4, 5);
|
||||||
scene.add(light);
|
scene.add(light);
|
||||||
|
|
||||||
controls = new OrbitControls(camera, renderer.domElement);
|
controls = new OrbitControls(camera, renderer.domElement);
|
||||||
controls.enableDamping = true;
|
controls.enableDamping = true;
|
||||||
|
controls.enabled = false;
|
||||||
|
|
||||||
controls.minDistance = 5;
|
// controls.minDistance = 5;
|
||||||
controls.maxDistance = 5;
|
// controls.maxDistance = 5;
|
||||||
controls.maxPolarAngle = Math.PI / 2;
|
controls.maxPolarAngle = Math.PI / 2;
|
||||||
|
controls.minAzimuthAngle = -Math.PI / 2;
|
||||||
|
controls.maxAzimuthAngle = Math.PI / 2;
|
||||||
|
|
||||||
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
|
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
|
||||||
|
|
||||||
@@ -44,7 +64,7 @@ function loadModel() {
|
|||||||
if (model) {
|
if (model) {
|
||||||
scene.remove(model);
|
scene.remove(model);
|
||||||
}
|
}
|
||||||
let modelUrl = "/models/Monitor_draco.glb";
|
let modelUrl = "/models/room-draco.glb";
|
||||||
let dracoPath = "/draco/";
|
let dracoPath = "/draco/";
|
||||||
|
|
||||||
const dracoLoader = new DRACOLoader();
|
const dracoLoader = new DRACOLoader();
|
||||||
@@ -61,12 +81,36 @@ function loadModel() {
|
|||||||
const box = new THREE.Box3().setFromObject(model);
|
const box = new THREE.Box3().setFromObject(model);
|
||||||
const center = box.getCenter(new THREE.Vector3());
|
const center = box.getCenter(new THREE.Vector3());
|
||||||
const size = box.getSize(new THREE.Vector3());
|
const size = box.getSize(new THREE.Vector3());
|
||||||
|
const texture_surf_video = new THREE.VideoTexture(video_surf);
|
||||||
|
const texure_ski = new THREE.VideoTexture(video_ski);
|
||||||
|
screen1 = model.getObjectByName("fernseher1Bild");
|
||||||
|
screen4 = model.getObjectByName("fernseher4Bild");
|
||||||
|
screen3 = model.getObjectByName("fernseher3Bild");
|
||||||
|
|
||||||
|
texture_surf_video.flipY = false;
|
||||||
|
texure_ski.flipY = false;
|
||||||
|
texure_ski.offset.set(-0.3, -0.2);
|
||||||
|
|
||||||
|
screen1.material = new THREE.MeshBasicMaterial({
|
||||||
|
map: texture_surf_video,
|
||||||
|
});
|
||||||
|
screen4.material = new THREE.MeshBasicMaterial({
|
||||||
|
map: texure_ski,
|
||||||
|
});
|
||||||
|
screen3.material = new THREE.MeshBasicMaterial({
|
||||||
|
map: texure_ski,
|
||||||
|
});
|
||||||
|
const maxSize = Math.max(size.x, size.y, size.z);
|
||||||
|
const distance = maxSize * 2;
|
||||||
|
|
||||||
|
camera.position.set(center.x, center.y, center.z + distance);
|
||||||
controls.target.copy(center);
|
controls.target.copy(center);
|
||||||
controls.update();
|
controls.update();
|
||||||
|
|
||||||
|
console.log(scene);
|
||||||
model.position.set(0, 0, 0);
|
model.position.set(0, 0, 0);
|
||||||
scene.add(model);
|
scene.add(model);
|
||||||
|
gsapCtx = scrollCamreaGsap(center);
|
||||||
|
|
||||||
document.title = "Model geladen";
|
document.title = "Model geladen";
|
||||||
},
|
},
|
||||||
@@ -104,6 +148,57 @@ function onResize() {
|
|||||||
camera.updateProjectionMatrix();
|
camera.updateProjectionMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scrollCamreaGsap(center) {
|
||||||
|
gsap.registerPlugin(ScrollTrigger);
|
||||||
|
|
||||||
|
const ctx = gsap.context(() => {
|
||||||
|
gsap.to(camera.position, {
|
||||||
|
z: center.z + 5,
|
||||||
|
ease: "none",
|
||||||
|
scrollTrigger: {
|
||||||
|
trigger: canvasRef.value,
|
||||||
|
start: "top top",
|
||||||
|
end: "+=2000",
|
||||||
|
scrub: 1,
|
||||||
|
pin: true,
|
||||||
|
anticipatePin: 1,
|
||||||
|
onUpdate: (self) => {
|
||||||
|
if (self.progress >= 0.8) {
|
||||||
|
controls.enabled = true;
|
||||||
|
|
||||||
|
controls.enableRotate = true;
|
||||||
|
controls.enableZoom = false;
|
||||||
|
controls.enablePan = false;
|
||||||
|
|
||||||
|
screen1.visible = true;
|
||||||
|
screen3.visible = true;
|
||||||
|
screen4.visible = true;
|
||||||
|
setVideoActive(true);
|
||||||
|
} else {
|
||||||
|
controls.enabled = false;
|
||||||
|
screen1.visible = false;
|
||||||
|
screen3.visible = false;
|
||||||
|
screen4.visible = false;
|
||||||
|
setVideoActive(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, canvasRef.value);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVideoActive(active) {
|
||||||
|
if (active) {
|
||||||
|
video_surf.play();
|
||||||
|
video_ski.play();
|
||||||
|
} else {
|
||||||
|
video_surf.pause();
|
||||||
|
video_ski.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(onResize);
|
const resizeObserver = new ResizeObserver(onResize);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -119,28 +214,39 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener("resize", onResize);
|
window.removeEventListener("resize", onResize);
|
||||||
resizeObserver.disconnect();
|
resizeObserver.disconnect();
|
||||||
renderer?.dispose();
|
renderer?.dispose();
|
||||||
|
gsapCtx?.revert();
|
||||||
|
ScrollTrigger.getAll().forEach((t) => t.kill());
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="spacer"></div>
|
<!-- <div class="spacer"></div> -->
|
||||||
|
|
||||||
<canvas class="canvas" ref="canvasRef"></canvas>
|
<canvas class="canvas" ref="canvasRef"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="scroll-buffer"></div>
|
||||||
|
<div class="spacer"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.spacer {
|
.spacer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 20vh;
|
height: 200vh;
|
||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
.canvas {
|
.canvas {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: block;
|
}
|
||||||
|
.scroll-buffer {
|
||||||
|
height: 100vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ onUnmounted(() => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="parallax__content">
|
<section class="parallax__content">
|
||||||
<div ref="childRef" class="model__wrapper">
|
<!-- <div ref="childRef" class="model__wrapper">
|
||||||
<MonitorModel />
|
<MonitorModel />
|
||||||
</div>
|
</div> -->
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { onMounted, nextTick } from "vue";
|
|||||||
import gsap from "gsap";
|
import gsap from "gsap";
|
||||||
import ScrollTrigger from "gsap/ScrollTrigger";
|
import ScrollTrigger from "gsap/ScrollTrigger";
|
||||||
import ScrollSmoother from "gsap/ScrollSmoother";
|
import ScrollSmoother from "gsap/ScrollSmoother";
|
||||||
|
import MonitorModel from "../components/sections/MonitorModel.vue";
|
||||||
|
|
||||||
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
|
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ onMounted(async () => {
|
|||||||
<div id="smooth-wrapper">
|
<div id="smooth-wrapper">
|
||||||
<div id="smooth-content">
|
<div id="smooth-content">
|
||||||
<WelcomeSection id="welcome" />
|
<WelcomeSection id="welcome" />
|
||||||
|
<MonitorModel id="model" />
|
||||||
<!-- <HeroSection id="hero" /> -->
|
<!-- <HeroSection id="hero" /> -->
|
||||||
<ImageSection id="image" />
|
<ImageSection id="image" />
|
||||||
<TextSection id="text" />
|
<TextSection id="text" />
|
||||||
|
|||||||
Reference in New Issue
Block a user