threejs实现三维恐龙滑板动画效果代码

代码语言:html

所属分类:三维

代码描述:threejs实现三维恐龙滑板动画效果代码

代码标签: three 恐龙 三维 滑板

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  
<style>
body {
  margin: 0;
}
.world {
  position: absolute;
  overflow: hidden;
  width: 100%;
  height: 100%;
  background-color: #65BDCC;
}
.toggle-music {
  position: absolute;
  top: 1rem;
  left: 1rem;
  width: 3rem;
  height: 3rem;
  background: url('//repo.bfw.wiki/bfwrepo/icon/60d1c2f3e1d1e.png') center center / 70% no-repeat;
  cursor: pointer;
}
.music-off {
  background: url('//repo.bfw.wiki/bfwrepo/icon/60d1c2e3eff9a.gif') center center / 60% no-repeat;
}
</style>



</head>

<body  >
  <div class="world"></div><a class="toggle-music"></a>
<audio class="world-music" src="//repo.bfw.wiki/bfwrepo/sound/61397f63d3f7c.mp3"></audio>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.84.js"></script>
      <script>
'use strict';

let scene,
camera,
renderer,
raycaster,
mouseDown,
world,
night = false;

let ground,
city,
dino;

let width,
height;

let speed = 0.05;

function init() {
  width = window.innerWidth,
  height = window.innerHeight;

  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 50);
  camera.position.set(-2, 2, 12);
  camera.lookAt(scene.position);

  renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;

  addLights();
  drawGround();
  drawCity();
  drawDino();

  world = document.querySelector('.world');
  world.appendChild(renderer.domElement);

  document.addEventListener('mousedown', onMouseDown);
  document.addEventListener('mouseup', onMouseUp);
  document.addEventListener('touchstart', onTouchStart);
  document.addEventListener('touchend', onTouchEnd);
  window.addEventListener('resize', onResize);
}

function addLights() {
  const light = new THREE.HemisphereLight();
  scene.add(light);

  const directLight1 = new THREE.DirectionalLight(0xffffff, 0.3);
  directLight1.castShadow = true;
  directLight1.position.set(20, 10, 18);
  scene.add(directLight1);

  const directLight2 = new THREE.DirectionalLight(0xffffff, 0.8);
  directLight2.castShadow = true;
  directLight2.position.set(-14, 6, 14);
  scene.add(directLight2);
}

function drawGround() {
  ground = new THREE.Mesh(new THREE.PlaneGeometry(90, 30), new THREE.MeshStandardMaterial({
    color: 0x375076,
    roughness: 1 }));

  ground.rotation.x = -Math.PI / 2;
  ground.position.y = -0.6;
  ground.receiveShadow = true;
  scene.add(ground);
}

function drawCity() {
  city = new City();
  scene.add(city.group);
}

function drawDino() {
  dino = new Dino();
  scene.add(dino.group);
}

function onResize() {
  width = window.innerWidth;
  height = window.innerHeight;
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
}

function onMouseDown(event) {
  mouseDown = true;
}
function onTouchStart(event) {
  if (event.target.classList[0] === 'toggle-music') return;
  event.preventDefault();
  mouseDown = true;
  if (speed !== 0.1) speed = 0.1;
}

function onMouseUp() {
  mouseDown = false;
}
function onTouchEnd(event) {
  if (event.target.classList[0] === 'toggle-music') return;
  event.preventDefault();
  mouseDown = false;
}

function animate() {
  requestAnimationFrame(animate);

  render();
}

function render() {
  if (mouseDown) {
    city.move(speed * 2);
    dino.moveFast(speed * 2);
  } else {
    city.move(speed);
    dino.move(speed);
  }

  city.road.forEach(bus => {
    bus.moveOut(dino.group.position);
  });

  renderer.render(scene, camera);
}

