threejs打造3d跑车竞赛动画效果
代码语言:html
所属分类:三维
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
cursor: move;
}
</style>
</head>
<body translate="no">
<script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/three.js"></script>
<script src='http://repo.bfw.wiki/bfwrepo/js/OrbitControls.js'></script>
<script src='http://repo.bfw.wiki/bfwrepo/js/dat.gui.min.js'></script>
<script >
window.addEventListener("DOMContentLoaded", app);
function app() {
var scene,
camera,
renderer,
textureLoader = new THREE.TextureLoader(),
controls,
GUI,
road,
cybertruck,
ambientLight,
daylight,
fogColor;
var adjustWindow = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
},
init = () => {
// setup
let licensePlate = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d982ef313.png"),
grassTile = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d982ef313.png"),
roadTile = textureLoader.load("http://repo.bfw.wiki/bfwrepo/image/5df5d96d46d8e.png");
scene = new THREE.Scene();
fogColor = {
h: 215,
s: 80,
l: 80 };
scene.fog = new THREE.Fog(`hsl(${fogColor.h},${fogColor.s}%,${fogColor.l}%)`, 0.01, 272);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(20, 10, 20);
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer({
logarithmicDepthBuffer: false });
renderer.setClearColor(scene.fog.color.getStyle());
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
let camControls = new THREE.OrbitControls(camera, renderer.domElement);
camControls.enablePan = false;
// road
road = new Road(grassTile, roadTile);
// cybertruck
cybertruck = new Cybertruck(licensePlate);
cybertruck.mesh.name = "Cybertruck";
cybertruck.mesh.position.y = cybertruck.height / 2;
// ambient light
ambientLight = new THREE.AmbientLight(0xffffff);
ambientLight.intensity = 1;
scene.add(ambientLight);
// daylight
daylight = new THREE.PointLight(0xffffff, ambientLight.intensity * 2);
daylight.position.set(0, 64, 0);
daylight.castShadow = true;
scene.add(daylight);
// config
controls = {
daylight: ambientLight.intensity,
speed: cybertruck.speed,
resetCam: () => {
camControls.reset();
} };
GUI = new dat.GUI();
GUI.add(controls, "daylight", 0.1, 1, 0.01).name("Daylight").onChange(e => {
let newVal = controls.daylight;
cybertruck.headlight.intensity = (1 - newVal) * 2;
cybertruck.rearlight.intensity = (1 - newVal) * 2;
ambientLight.intensity = newVal;
daylight.intensity = newVal * 2;
let h = fogColor.h,
s = fogColor.s,
l = newVal * 100;
fogColor.l = l * 0.8;
let daylightColorStr = `hsl(${h},${s}%,${l.toFixed(0)}%)`,
fogColorStr = `hsl(${h},${s}%,${fogColor.l.toFixed(0)}%)`;
daylight.color = new THREE.Color(daylightColorStr);
renderer.setClearColor(fogColorStr);
scene.fog.color.set(fogColorStr);
});
GUI.add(controls, "speed", 0, 60, 1).name("Speed (MPH)").onChange(e => {
cybertruck.speed = controls.speed;
});
GUI.add(controls, "resetCam").name("Reset Camera");
// first render
document.body.appendChild(renderer.domElement);
renderScene();
},
renderScene = () => {
updateObjects();
renderer.render(scene, camera);
requestAnimationFrame(renderScene);
},
spawnObjects = () => {
scene.add(road.mesh);
scene.add(cybertruck.mesh);
},
updateObjects = () => {
if (scene.getObjectByName(cybertruck.mesh.name)) {
cybertruck.move();
if (cybertruck.mesh.position.z > road.tileSize)
cybertruck.mesh.position.z -= road.tileSize;
let cybertruckZ = cybertruck.mesh.position.z;
daylight.position.z = cybertruckZ;
scene.position.z = -cybertruckZ;
}
};
init();
window.addEventListener("load", spawnObjects);
window.addEventListener("resize", adjustWindow);
}
class Cybertruck {
constructor(licensePlateImg) {
this.speed = 5;
this.wireframes = false;
this.width = 8;
this.height = 7.5;
this.depth = 23;
this.mesh = new THREE.Object3D();
let W = this.width,
H = this.height,
D = this.depth,
flipXVertices = a => [-a[0], a[1], a[2]],
toVectors = a => new THREE.Vector3(W * a[0], H * a[1], D * a[2]),
reverseFaceDraws = a => a.reverse(),
toFaces = a => new THREE.Face3(a[0], a[1], a[2]);
// I. Body
// A. Main
let bodyVerticesArr = [
// back (0–3)
[-0.45, 0.26, -0.5],
[0.45, 0.26, -0.5],
[-0.45, -0.1, -0.48],
[0.45, -0.1, -0.48],
// top (4–5)
[-0.326, 0.5, 0.08],
[0.326, 0.5, 0.08],
// middle (6–19)
[-0.45, -0.1, -0.38],
[0.45, -0.1, -0.38],
[-0.45, 0.06, -0.36],
[0.45, 0.06, -0.36],
[-0.45, 0.06, -0.24],
[0.45, 0.06, -0.24],
[-0.45, -0.15, -0.18],
[0.45, -0.15, -0.18],
[-0.45, -0.17, 0.255],
[0.45, -0.17, 0.255],
[-0.45, 0.06, 0.303],
[0.45, 0.06, 0.303],
[-0.45, 0.06, 0.42],
[0.45, 0.06, 0.42],
// upper front (20–23)
[-0.45, 0.08, 0.47],
[0.45, 0.08, 0.47],
[-0.33, 0.045, 0.5],
[0.33, 0.045, 0.5],
// lower front (24–27)
[-0.45, -0.13, 0.46],
[0.45, -0.13, 0.46],
[-0.343, -0.13, 0.488],
[0.343, -0.13, 0.488],
// bottom flaps (28–31)
[-0.41, -0.21, -0.173],
[0.41, -0.21, -0.173],
[-0.41, -0.23, 0.25],
[0.41, -0.23, 0.25],
// windows (32–39)
[-0.4225, 0.27, -0.14],
[0.4225, 0.27, -0.14],
[-0.379, 0.39, -0.13],
[0.379, 0.39, -0.13],
[-0.337, 0.47, 0.08],
[0.337, 0.47, 0.08],
[-0.425, 0.17, 0.36],
[0.425, 0.17, 0.36]],
bodyVertices = bodyVerticesArr.map(toVectors),
bodyFacesArr = [
[0, 1, 3],
[3, 2, 0],
[0, 4, 5],
[5, 1, 0],
[5, 37, 35],
[1, 5, 35],
[1, 35, 33],
[33, 21, 1],
[39, 21, 33],
[5, 21, 37],
[21, 39, 37],
[4, 34, 36],
[0, 34, 4],
[0, 32, 34],
[32, 0, 20],
[38, 32, 20],
[4, 36, 20],
[20, 36, 38],
[20, 18, 24],
[20, 0, 18],
[18, 0, 16],
[16, 0, 10],
[10, 0, 8],
[8, 0, 2],
[2, 6, 8],
[16, 10, 14],
[12, 14, 10],
[14, 12, 28],
[28, 30, 14],
[21, 25, 19],
[21, 19, 1],
[19, 17, 1],
[17, 11, 1],
[11, 9, 1],
[1, 9, 7],
[7, 3, 1],
[11, 17, 15],
[15, 13, 11],
[15, 31, 29],
[29, 13, 15],
[5, 4, 20],
[20, 21, 5],
[21, 20, 22],
[22.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0