three.js + vue 实现物体公转(three.js实现简单动画)

 目录

一、动画实质

1、position

2、rotation

3、scale

二、整体思路

三、核心代码

四、源码解析 

1、创建球体(父元素)

2、创建立方体(目标元素) 

3、旋转父元素


实现目标:正方体在 x=4 的位置,绕y轴公转;

正方体公转运动

一、动画实质

让三维物体做动画的实质,其实就是做【平移、旋转、放缩】;

在three.js中对应【position、rotation、scale】这三个Object3D物体的属性,其中:

1、position

是一个三维向量,默认值是(0,0,0);

表示物体相对于原点(0,0,0)在x,y,z轴上的偏移量;

2、rotation

是一个三维向量,默认值是(0,0,0);

表示物体沿着x,y,z轴方向的旋转分量,用弧度表示;

3、scale

是一个三维向量,默认值是(1,1,1);

表示物体在x,y,z轴方向放缩分量;

二、整体思路

three.js中虽然有改变物体旋转的属性【rotation】,但它紧紧只能改变自身沿着x,y,z轴方向的旋转分量,想要实现物体的公转效果还是不够的;

我们可以借助另外一个属性【parent】,这个属性是指一个对象的父级对象;

有了这个属性,我们可以这样做:

  • 先创建一个父级对象,再创建目标物体并添加到父级对象中;
  • 根据旋转中心(比如y轴)设置好父级对象的位置(可以设在原点);
  • 再改变目标物体在x轴、z轴上的【position】偏移量;
  • 最后,让父级元素沿着目标轴(y轴)旋转,即可带动我们的目标元素公转;

三、核心代码

threejs.vue 

<template>
  <div class="box" ref="box"></div>
</template>
<script>
// 引入three.js
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default {
  name: "ThreeJs",
  methods: {
    getThreeJs() {
      // 创建场景
      const scene = new THREE.Scene();

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        100
      );
      camera.position.set(10, 10, 10); // 设置相机位置
      camera.lookAt(0, 0, 0); // 设置相机看向原点

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      const box = this.$refs.box; // 获取元素
      box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素

      // 添加辅助坐标
      const axesHelper = new THREE.AxesHelper(20);
      scene.add(axesHelper);

      // 添加轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      // 设置带阻尼的惯性
      controls.enableDamping = true;
      // 设置阻尼的系数
      controls.dampingFactor = 0.05;
      // 设置自动旋转
      // controls.autoRotate = true;

      // 创建球体
      const sphere = new THREE.SphereGeometry(0.0001, 32, 16);
      const sphereMaterial = new THREE.MeshBasicMaterial();
      const ball = new THREE.Mesh(sphere, sphereMaterial);
      scene.add(ball);

      // 创建立方体
      const geometry = new THREE.BoxGeometry(2, 2, 2);
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new THREE.Mesh(geometry, material);
      cube.position.set(4, 0, 0);
      ball.add(cube);

      // 声明渲染函数
      function animate() {
        // 球体旋转指定度数; 2π(弧度) = 360°
        ball.rotation.y -= Math.PI / 180;   // + 为逆时针;-为顺时针;
        controls.update(); // 更新控制器
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
      }
      animate();

      // 监听窗口变化
      window.addEventListener("resize", () => {
        // 重置渲染器宽高比
        renderer.setSize(window.innerWidth, window.innerHeight);
        // 重置相机宽高比
        camera.aspect = window.innerWidth / window.innerHeight;
        // 更新相机的投影矩阵
        camera.updateProjectionMatrix();
      });
    },
  },
  mounted() {
    this.getThreeJs(); // 执行three的相关代码
  },
};
</script>
<style scoped>
.box {
  width: 100%;
  height: 100%;
}
</style>

App.vue

<template>
  <div>
    <!-- 使用ThreeJs组件 -->
    <ThreeJs />
  </div>
</template>

<script>
// 引入ThreeJs组件
import ThreeJs from "./components/threejs.vue";
export default {
  name: "App",
  components: {
    ThreeJs, // 注册ThreeJs组件
  },
};
</script>

