返回

用three.js描绘一幅活灵活现的兔子——献给兔年的专属礼物

前端

用 three.js 勾勒兔子的灵动:为兔年献上一份代码艺术

作为一名技术博客创作专家,我总是热衷于从独特的视角审视事物,并在此基础上构建文章。今天,让我带你踏上一次奇妙的旅程,探索如何利用 three.js 的强大功能,用代码勾勒出一幅惟妙惟肖的兔子,为即将到来的兔年献上一份别致的礼物。

用 three.js 开启图形世界的冒险

three.js,一个声名赫赫的图形库,以其简洁易用的特性,为开发者在图形领域驰骋提供了广阔的天地。而我们今天要做的,仅仅用几十行代码,就能将一只栩栩如生的兔子呈现在网页上。

从零开始,构建兔子模型

首先,让我们从一个空白的画布开始。创建一个新的 HTML 文件,并引入 three.js 库:

<html>
<head>
  
  <script src="three.js"></script>
</head>
<body>
  <canvas id="webgl-output"></canvas>
  <script>
    // 你的 three.js 代码将在此处书写
  </script>
</body>
</html>

接下来,是时候让 three.js 大显身手了。在<script>标签内,编写以下代码:

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;

// 创建渲染器
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector('#webgl-output')});
renderer.setSize(window.innerWidth, window.innerHeight);

// 创建兔子模型
const geometry = new THREE.BoxGeometry(0.5, 1, 0.5);
const material = new THREE.MeshBasicMaterial({color: 0xffffff});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 渲染场景
function animate() {
  requestAnimationFrame(animate);

  // 旋转兔子
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  // 渲染
  renderer.render(scene, camera);
}

animate();

随着这些代码的注入,一个简单的兔子模型便诞生了。现在,让我们赋予它生命,让它动起来。

让兔子动起来,注入灵动的生命力

animate()函数中,加入以下代码:

// 旋转兔子
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

这段代码会以每秒 0.01 弧度的速度旋转兔子,为它注入灵动的生命力。

三维展示,让兔子跃然眼前

现在,我们的兔子已经跃然眼前了。但仅仅是一个静态的模型,还远远不够。让我们借助 three.js 强大的三维展示能力,让兔子真正动起来。

// 创建轨迹控制器
const controls = new THREE.OrbitControls(camera, renderer.domElement);

这段代码添加了一个轨迹控制器,允许你从各个角度观察兔子,欣赏它的立体美感。

点睛之笔,赋予兔子兔子的特征

至此,我们的兔子已经初具雏形。但要让它真正栩栩如生,少不了兔子的标志性特征——长耳朵。

// 创建兔子耳朵
const earGeometry = new THREE.BoxGeometry(0.1, 0.5, 0.1);
const earMaterial = new THREE.MeshBasicMaterial({color: 0xffffff});
const ear1 = new THREE.Mesh(earGeometry, earMaterial);
ear1.position.set(0.25, 1, 0);
const ear2 = new THREE.Mesh(earGeometry, earMaterial);
ear2.position.set(-0.25, 1, 0);
cube.add(ear1);
cube.add(ear2);

通过这几行代码,我们为兔子添加了一对可爱的耳朵,让它的形象更加饱满。

完善细节,让兔子更加灵动逼真

为了让兔子更加灵动逼真,我们还可以添加一些细节,比如胡须和眼睛。

// 创建兔子胡须
const whiskerGeometry = new THREE.Geometry();
whiskerGeometry.vertices.push(new THREE.Vector3(0, 0.5, 0));
whiskerGeometry.vertices.push(new THREE.Vector3(0.1, 0.75, 0));
const whiskerMaterial = new THREE.LineBasicMaterial({color: 0x000000});
const whisker1 = new THREE.Line(whiskerGeometry, whiskerMaterial);
whisker1.position.set(0.2, 0.5, 0.25);
const whisker2 = new THREE.Line(whiskerGeometry, whiskerMaterial);
whisker2.position.set(-0.2, 0.5, 0.25);
cube.add(whisker1);
cube.add(whisker2);

// 创建兔子眼睛
const eyeGeometry = new THREE.SphereGeometry(0.05, 16, 16);
const eyeMaterial = new THREE.MeshBasicMaterial({color: 0x000000});
const eye1 = new THREE.Mesh(eyeGeometry, eyeMaterial);
eye1.position.set(0.2, 0.6, 0.3);
const eye2 = new THREE.Mesh(eyeGeometry, eyeMaterial);
eye2.position.set(-0.2, 0.6, 0.3);
cube.add(eye1);
cube.add(eye2);

有了这些细节的点缀,我们的兔子更加栩栩如生,灵动可爱。

总结

至此,我们已经用 three.js 成功绘制了一只活灵活现的兔子。从简单的几何体到细节的完善,我们一步步地将代码转化为一个生动的艺术品。

随着 three.js 的不断发展,我们探索图形世界的可能性也越来越广阔。用代码创造出栩栩如生的场景,描绘出动人心弦的故事,这正是 three.js 的魅力所在。

希望这篇博文能激发你的灵感,让你踏上 three.js 的奇妙之旅。愿你在图形的海洋中乘风破浪,创造出更多令人惊叹的作品。

常见问题解答

1. 如何让兔子移动?

// 在 animate() 函数中添加以下代码:
cube.position.x += 0.01; // 向 x 轴移动
cube.position.y += 0.01; // 向 y 轴移动

2. 如何改变兔子的颜色?

// 更改 material.color 属性
material.color.set(0xff0000); // 红色
material.color.set(0x00ff00); // 绿色
material.color.set(0x0000ff); // 蓝色

3. 如何添加纹理到兔子身上?

// 加载纹理图像
const texture = new THREE.TextureLoader().load('rabbit-texture.jpg');

// 应用纹理到材质
material.map = texture;

4. 如何让兔子跳跃?

// 在 animate() 函数中添加以下代码:
cube.position.y += Math.sin(Date.now() / 1000) * 0.1; // 根据时间进行正弦运动

5. 如何让兔子与用户交互?

// 使用 Raycaster 检测鼠标点击
const raycaster = new THREE.Raycaster();

// 添加事件监听器
renderer.domElement.addEventListener('click', (event) => {
  const mouse = new THREE.Vector2();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObject(cube);

  if (intersects.length > 0) {
    // 兔子被点击了,可以执行操作
  }
});