ThreeJs学习笔记【day1】

288 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 >>

前言

threeJs是基于浏览器原生webGlAPI进行封装的3D效果框架,基于ThreeJs,我们可以很轻松的在浏览器实现不错的3D效果,不出意外的话,接下来的一个月时间,我将会针对ThreeJs进行练习,此系列文章就作为打卡的依据吧

食用提示

因为将会默认跳过一些最基础的知识,故本文适合有前端基础的内容阅读

下载

npm init

...

yarn add three

如图所示 从node_modules里将three.js取出即可

image.png 引入成功后,会在window上挂载THREE对象,可以通过THREE对象查看当前代码引擎的版本,如下图所示

image.png

THREE 三剑客 场景 相机 渲染器

为了真正能够让你的场景借助three.js来进行显示,我们需要以下几个对象:场景、相机和渲染器,这样我们就能透过摄像机渲染出场景

下面是day1Js内的内容

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, document.documentElement.clientWidth / document.documentElement.clientHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( document.documentElement.clientWidth, document.documentElement.clientHeight );
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 ); 
camera.position.z = 5;
function animate() { 
    requestAnimationFrame( animate );
    cube.rotation.x += 0.01; 
    cube.rotation.y += 0.01;
    renderer.render( scene, camera ); 
}; 
animate();

PerspectiveCamera 是THREE里的透视摄像机 此时我们将会创建一个和浏览器文档窗口同宽同高的一个canvas对象

参数说明

new THREE.PerspectiveCamera(fov,aspectRatio, near, far)

fov 视场角

在摄影学中,视角(angle of view)是在一般环境中,相机可以接收影像的角度范围,也可以常被称为视野。 

视角(angle of view)与成像范围(angle of coverage)是不同的,他是描述镜头可以撷取的影像角度,一般来说镜头的成像圈都够大到涵盖底片或者感光元件(或许会有一点点的边缘暗角)。

假如镜头的成像范围无法涵盖整个感光元件,则成像圈会被看见,一般会伴随严重的边缘暗角,在这个状态下,视角会被成像范围所限制。

视场角 英文 field angle; angle of view; field angle; 又称:视场 在光学工程中,视场角又可用FOV表示。 image.png

官方文档是这样说的: 视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的单位是角度(与弧度区分开)。按我的理解的话,就是指的相机所辐射的水平范围

aspectRatio 长宽比 长度与宽度比值,不做赘述,此处长宽比取了渲染器宽高比

near 近截面 通俗解释,相机最近可以看到哪里

far 远截面 通俗解释,相机最远可以看到哪里

WebGLRenderer 渲染器 threeJs提供了多种类型的渲染器,作用是在不支持webGL的浏览器上进行降级

对于性能比较敏感的应用程序来说,你可以使用setSize传入一个较小的值,例如window.innerWidth/2window.innerHeight/2,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。

如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用setSize时,将updateStyle(第三个参数)设为false。例如,假设你的 标签现在已经具有了100%的宽和高,调用setSize(window.innerWidth/2, window.innerHeight/2, false) 将使得你的应用程序以一半的分辨率来进行渲染。

BoxGeometry 立方体对象,内置对象,包含立方体的所有顶点和面 MeshBasicMaterial 内置材质 Mesh(网格)。 按我的理解,网格相当于给场景加上了坐标系,通过网格,我们可以让元素自由移动。网格包含一个立方体和材质。

通过renderer.render( scene, camera ); 进行渲染

知识拓展 CSS中的3D属性

此处类比一下css有关3D的属性

// 父元素身上指定  是否支持3D模式展示,默认为flat 平面模式
transform-style: flat/preserve-3d;
// 决定了相机和平面的距离,景深和视距,相当于远截面,视场角的有机结合
perspective:1000px
// 指定相机源点 相当于近截面,远截面的视角的结合
perspective-origin 

requestAnimationFrame

  1. requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次reflow或者repaint中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般是系统的刷新频率。

  2. 在隐藏或不可见的元素中,requestAnimationFrame将不会进行repaint或reflow,这当然就意味着更少的的cpu,gpu和内存使用量。