基于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吧~

相关推荐
约定Da于配置40 分钟前
uniapp封装websocket
前端·javascript·vue.js·websocket·网络协议·学习·uni-app
山楂树の1 小时前
xr-frame 模型摆放与手势控制,支持缩放旋转
前端·xr·图形渲染
LBJ辉2 小时前
1. 小众但非常实用的 CSS 属性
前端·css
milk_yan2 小时前
Docker集成onlyoffice实现预览功能
前端·笔记·docker
m0_748255023 小时前
头歌答案--爬虫实战
java·前端·爬虫
noravinsc4 小时前
python md5加密
前端·javascript·python
ac-er88885 小时前
Yii框架优化Web应用程序性能
开发语言·前端·php
cafehaus5 小时前
抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
前端·vue.js·vscode
HoneyMoose6 小时前
可以自己部署的微博 Mastodon
前端
国产化创客6 小时前
物联网网关Web服务器--CGI开发实例BMI计算
服务器·前端·物联网·web网关