class City {
  constructor() {
    this.group = new THREE.Group();

    this.city = new THREE.Group();
    this.group.add(this.city);

    this.drawCity();
    this.drawRoad();
    this.drawSky();
  }
  drawCity() {
    this.line1 = new THREE.Group();
    this.line1.position.z = -3;
    this.city.add(this.line1);

    const houses = new THREE.Group();
    houses.name = 'houses';
    this.line1.add(houses);

    const houseMaterial = new THREE.MeshStandardMaterial({
      color: 0x2697A8,
      roughness: 1,
      shading: THREE.FlatShading });


    const windowMaterial = new THREE.MeshStandardMaterial({
      color: 0xEDF0F8,
      roughness: 1,
      shading: THREE.FlatShading });

    const windows = new THREE.Group();
    const window1 = this.drawBox(0.2, 0.4, 0.3, windowMaterial);
    const window2 = window1.clone();
    window2.position.x = 0.3;
    const window3 = window2.clone();
    window3.position.y = 0.5;
    const window4 = window1.clone();
    window4.position.y = 0.5;
    windows.add(window1);
    windows.add(window2);
    windows.add(window3);
    windows.add(window4);

    const house1 = this.drawBox(1, 1.2, 1, houseMaterial);
    const house1Windows = windows.clone();
    house1Windows.position.set(-0.2, -0.2, 0.5);
    house1.add(house1Windows);
    houses.add(house1);

    const house2 = this.drawBox(1.1, 2.4, 1, houseMaterial);
    house2.position.set(1, 0.6, 0);
    const house2Windows = windows.clone();
    house2Windows.position.set(0, 0.3, 0.5);
    house2.add(house2Windows);
    houses.add(house2);

    const house3 = this.drawBox(1.4, 1.6, 1, houseMaterial);
    house3.position.set(2.25, 0.2, 0);
    const house3Windows = windows.clone();
    house3Windows.position.set(0, -0.4, 0.5);
    house3.add(house3Windows);
    houses.add(house3);

    const house4 = this.drawBox(0.9, 1, 1, houseMaterial);
    house4.position.set(3.4, -0.1, 0);
    const house4Window = window1.clone();
    house4Window.position.set(0.2, 0.1, 0.5);
    house4.add(house4Window);
    houses.add(house4);

    const house5 = this.drawBox(1.2, 3.7, 1, houseMaterial);
    house5.position.set(4.5, 1.25, 0);
    const house5Windows = windows.clone();
    house5Windows.position.set(-0.3, -0.2, 0.5);
    house5.add(house5Windows);
    houses.add(house5);

    for (let i = 0; i < 8; i++) {
      const housesClone = houses.clone();
      housesClone.position.x = houses.position.x - 5.6 * (i + 1);
      this.line1.add(housesClone);
    }

    for (let i = 0; i < 8; i++) {
      const housesClone = houses.clone();
      housesClone.position.x = houses.position.x + 5.6 * (i + 1);
      this.line1.add(housesClone);
    }

    this.line2 = this.line1.clone();
    this.line2.position.set(-1, 0.3, -5);
    this.city.add(this.line2);

    this.line3 = this.line1.clone();
    this.line3.position.set(-2, 0.7, -8);
    this.city.add(this.line3);

    this.line4 = this.line1.clone();
    this.line4.position.set(-1.5, 1, -11);
    this.city.add(this.line4);
  }
  drawRoad() {
    this.road = [];

    const colors = [0x65BDCC, 0xC40066, 0xE0C538];

    for (let i = 0; i < 50; i++) {
      const randomColor = colors[Math.floor(Math.random() * colors.length)];
      const bus = new Bus(randomColor);

      bus.group.origX = Math.random() * 80 - 40;
      bus.group.origY = -0.25;
      bus.group.origZ = 0.8 + 3 * i / 12;
      bus.group.position.set(bus.group.origX, bus.group.origY, bus.group.origZ);

      this.group.add(bus.group);
      this.road.push(bus);
    }
  }
  drawSky() {
    this.sky = new THREE.Group();
    this.group.add(this.sky);
    const geometry = new THREE.IcosahedronGeometry(0.2, 0);

    for (let i = 0; i < 150; i++) {
      const material = new THREE.MeshStandardMaterial({
        color: 0xA9EFF9,
        roughness: 1,
        shading: THREE.FlatShading });

      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(Math.random() * 100 - 50,
      Math.random() * 12 + 4,
      Math.random() * 10 - 15);
      this.sky.add(mesh);
    }
  }
  drawCylinder(rTop, rBottom, height, rSeg, material) {
    const cylinder = new THREE.Mesh(new THREE.CylinderGeometry(rTop, rBottom, height, rSeg), material);
    cylinder.castShadow = true;
    cylinder.receiveShadow = true;
    return cylinder;
  }
  drawBox(w, h, d, material) {
    const box = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material);
    box.castShadow = true;
    box.receiveShadow = true;
    return box;
  }
  deg(degrees) {
    return degrees * (Math.PI / 180);
  }
  move(speed) {
    const lineLimits = [56, 54, 52, 53];
    const lines = [this.line1, this.line2, this.line3, this.line4];
    lines.forEach((line, index) => {
      line.traverse(houses => {
        if (houses.name === 'houses') {
          houses.position.x += speed;
          if (houses.position.x > lineLimits[index]) {
            houses.position.x = lineLimits[index] - 95.2;
          }
        }
      });
    });

    this.sky.traverse(cloud => {
      if (cloud instanceof THREE.Mesh) {
        cloud.position.x += speed;
        if (cloud.position.x > 50) {
          cloud.position.x = -50;
        }
      }
    });

    this.road.forEach(bus => {
      bus.move(speed);
    });
  }}


class Dino {
  constructor() {
    this.group = new THREE.Group();
    this.group.position.y = 0.7;
    this.group.position.z = 6;

    this.vAngle = 0;

    this.skinMaterial = new THREE.MeshStandardMaterial({
      color: 0xE0C538,
      roughness: 1,
      shading: THREE.FlatShading });

    this.whiteMaterial = new THREE.MeshStandardMaterial({
      color: 0xEDF0F8,
      roughness: 1,
      shading: THREE.FlatShading });

    this.darkMaterial = new THREE.MeshStandardMaterial({
      color: 0x375076,
      roughness: 1,
      shading: THREE.FlatShading });


    this.drawBody();
    this.drawLegs();

    this.drawAirship();
  }
  drawBody() {
    this.body = new THREE.Group();
    this.body.position.y = 0.75;
    this.body.rotation.set(this.deg(-23.3), this.deg(40), this.deg(34));
    this.group.add(this.body);

    const torso = this.drawCylinder(0.4, 1, 1.3, 4, this.skinMaterial);
    torso.position.y = 0.95;
    this.body.add(torso);

    const back = this.drawCylinder(1, 0.75, 0.85, 4, this.skinMaterial);
    back.position.y = -0.11;
    this.body.add(back);

    this.drawHead();
    this.drawTail();
    this.drawHands();
  }
  drawHead() {
    this.head = new THREE.Group();
    this.head.rotation.set(0, this.deg(-45), this.deg(-20));
    this.head.posit.........完整代码请登录后点击上方下载按钮下载查看

网友评论0