Hello everyone,
I found a repo:
where author created a tube, which follows specific points and I was wondering if I could do the same, but to create terrain with the exact same behaviour. To be more specific:
this is the effect I’m looking for, where camera moves on scroll and follows the road.
I tried to look for something related, but could not find anything helpful, so I thought that maybe I’m not on a correct path to do this and there’s another way.
Please consider that I am a beginner and update or note will be helpful.
Here is my updated code if that helps (replace everything in index.js)
import * as THREE from "three";
import spline from "./spline.js";
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 10);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputColorSpace = THREE.SRGBColorSpace;
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', ()=> {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
const tubeGeo = new THREE.TubeGeometry(spline, 252, 1.65, 36, true);
const edges = new THREE.EdgesGeometry(tubeGeo, 0.2);
const lineMat = new THREE.LineBasicMaterial({ color: 0xcccccc });
const tubeLines = new THREE.LineSegments(edges, lineMat);
scene.add(tubeLines);
function updateCamera(t) {
const time = t * 0.1;
const looptime = 10 * 1000;
const p = (time % looptime) / looptime;
const pos = tubeGeo.parameters.path.getPointAt(p);
const lookAt = tubeGeo.parameters.path.getPointAt((p + 0.03) % 1);
camera.position.copy(pos);
camera.lookAt(lookAt);
}
let zoomInterval
let t = 0
window.addEventListener("wheel", (e) => {
zoomInterval && clearInterval(zoomInterval)
if (e.deltaY < 0) {
const current = t
zoomInterval = setInterval(() => {
t -= 20
if(current - t == 1200) clearInterval(zoomInterval)
}, 5);
}
else if (e.deltaY > 0) {
const current = t
zoomInterval = setInterval(() => {
t += 20
if(current - t == -1200) clearInterval(zoomInterval)
}, 5);
}
if(t <= 100) t = 0
})
updateCamera(t)
function animate() {
requestAnimationFrame(animate);
updateCamera(t)
renderer.render(scene, camera)
}
animate();
Thank you in advance and have a great day!