Files
Portfolio/src/scene/world/road.ts

51 lines
1.8 KiB
TypeScript

import * as THREE from 'three';
import type { SceneResourceBag } from '@/scene/resources';
export function createRoad(resources: SceneResourceBag) {
const group = new THREE.Group();
const roadGeometry = resources.own('geometry', new THREE.PlaneGeometry(18, 240));
const roadMaterial = resources.own('material', new THREE.MeshStandardMaterial({
color: 0x070b16,
roughness: 0.88,
metalness: 0.12,
}));
const road = new THREE.Mesh(roadGeometry, roadMaterial);
road.rotation.x = -Math.PI / 2;
road.position.z = -92;
group.add(road);
const edgeGeometry = resources.own('geometry', new THREE.BoxGeometry(0.12, 0.035, 240));
const edgeMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0x38dff2 }));
for (const x of [-8.65, 8.65]) {
const edge = new THREE.Mesh(edgeGeometry, edgeMaterial);
edge.position.set(x, 0.035, -92);
group.add(edge);
}
const markerGeometry = resources.own('geometry', new THREE.BoxGeometry(0.14, 0.025, 3.8));
const markerMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0xff9e68 }));
const markers: Array<{ position: { z: number } }> = [];
for (let index = 0; index < 22; index += 1) {
const marker = new THREE.Mesh(markerGeometry, markerMaterial);
marker.position.set(0, 0.045, 8 - index * 10);
markers.push(marker);
group.add(marker);
}
return {
group,
update(distance: number, speed: number) {
const flow = distance * (5 + speed * 8);
for (let index = 0; index < markers.length; index += 1) {
const marker = markers[index];
if (!marker) continue;
marker.position.z = 8 - modulo(index * 10 - flow, 220);
}
},
};
}
function modulo(value: number, divisor: number): number {
return ((value % divisor) + divisor) % divisor;
}