<style>
* {
  padding: 0;
  margin: 0;
}
</style>

四、源码解析 

***此时,只对核心代码进行简单说明,其他的相关代码,请参考:vue+three.js结合开发示例

1、创建球体(父元素)

首先,使用【球缓冲几何体(SphereGeometry)】创建一个球体实例对象,传入三个参数,分别是半径、水平分段数、 垂直分段数;

注意,球体半径我们可以设置的稍微小一些,这样渲染出来后的效果,它几乎就是不可见的;

最后,将创建好的球体实例对象添加到场景中;

// 创建球体
const sphere = new THREE.SphereGeometry(0.0001, 32, 16);
const sphereMaterial = new THREE.MeshBasicMaterial();
const ball = new THREE.Mesh(sphere, sphereMaterial);
scene.add(ball);

2、创建立方体(目标元素) 

首先,使用【立方缓冲几何体(BoxGeometry)】创建一个立方体实例对象,分别传入长、宽、高三个参数;

其次,使用【 set() 】方法,设置立方体的位置为(4,0,0);

最后,将这个立方体添加到ball中,让ball球体作为它的父元素;

// 创建立方体
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(4, 0, 0);
ball.add(cube);

3、旋转父元素

在渲染函数中让父元素ball沿着y轴进行旋转,每次屏幕刷新时旋转1°(rotation为弧度制);

顺时针每次+1;逆时针每次-1;

这样一来,父元素的旋转会带动目标元素立方体的旋转,也就实现了立方体绕y轴公转的效果;

// 球体旋转指定度数; 2π(弧度) = 360°
ball.rotation.y -= Math.PI / 180;   // + 为逆时针;-为顺时针;

==================================================================================================================================================

至此,已经能够简单做出物体公转效果,可以试试公转的同时加上自转呢?或者进一步做一个简易版的太阳系效果呢?

一整个期待住了~~~

有问题还请大家指正,不吝赐教!!!

以下是使用three.jsVue实现机械臂摆动的示例代码: ```html <template> <div ref="container"></div> </template> <script> import * as THREE from 'three'; export default { mounted() { // 创建场景 const scene = new THREE.Scene(); // 创建相机 const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; // 创建渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); this.$refs.container.appendChild(renderer.domElement); // 创建机械臂 const arm = new THREE.Object3D(); const base = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshNormalMaterial() ); base.position.y = 0.5; arm.add(base); const joint1 = new THREE.Mesh( new THREE.SphereGeometry(0.5), new THREE.MeshNormalMaterial() ); joint1.position.y = 1; arm.add(joint1); const link1 = new THREE.Mesh( new THREE.BoxGeometry(0.5, 2, 0.5), new THREE.MeshNormalMaterial() ); link1.position.y = 2; arm.add(link1); const joint2 = new THREE.Mesh( new THREE.SphereGeometry(0.5), new THREE.MeshNormalMaterial() ); joint2.position.y = 3; arm.add(joint2); const link2 = new THREE.Mesh( new THREE.BoxGeometry(0.5, 2, 0.5), new THREE.MeshNormalMaterial() ); link2.position.y = 4; arm.add(link2); const joint3 = new THREE.Mesh( new THREE.SphereGeometry(0.5), new THREE.MeshNormalMaterial() ); joint3.position.y = 5; arm.add(joint3); const link3 = new THREE.Mesh( new THREE.BoxGeometry(0.5, 2, 0.5), new THREE.MeshNormalMaterial() ); link3.position.y = 6; arm.add(link3); scene.add(arm); // 创建灯光 const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 0, 10); scene.add(light); // 渲染场景 const animate = () => { requestAnimationFrame(animate); arm.rotation.x += 0.01; arm.rotation.y += 0.01; renderer.render(scene, camera); }; animate(); }, }; </script> ``` 这段代码创建了一个机械臂模型,并通过旋转机械臂的角度来实现摆动效果。你可以将这段代码放入Vue组件中,然后在页面中渲染出来。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值