首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Three.js中制作移动/滑动元素?

如何在Three.js中制作移动/滑动元素?
EN

Stack Overflow用户
提问于 2021-11-03 22:53:13
回答 1查看 37关注 0票数 1

我发现了我现在喜欢使用的three.js,但我用键盘箭头创建了一个旋转的汽车动画来控制它,但我不知道如何制作滑动动画(例如,

代码语言:javascript
运行
复制
-> -> ->

)而不是旋转动画。我试着搜索,但除了滑动动画,我甚至不知道如何解释它。有没有人知道你能不能做到?

下面是我的代码:

代码语言:javascript
运行
复制
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>ThreeJS Animation</title>
        <style>            
            body {
              margin: 0;
              font-weight: 100;
              float: none;
              overflow: hidden;
            }
            canvas {
              width: 100%;
              height: 100%;
              margin: 0;
              padding: 0;
            }
        </style>
    </head>
    <body>
        <script src="https://threejs.org/build/three.js"></script>
        <script>
let carBottomColor = "#999";
let carTopColor = "#FFF";
let carWindowColor = "#666";
const scene = new THREE.Scene();
scene.background = new THREE.Color("#f1f1f1");
const car = createCar();
scene.add(car);

const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);

const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(200, 500, 300);
scene.add(dirLight);

const aspectRatio = window.innerWidth / window.innerHeight;
const cameraWidth = 300;
const cameraHeight = cameraWidth / aspectRatio;
const camera = new THREE.OrthographicCamera(
  cameraWidth / -2, // left
  cameraWidth / 2, // right
  cameraHeight / 2, // top
  cameraHeight / -2, // bottom
  200, // near plane
  800 // far plane
);
camera.position.set(200, 200, 200);
camera.lookAt(0, 10, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);

let x = 0;
let y = 0;
let keydown = '';
document.body.addEventListener('keydown', e => {
  keydown = e.key;
});
document.body.addEventListener('keyup', e => {
  keydown = '';
});
const update = () => {
    switch (keydown) {
    case 'ArrowUp':
      x -= 0.1;
      car.rotation.x = x;
      break;
    case 'ArrowDown':
      x += 0.1;
      car.rotation.x = x;
      break;
    case 'ArrowLeft':
      y -= 0.1;
      car.rotation.y = y;
      break;
    case 'ArrowRight':
      y += 0.1;
      car.rotation.y = y;
      break;
  }
  window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);


renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
});

document.body.appendChild(renderer.domElement);

function createCar() {
  const car = new THREE.Group();
  const backWheel = createWheels();
  backWheel.position.y = 6;
  backWheel.position.x = -18;
  car.add(backWheel);

  const frontWheel = createWheels();
  frontWheel.position.y = 6;
  frontWheel.position.x = 18;
  car.add(frontWheel);

  const main = new THREE.Mesh(
    new THREE.BoxBufferGeometry(60, 15, 30),
    new THREE.MeshLambertMaterial({ color: carBottomColor })
  );
  main.position.y = 12;
  car.add(main);

  const carFrontTexture = getCarFrontTexture();

  const carBackTexture = getCarFrontTexture();

  const carRightSideTexture = getCarSideTexture();

  const carLeftSideTexture = getCarSideTexture();
  carLeftSideTexture.center = new THREE.Vector2(0.5, 0.5);
  carLeftSideTexture.rotation = Math.PI;
  carLeftSideTexture.flipY = false;

  const cabin = new THREE.Mesh(new THREE.BoxBufferGeometry(33, 12, 24), [
    new THREE.MeshLambertMaterial({ map: carFrontTexture }),
    new THREE.MeshLambertMaterial({ map: carBackTexture }),
    new THREE.MeshLambertMaterial({ color: carTopColor }), // top
    new THREE.MeshLambertMaterial({ color: carTopColor }), // bottom
    new THREE.MeshLambertMaterial({ map: carRightSideTexture }),
    new THREE.MeshLambertMaterial({ map: carLeftSideTexture })
  ]);
  cabin.position.x = -6;
  cabin.position.y = 25.5;
  car.add(cabin);
  return car;
}

function createWheels() {
  const geometry = new THREE.BoxBufferGeometry(12, 12, 33);
  const material = new THREE.MeshLambertMaterial({ color: "#333" });
  const wheel = new THREE.Mesh(geometry, material);
  return wheel;
}

function getCarFrontTexture() {
  const canvas = document.createElement("canvas");
  canvas.width = 64;
  canvas.height = 32;
  const context = canvas.getContext("2d");

  context.fillStyle = "#ffffff";
  context.fillRect(0, 0, 64, 32);

  context.fillStyle = carWindowColor || carBaseColor; // Wheel color
  context.fillRect(8, 8, 48, 24);

  return new THREE.CanvasTexture(canvas);
}

function getCarSideTexture() {
  const canvas = document.createElement("canvas");
  canvas.width = 128;
  canvas.height = 32;
  const context = canvas.getContext("2d");

  context.fillStyle = "#ffffff";
  context.fillRect(0, 0, 128, 32);

  context.fillStyle = carWindowColor || carBaseColor; // Wheel color
  context.fillRect(10, 8, 38, 24);
  context.fillRect(58, 8, 60, 24);

  return new THREE.CanvasTexture(canvas);
}
        </script>
    </body>
