赞
踩
目录
第一步:创建空项目
第二步:终端输入
npm init
直接一路回车。
第三步:安装parcel
npm install parcel-bundler
接着,通过修改你的package.json来添加这些任务脚本
- "scripts": {
- "dev": "parcel src/index.html",
- "build": "parcel build src/index.html"
- },
第四步:创建src/index.html
第五步:终端输入命令
npm install parcel-bundler -dev
第六步:创建静态文件,引入静态文件
第七步:编写style.css代码
- * {
- margin: 0;
- padding: 0;
- }
-
- body {
- background-color: skyblue;
- }
第八步:安装threejs依赖
npm install three --save
第九步:编写main.js代码,看threejs是否安装成功
- import * as THREE from "three"
-
- console.log(THREE);
第十步:启动项目
- import * as THREE from "three"
-
- // 1、创建场景
- const scene = new THREE.Scene()
-
- // 2、创建相机
- const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
-
- // 3、设置相机位置
- camera.position.set(0, 0, 10);
- scene.add(camera)
-
- // 添加物体
- // 创建几何体
- const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
- // 材质
- const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffff00});
- // 根据几何体和材质创建物体
- const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
- // 将物体添加到场景中
- scene.add(cube)
-
- // 初始化渲染器
- const renderer = new THREE.WebGLRenderer();
- // 设置渲染的尺寸大小
- renderer.setSize(window.innerWidth, window.innerHeight);
- // 将webgl渲染的canvas内容添加到body
- document.body.appendChild(renderer.domElement);
-
- // 使用渲染器,通过相机将场景渲染进来
- renderer.render(scene, camera);
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- import * as THREE from "three"
- // 导入轨道控制器
- import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
-
- // 1、创建场景
- const scene = new THREE.Scene()
-
- // 2、创建相机
- const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
-
- // 3、设置相机位置
- camera.position.set(0, 0, 10);
- scene.add(camera)
-
- // 添加物体
- // 创建几何体
- const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
- // 材质
- const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffff00});
- // 根据几何体和材质创建物体
- const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
- // 将物体添加到场景中
- scene.add(cube)
-
- // 初始化渲染器
- const renderer = new THREE.WebGLRenderer();
- // 设置渲染的尺寸大小
- renderer.setSize(window.innerWidth, window.innerHeight);
- // 将webgl渲染的canvas内容添加到body
- document.body.appendChild(renderer.domElement);
-
- // 使用渲染器,通过相机将场景渲染进来
- // renderer.render(scene, camera);
-
-
- // 创建轨道控制器
- const controls = new OrbitControls(camera, renderer.domElement);
-
- function render() {
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
-
- render();
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
可以拖动了。
- // 添加坐标轴辅助器 5代表轴的线段长度
- const axesHelper = new THREE.AxesHelper(5)
- scene.add(axesHelper)
红色代表X轴,绿色代表Y轴,蓝色代表Z轴。
- // 修改物体的位置
- // 参数分别为 x,y,z
- cube.position.set(5, 2, 0)
当然你也可以使用直接点的形式:
- cube.position.x = 5
- cube.position.y = 2
小案例:模拟物体从左到右循环运动
- function render() {
- cube.position.x += 0.01
- if (cube.position.x > 5) {
- cube.position.x = 0
- }
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
- // 缩放
- // 参数 x轴是3倍,y轴是两倍
- cube.scale.set(3, 2, 1)
- //旋转
- // 参数都为弧度,Math.PI / 4代表绕X轴旋转45度
- cube.rotation.set(Math.PI / 4, 0, 0)
小案例:模拟物体从左到右循环运动,并按X轴旋转
- function render() {
- cube.position.x += 0.01
- cube.rotation.x += 0.01
- if (cube.position.x > 5) {
- cube.position.x = 0
- }
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
首先,我们的render函数有个默认的参数time,代表每一帧的时间,如果你打印会发现每一帧的时间都不太匀速,比如我们上面这个案例,x轴长度为5,假如我打算1秒运动长度1,匀速就是5秒完成,但打印结果并不是匀速的。
- // 匀速
- function render(time) {
- let t = time / 1000 % 5;
- cube.position.x = t * 1
- if (cube.position.x > 5) {
- cube.position.x = 0
- }
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
- // 设置时钟
- const clock = new THREE.Clock();
-
- function render() {
- // 获取时钟运行的总时长
- let time = clock.getElapsedTime();
- console.log("时钟运行总时长:", time);
- let deltaTime = clock.getDelta();
- console.log("两次获取时间的间隔时间:", deltaTime)
-
- let t = time % 5;
- cube.position.x = t * 1
- if (cube.position.x > 5) {
- cube.position.x = 0
- }
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
npm install gsap
动画库的作用就解决了我们上面手动计算处理动画的问题。
- // 设置动画
- // x轴上移动到5的位置,所花费时间5秒
- gsap.to(cube.position, {x: 5, duration: 5, ease: "power1.out"})
- // 绕x轴上旋转到360度,所花费时间5秒
- gsap.to(cube.rotation, {x: 2 * Math.PI, duration: 5})
-
- function render() {
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
ease属性(速率):
power1.out:起始阶段平滑地加速,然后以逐渐减速的方式结束。
power1.in:起始阶段缓慢加速,然后以较快的速度向目标值靠近。
power1.inOut:在动画开始和结束时,属性的变化速度较慢,然后在动画的中间阶段达到最快的变化速度。
- // 设置动画
- // x轴上移动到5的位置,所花费时间5秒
- let animate1 = gsap.to(cube.position, {
- x: 5,
- duration: 5,
- ease: "power1.inOut",
- repeat: -1, // 设置重复的次数,无限次循环-1
- yoyo: true, // 往返运动
- delay: 2, // 延迟2秒运动
- onStart: () => {
- console.log("动画开始")
- },
- onComplete: () => {
- console.log("动画完成")
- }
- })
- // 绕x轴上旋转到360度,所花费时间5秒
- gsap.to(cube.rotation, {x: 2 * Math.PI, duration: 5})
-
- // 点击动画,暂停或恢复
- window.addEventListener("click", () => {
- if(animate1.isActive()) {
- animate1.pause(); // 暂停
- } else {
- animate1.resume(); // 恢复运动
- }
- })
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- // 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用update()
- controls.enableDamping = true;
-
- function render() {
- controls.update();
- renderer.render(scene, camera);
- // 渲染下一帧的时候就会调用render函数
- requestAnimationFrame(render)
- }
- // 监听画面变化,更新渲染画面
- window.addEventListener("resize", () => {
- // 更新摄像头
- camera.aspect = window.innerWidth / window.innerHeight;
- // 更新摄像机的投影矩阵
- camera.updateProjectMatrix();
- // 在更新渲染器
- renderer.setSize(window.innerWidth, window.innerHeight)
- // 设置渲染器的像素比
- renderer.setPixelRatio(window.devicePixelRatio);
- })
尽管你更改分辨率,这段代码都会保持画面原样。
- // 双击控制屏幕进入全屏,退出全屏
- window.addEventListener("dblclick", () => {
- const fullScreenElement = document.fullscreenElement; // 页面是否处于全屏
- if (!fullScreenElement){
- renderer.domElement.requestFullscreen(); // 全屏
- } else {
- document.exitFullscreen(); // 退出全屏
- }
- })
很多时候我们调试3D图像很麻烦,普遍都是改完代码然后看页面效果,而dat.gui就大大简化了我们的操作问题。
npm install -save dat.gui
- // 导入dat.gui
- import * as dat from 'dat.gui'
-
- const gui = new dat.GUI();
- gui.add(cube.position, "x").min(0).max(5).name("移动X轴坐标").onChange((value) => {
- console.log("值被修改:", value)
- }).onFinishChange((value) => {
- console.log("完全停下来触发:", value)
- })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。