基于uni-app和 Three.js 开发一款DIY蛋糕应用

环境搭建

1. 安装Node.js和npm

首先,确保的开发环境中安装了Node.js和npm。可以从 Node.js官网 下载并安装最新的LTS版本。

bash 复制代码
node -v
npm -v

2. 安装HBuilderX

HBuilderX 是由DCloud推出的支持uni-app开发的IDE。下载并安装HBuilderX:

3. 安装uni-app CLI(可选)

使用命令行,可以安装uni-app的CLI工具:

bash 复制代码
npm install -g @vue/cli
npm install -g @dcloudio/uni-app

创建uni-app项目

1. 使用HBuilderX创建项目

  1. 打开HBuilderX。
  2. 点击"文件" > "新建" > "项目"。
  3. 选择"uni-app"模板,填写项目名称(如DIYCakeApp),选择项目保存路径,点击"创建"。

2. 使用命令行创建项目(可选)

如果使用命令行:

bash 复制代码
vue create -p dcloudio/uni-preset-vue DIYCakeApp
cd DIYCakeApp

集成Three.js

1. 安装Three.js

在项目根目录下,通过npm安装Three.js:

bash 复制代码
npm install three

2. 引入Three.js

在需要使用Three.js的页面或组件中引入:

javascript 复制代码
import * as THREE from 'three';

设计3D蛋糕模型

1. 准备3D模型

使用Three.js自带的几何体(如圆柱体、球体等)组合成蛋糕,也可以使用3D建模软件(如Blender)创建复杂模型,并导出为Three.js支持的格式(如GLTF)。

2. 使用Three.js创建基本蛋糕模型

以下是一个简单的蛋糕模型示例:

javascript 复制代码
// 创建场景
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);

// 将渲染器的DOM添加到页面
document.getElementById('three-container').appendChild(renderer.domElement);

// 添加蛋糕主体(圆柱体)
const cakeGeometry = new THREE.CylinderGeometry(1, 1, 0.5, 32);
const cakeMaterial = new THREE.MeshBasicMaterial({ color: 0xff69b4 });
const cake = new THREE.Mesh(cakeGeometry, cakeMaterial);
scene.add(cake);

// 添加蛋糕装饰(例如球体表示水果)
const decorationGeometry = new THREE.SphereGeometry(0.1, 16, 16);
const decorationMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const decoration = new THREE.Mesh(decorationGeometry, decorationMaterial);
decoration.position.set(0.5, 0.3, 0);
scene.add(decoration);

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  
  // 旋转蛋糕
  cake.rotation.y += 0.01;
  decoration.rotation.y += 0.02;
  
  renderer.render(scene, camera);
}
animate();

3. 在uni-app中集成3D场景

在uni-app页面中,添加一个用于渲染Three.js的容器。例如,在pages/index/index.vue中:

html 复制代码
<template>
  <view class="container">
    <view id="three-container" class="three-container"></view>
  </view>
</template>

<script>
import * as THREE from 'three';

export default {
  onReady() {
    this.initThree();
  },
  methods: {
    initThree() {
      // 与上述示例相同的Three.js初始化代码
      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);
      document.getElementById('three-container').appendChild(renderer.domElement);

      const cakeGeometry = new THREE.CylinderGeometry(1, 1, 0.5, 32);
      const cakeMaterial = new THREE.MeshBasicMaterial({ color: 0xff69b4 });
      const cake = new THREE.Mesh(cakeGeometry, cakeMaterial);
      scene.add(cake);

      const decorationGeometry = new THREE.SphereGeometry(0.1, 16, 16);
      const decorationMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
      const decoration = new THREE.Mesh(decorationGeometry, decorationMaterial);
      decoration.position.set(0.5, 0.3, 0);
      scene.add(decoration);

      function animate() {
        requestAnimationFrame(animate);
        cake.rotation.y += 0.01;
        decoration.rotation.y += 0.02;
        renderer.render(scene, camera);
      }
      animate();
    }
  }
}
</script>

<style>
.container {
  width: 100%;
  height: 100vh;
}
.three-container {
  width: 100%;
  height: 100%;
}
</style>

实现用户交互

