three.js(二)
- 参考
- 前言
- 正文
- 简单开始(不使用任何框架)
- 补充
- 粗略带过(使用Vue框架)
- 细致讲解(比如我使用react框架)
- App.jsx 的进阶版
- 项目打包
- 补充
- 打包遇到的问题:
- 原因:
- 解决办法:
参考
https://threejs.org/docs/
前言
上一集中,我们用到了three.js的一个cdn的方法可以快速搭建一个前端页面,
现在我们尝试使用react框架来打包一下前端页面,然后在运行到我们已经搭建好的cpp-httplib框架搭建的后端服务器.
正文
简单开始(不使用任何框架)
npm init vite@latest
然后一路回车
cd vite-project
npm install
npm run dev
然后你就搭建成功了!
ctrl + c停掉
然后
(base) root@racknerd-cecdb9:~/myspace/three/noFrame-three-app/vite-project# npm install three#假如你就想下0.153的版本,你可以直接npm install three@0.153
然后你就可以使用
https://threejs.org/docs/#manual/zh/introduction/Creating-a-scene
的例子了
(稍作部分修改)
- index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>My first three.js app</title><style>body { margin: 0; }</style></head><body><script type="module" src="src/main.js"></script></body>
</html>
- main.js
import * as THREE from 'three';const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
//创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//创建几何体
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
//创建材质
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//创建网格=几何体+材质
const cube = new THREE.Mesh( geometry, material );
//将网格添加到场景
scene.add( cube );//正对着我们的是z轴
camera.position.z = 5;
//默认看向原点
camera.lookAt(0,0,0);function animate() {//播放下一帧,继续调用animate函数requestAnimationFrame( animate );//旋转cube.rotation.x += 0.01;cube.rotation.y += 0.01;//渲染renderer.render( scene, camera );
}
//调用函数
animate();
然后就直接诶直接可以npm run dev
补充
canvas:画布
粗略带过(使用Vue框架)
npm init vite@latest
然后不要一路回车了!!!!
你可以在这里选择相关的前端框架,你可以看到非常的多,在这里我们选择Vue框架
# 我们选择Vue+JavaScript
✔ Project name: … vite-project
✔ Select a framework: › Vue
✔ Select a variant: › JavaScript
cd vite-project
npm install
npm run dev
然后你就搭建成功了!
ctrl + c停掉
然后
(base) root@racknerd-cecdb9:~/myspace/three/noFrame-three-app/vite-project# npm install three
- 你只需要修改Vue.app,然后npm run dev就欧克了
<script setup>
import * as THREE from 'three';const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
//创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//创建几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
//创建材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//创建网格=几何体+材质
const cube = new THREE.Mesh(geometry, material);
//将网格添加到场景
scene.add(cube);//正对着我们的是z轴
camera.position.z = 5;
//默认看向原点
camera.lookAt(0, 0, 0);function animate() {//播放下一帧,继续调用animate函数requestAnimationFrame(animate);//旋转cube.rotation.x += 0.01;cube.rotation.y += 0.01;//渲染renderer.render(scene, camera);
}
//调用函数
animate();
</script><template><div></div>
</template><style scoped>
.logo {height: 6em;padding: 1.5em;will-change: filter;transition: filter 300ms;
}.logo:hover {filter: drop-shadow(0 0 2em #646cffaa);
}.logo.vue:hover {filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
细致讲解(比如我使用react框架)
npm init vite@latest
然后不要一路回车了!!!!
你可以在这里选择相关的前端框架,你可以看到非常的多,在这里我们选择React框架
选择结果:
Vanilla
✔ Select a framework: › React
✔ Select a variant: › JavaScript
cd vite-project
npm install
npm install three
npm run dev
- 修改App.jsx
import { useState, useEffect, Component } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import * as THREE from 'three';// function App() {
// useEffect(() => {// const scene = new THREE.Scene();
// const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// //创建渲染器
// const renderer = new THREE.WebGLRenderer();
// renderer.setSize(window.innerWidth, window.innerHeight);
// document.body.appendChild(renderer.domElement);
// //创建几何体
// const geometry = new THREE.BoxGeometry(1, 1, 1);
// //创建材质
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// //创建网格=几何体+材质
// const cube = new THREE.Mesh(geometry, material);
// //将网格添加到场景
// scene.add(cube);// //正对着我们的是z轴
// camera.position.z = 5;
// //默认看向原点
// camera.lookAt(0, 0, 0);// //创建轨道控制器
// //const controls = new OrbitControls(camera, renderer.domElement);// function animate() {
// //播放下一帧,继续调用animate函数
// requestAnimationFrame(animate);
// //旋转
// cube.rotation.x += 0.01;
// cube.rotation.y += 0.01;
// //渲染
// renderer.render(scene, camera);
// }
// //调用函数
// animate();
// }, [])// return (
// <>
// <div className='App'></div>// </>
// )
// }class App extends Component {render() {return <div></div>}componentDidMount() {const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);//创建渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);//创建几何体const geometry = new THREE.BoxGeometry(1, 1, 1);//创建材质const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });//创建网格=几何体+材质const cube = new THREE.Mesh(geometry, material);//将网格添加到场景scene.add(cube);//正对着我们的是z轴camera.position.z = 5;//默认看向原点camera.lookAt(0, 0, 0);//创建轨道控制器//const controls = new OrbitControls(camera, renderer.domElement);function animate() {//播放下一帧,继续调用animate函数requestAnimationFrame(animate);//旋转cube.rotation.x += 0.01;cube.rotation.y += 0.01;//渲染renderer.render(scene, camera);}//调用函数animate();}
}export default App
- 修改index.css
* {margin: 0;padding: 0;
}canvas {display: block;position: fixed;left: 0;top: 0;width: 0;height: 0;
}
App.jsx 的进阶版
import { useState, useEffect, Component } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import * as THREE from 'three';
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入动画库
import gsap from "gsap";// function App() {
// useEffect(() => {// const scene = new THREE.Scene();
// const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// //创建渲染器
// const renderer = new THREE.WebGLRenderer();
// renderer.setSize(window.innerWidth, window.innerHeight);
// document.body.appendChild(renderer.domElement);
// //创建几何体
// const geometry = new THREE.BoxGeometry(1, 1, 1);
// //创建材质
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// //创建网格=几何体+材质
// const cube = new THREE.Mesh(geometry, material);
// //将网格添加到场景
// scene.add(cube);// //正对着我们的是z轴
// camera.position.z = 5;
// //默认看向原点
// camera.lookAt(0, 0, 0);// //创建轨道控制器
// //const controls = new OrbitControls(camera, renderer.domElement);// function animate() {
// //播放下一帧,继续调用animate函数
// requestAnimationFrame(animate);
// //旋转
// cube.rotation.x += 0.01;
// cube.rotation.y += 0.01;
// //渲染
// renderer.render(scene, camera);
// }
// //调用函数
// animate();
// }, [])// return (
// <>
// <div className='App'></div>// </>
// )
// }class App extends Component {render() {return <div></div>}componentDidMount() {// const scene = new THREE.Scene();// const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// //创建渲染器// const renderer = new THREE.WebGLRenderer();// renderer.setSize(window.innerWidth, window.innerHeight);// document.body.appendChild(renderer.domElement);// //创建几何体// const geometry = new THREE.BoxGeometry(1, 1, 1);// //创建材质// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });// //创建网格=几何体+材质// const cube = new THREE.Mesh(geometry, material);// //将网格添加到场景// scene.add(cube);// //正对着我们的是z轴// camera.position.z = 5;// //默认看向原点// camera.lookAt(0, 0, 0);// //创建轨道控制器// //const controls = new OrbitControls(camera, renderer.domElement);// function animate() {// //播放下一帧,继续调用animate函数// requestAnimationFrame(animate);// //旋转// cube.rotation.x += 0.01;// cube.rotation.y += 0.01;// //渲染// renderer.render(scene, camera);// }// //调用函数// animate();// console.log(THREE);// 设置场景、相机const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 设置相机位置camera.position.set(0, 0, 10);scene.add(camera);//渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 监听窗口大小变化事件window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;// 更新相机的宽高比camera.aspect = width / height;// 更新相机的投影矩阵camera.updateProjectionMatrix();// 更新渲染器大小renderer.setSize(width, height);// 设置渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio);});// 创建一个立方体const geometry = new THREE.BoxGeometry();const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });const cube = new THREE.Mesh(geometry, material);scene.add(cube);camera.position.z = 5;/**************/// 创建轨道控制器(此时你可以使用右键让模型动起来)const controls = new OrbitControls(camera, renderer.domElement);// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。controls.enableDamping = true;// 添加坐标轴辅助器const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);// 设置时钟const clock = new THREE.Clock();window.addEventListener("dblclick", () => {const fullScreenElement = document.fullscreenElement;if (!fullScreenElement) {// 双击控制屏幕进入全屏,退出全屏// 让画布对象全屏renderer.domElement.requestFullscreen();} else {// 退出全屏,使用document对象document.exitFullscreen();}// console.log(fullScreenElement);});/**************/// 鼠标交互let isDragging = false;let previousMousePosition = {x: 0,y: 0};function onDocumentMouseDown(event) {isDragging = true;}function onDocumentMouseMove(event) {if (isDragging) {var deltaMove = {x: event.clientX - previousMousePosition.x,y: event.clientY - previousMousePosition.y};const deltaRotationQuaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(toRadians(deltaMove.y * 1),toRadians(deltaMove.x * 1),0,'XYZ'));cube.quaternion.multiplyQuaternions(deltaRotationQuaternion, cube.quaternion);}previousMousePosition = {x: event.clientX,y: event.clientY};}function onDocumentMouseUp(event) {isDragging = false;}// 将鼠标事件监听器添加到渲染器的DOM元素renderer.domElement.addEventListener('mousedown', onDocumentMouseDown, false);renderer.domElement.addEventListener('mousemove', onDocumentMouseMove, false);renderer.domElement.addEventListener('mouseup', onDocumentMouseUp, false);// 动画循环渲染function animate() {// 如果没有鼠标交互,立方体会自动旋转if (!isDragging) {cube.rotation.x += 0.01;cube.rotation.y += 0.01;}controls.update();renderer.render(scene, camera);requestAnimationFrame(animate);}animate(); // 开始动画循环// 辅助函数:将角度转换为弧度function toRadians(angle) {return angle * (Math.PI / 180);}}
}export default App// // 目标:js控制画面全屏// // 1、创建场景
// const scene = new THREE.Scene();// // 2、创建相机
// const camera = new THREE.PerspectiveCamera(
// 75,
// window.innerWidth / window.innerHeight,
// 0.1,
// 1000
// );// // 设置相机位置
// camera.position.set(0, 0, 10);
// scene.add(camera);// // 添加物体
// // 创建几何体
// const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
// // 根据几何体和材质创建物体
// const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);// // 修改物体的位置
// // cube.position.set(5, 0, 0);
// // cube.position.x = 3;
// // 缩放
// // cube.scale.set(3, 2, 1);
// // cube.scale.x = 5;
// // 旋转
// cube.rotation.set(Math.PI / 4, 0, 0, "XZY");// // 将几何体添加到场景中
// scene.add(cube);// console.log(cube);// // 初始化渲染器
// const renderer = new THREE.WebGLRenderer();
// // 设置渲染的尺寸大小
// renderer.setSize(window.innerWidth, window.innerHeight);
// // console.log(renderer);
// // 将webgl渲染的canvas内容添加到body
// document.body.appendChild(renderer.domElement);// // // 使用渲染器,通过相机将场景渲染进来
// // renderer.render(scene, camera);// // 创建轨道控制器
// const controls = new OrbitControls(camera, renderer.domElement);
// // 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。
// controls.enableDamping = true;// // 添加坐标轴辅助器
// const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);
// // 设置时钟
// const clock = new THREE.Clock();// window.addEventListener("dblclick", () => {
// const fullScreenElement = document.fullscreenElement;
// if (!fullScreenElement) {
// // 双击控制屏幕进入全屏,退出全屏
// // 让画布对象全屏
// renderer.domElement.requestFullscreen();
// } else {
// // 退出全屏,使用document对象
// document.exitFullscreen();
// }
// // console.log(fullScreenElement);
// });// function render() {
// controls.update();
// renderer.render(scene, camera);
// // 渲染下一帧的时候就会调用render函数
// requestAnimationFrame(render);
// }// render();// // 监听画面变化,更新渲染画面
// window.addEventListener("resize", () => {
// // console.log("画面变化了");
// // 更新摄像头
// camera.aspect = window.innerWidth / window.innerHeight;
// // 更新摄像机的投影矩阵
// camera.updateProjectionMatrix();// // 更新渲染器
// renderer.setSize(window.innerWidth, window.innerHeight);
// // 设置渲染器的像素比
// renderer.setPixelRatio(window.devicePixelRatio);
项目打包
教程:https://juejin.cn/post/6869708334371602445
如果不想看教程,那就直接往下看
你就直接在项目的根目录下执行
npm run build
就行了
然后你就生成了一个dist目录,你把dist目录下的文件放在服务器下面就能直接跑!(假如你生成的文件夹和我的这个不一样,请看下面的补充)
补充
打包遇到的问题:
你可能会遇到下面三种情况:
- 只生成了dist目录
- 只生成了build目录
- 既生成了dist目录又生成了build目录
原因:
版本不同,操作系统不同,配置文件也有差异
解决办法:
- 如果只生成了一个dist文件,就只需要把
这一个文件下的内容
放在服务器下即可. - 如果build和dist都生成了,就把
他们两个的文件夹里面的内容
一起放在在服务器下. - 如果只生成了一个build文件,就只需要把
这一个文件下的内容
放在服务器下即可.