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