为了让用户能够DIY蛋糕,需要实现以下交互功能:

  1. 选择蛋糕基底:不同的蛋糕形状或口味。
  2. 添加装饰:添加水果、奶油、糖霜等装饰。
  3. 颜色选择:更改蛋糕和装饰的颜色。
  4. 视角控制:允许用户旋转、缩放和移动视角。

1. 添加控制器

使用OrbitControls来实现视角控制。首先,引入OrbitControls:

javascript 复制代码
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

然后,在初始化Three.js时添加控制器:

javascript 复制代码
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 使动画更流畅

在渲染循环中更新控制器:

javascript 复制代码
function animate() {
  requestAnimationFrame(animate);
  
  controls.update(); // 更新控制器

  cake.rotation.y += 0.01;
  decoration.rotation.y += 0.02;
  
  renderer.render(scene, camera);
}

2. 添加UI控件

在uni-app中使用<button>或自定义组件来作为用户交互的控件。例如,添加颜色选择按钮:

html 复制代码
<template>
  <view class="container">
    <view id="three-container" class="three-container"></view>
    <view class="controls">
      <button @click="changeCakeColor('#ff69b4')">粉红色</button>
      <button @click="changeCakeColor('#8a2be2')">蓝紫色</button>
      <!-- 更多颜色按钮 -->
    </view>
  </view>
</template>

<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

export default {
  data() {
    return {
      cakeMaterial: null,
      decorationMaterial: null,
    }
  },
  onReady() {
    this.initThree();
  },
  methods: {
    initThree() {
      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);
      document.getElementById('three-container').appendChild(renderer.domElement);

      const cakeGeometry = new THREE.CylinderGeometry(1, 1, 0.5, 32);
      this.cakeMaterial = new THREE.MeshBasicMaterial({ color: 0xff69b4 });
      const cake = new THREE.Mesh(cakeGeometry, this.cakeMaterial);
      scene.add(cake);

      const decorationGeometry = new THREE.SphereGeometry(0.1, 16, 16);
      this.decorationMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
      const decoration = new THREE.Mesh(decorationGeometry, this.decorationMaterial);
      decoration.position.set(0.5, 0.3, 0);
      scene.add(decoration);

      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true;

      const animate = () => {
        requestAnimationFrame(animate);
        controls.update();
        cake.rotation.y += 0.01;
        decoration.rotation.y += 0.02;
        renderer.render(scene, camera);
      };
      animate();
    },
    changeCakeColor(color) {
      if (this.cakeMaterial) {
        this.cakeMaterial.color.set(color);
      }
    }
  }
}
</script>

<style>
.container {
  position: relative;
  width: 100%;
  height: 100vh;
}
.three-container {
  width: 100%;
  height: 100%;
}
.controls {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
}
button {
  padding: 10px 20px;
  background-color: #ffffffaa;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
button:hover {
  background-color: #ffffff;
}
</style>

3. 动态添加装饰

允许用户从预设的装饰列表中选择并添加到蛋糕上。以下是一个简单的实现示例:

javascript 复制代码
methods: {
  // ...之前的代码
  addDecoration(color) {
    const decorationGeometry = new THREE.SphereGeometry(0.1, 16, 16);
    const decorationMaterial = new THREE.MeshBasicMaterial({ color });
    const decoration = new THREE.Mesh(decorationGeometry, decorationMaterial);
    decoration.position.set(Math.random() - 0.5, Math.random() * 0.5, Math.random() - 0.5);
    this.$refs.scene.add(decoration);
  }
}

在UI中添加按钮调用addDecoration方法:

html 复制代码
<button @click="addDecoration('#00ff00')">添加绿色装饰</button>
<button @click="addDecoration('#0000ff')">添加蓝色装饰</button>

注意 :确保在Three.js的初始化代码中将场景对象存储在this.$refs.scene或其他可访问的位置。

如果喜欢,或者帮助启发到你,送给我star吧~

相关推荐
GISer_Jing1 小时前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪2 小时前
CSS复习
前端·css
咖啡の猫4 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲6 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5817 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路7 小时前
GeoTools 读取影像元数据
前端
ssshooter8 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry8 小时前
Jetpack Compose 中的状态
前端
dae bal9 小时前
关于RSA和AES加密
前端·vue.js
柳杉9 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化