</html>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-04 02:58:54

我做了一些假设,但我认为你要做的是在按左/右箭头时沿y轴旋转汽车,并且在按上/下箭头时尝试将卡片向前移动。如果是这样的话,您可以使用car.translateX()来创建前进/后退运动,使用car.rotation.y来使汽车转弯。

下面是修改后的示例:

代码语言:javascript
运行
复制
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>ThreeJS Animation</title>
        <style>            
            body {
              margin: 0;
              font-weight: 100;
              float: none;
              overflow: hidden;
            }
            canvas {
              width: 100%;
              height: 100%;
              margin: 0;
              padding: 0;
            }
        </style>
    </head>
    <body>
        <script src="https://threejs.org/build/three.js"></script>
        <script>
let carBottomColor = "#999";
let carTopColor = "#FFF";
let carWindowColor = "#666";
const scene = new THREE.Scene();
scene.background = new THREE.Color("#f1f1f1");
const car = createCar();
scene.add(car);

const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);

const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(200, 500, 300);
scene.add(dirLight);

const aspectRatio = window.innerWidth / window.innerHeight;
const cameraWidth = 300;
const cameraHeight = cameraWidth / aspectRatio;
const camera = new THREE.OrthographicCamera(
  cameraWidth / -2, // left
  cameraWidth / 2, // right
  cameraHeight / 2, // top
  cameraHeight / -2, // bottom
  200, // near plane
  800 // far plane
);
camera.position.set(200, 200, 200);
camera.lookAt(0, 10, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);

let x = 0;
let y = 0;
let keydown = '';
document.body.addEventListener('keydown', e => {
  e.preventDefault();
  keydown = e.key;
});
document.body.addEventListener('keyup', e => {
  keydown = '';
});
const update = () => {
    switch (keydown) {
    case 'ArrowUp':
      car.translateX(1.0);
      break;
    case 'ArrowDown':
      car.translateX(-1.0);
      break;
    case 'ArrowLeft':
      y += 0.1;
      car.rotation.y = y;
      break;
    case 'ArrowRight':
      y -= 0.1;
      car.rotation.y = y;
      break;
  }
  window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);


renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
});

document.body.appendChild(renderer.domElement);

function createCar() {
  const car = new THREE.Group();
  const backWheel = createWheels();
  backWheel.position.y = 6;
  backWheel.position.x = -18;
  car.add(backWheel);

  const frontWheel = createWheels();
  frontWheel.position.y = 6;
  frontWheel.position.x = 18;
  car.add(frontWheel);

  const main = new THREE.Mesh(
    new THREE.BoxBufferGeometry(60, 15, 30),
    new THREE.MeshLambertMaterial({ color: carBottomColor })
  );
  main.position.y = 12;
  car.add(main);

  const carFrontTexture = getCarFrontTexture();

  const carBackTexture = getCarFrontTexture();

  const carRightSideTexture = getCarSideTexture();

  const carLeftSideTexture = getCarSideTexture();
  carLeftSideTexture.center = new THREE.Vector2(0.5, 0.5);
  carLeftSideTexture.rotation = Math.PI;
  carLeftSideTexture.flipY = false;

  const cabin = new THREE.Mesh(new THREE.BoxBufferGeometry(33, 12, 24), [
    new THREE.MeshLambertMaterial({ map: carFrontTexture }),
    new THREE.MeshLambertMaterial({ map: carBackTexture }),
    new THREE.MeshLambertMaterial({ color: carTopColor }), // top
    new THREE.MeshLambertMaterial({ color: carTopColor }), // bottom
    new THREE.MeshLambertMaterial({ map: carRightSideTexture }),
    new THREE.MeshLambertMaterial({ map: carLeftSideTexture })
  ]);
  cabin.position.x = -6;
  cabin.position.y = 25.5;
  car.add(cabin);
  return car;
}

function createWheels() {
  const geometry = new THREE.BoxBufferGeometry(12, 12, 33);
  const material = new THREE.MeshLambertMaterial({ color: "#333" });
  const wheel = new THREE.Mesh(geometry, material);
  return wheel;
}

function getCarFrontTexture() {
  const canvas = document.createElement("canvas");
  canvas.width = 64;
  canvas.height = 32;
  const context = canvas.getContext("2d");

  context.fillStyle = "#ffffff";
  context.fillRect(0, 0, 64, 32);

  context.fillStyle = carWindowColor || carBaseColor; // Wheel color
  context.fillRect(8, 8, 48, 24);

  return new THREE.CanvasTexture(canvas);
}

function getCarSideTexture() {
  const canvas = document.createElement("canvas");
  canvas.width = 128;
  canvas.height = 32;
  const context = canvas.getContext("2d");

  context.fillStyle = "#ffffff";
  context.fillRect(0, 0, 128, 32);

  context.fillStyle = carWindowColor || carBaseColor; // Wheel color
  context.fillRect(10, 8, 38, 24);
  context.fillRect(58, 8, 60, 24);

  return new THREE.CanvasTexture(canvas);
}
        </script>
    </body>
</html>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69832654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档