引入three
npm i three -S
在react中使用
- 創(chuàng)建場景
后續(xù)模型、光源等都通過scene.add函數(shù)添加至場景中
const scene = new THREE.Scene()
scene.background = new THREE.Color(0xffffff)
- 創(chuàng)建相機(jī)
相機(jī)主要有正交相機(jī)(OrthographicCamera)、透視相機(jī)(PerspectiveCamera)。透視相機(jī)模范人眼,一般采用透視相機(jī)比較多。
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 400 //相機(jī)位置
可以添加OrbitControls控件來自由的旋轉(zhuǎn)縮放預(yù)覽效果。此處導(dǎo)入OrbitControls的地址與官網(wǎng)不同,當(dāng)前three版本0.162.0。添加方式:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
renderer.render(scene, camera)
})
- 創(chuàng)建渲染器
renderer.domElement 本質(zhì)上是一個(gè)canvas元素。
可以用renderer.render(scene, camera)來渲染需要繪制的內(nèi)容。如果需要動畫之類的效果,可以使用requestAnimationFrame,在每一幀修改模型等的屬性,如位置、旋轉(zhuǎn)等
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
- 創(chuàng)建3D文本
- 導(dǎo)入FontLoader、TextGeometry 以及字體的json格式描述文件(three源碼中內(nèi)置了幾種字體)
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
import HelvetikerFont from 'three/examples/fonts/helvetiker_bold.typeface.json'
2.繪制字體
loader.load的第一個(gè)參數(shù)需要是url地址,使用URL.createObjectURL創(chuàng)建url。
const loader = new FontLoader()
const jsonUrl = URL.createObjectURL(new Blob([JSON.stringify(HelvetikerFont)], { type: 'application/json' }));
loader.load(jsonUrl, function (font) {
const geometry = new TextGeometry('Hello three.js!', {
font: font, //THREE.Font的實(shí)例
size: 100, //字體大小,默認(rèn)值為100
height: 5, //擠出文本的厚度。默認(rèn)值為50
curveSegments: 12,//表示文本的)曲線上點(diǎn)的數(shù)量。默認(rèn)值為12
bevelEnabled: true, //是否開啟斜角,默認(rèn)為false
bevelThickness: 10, //文本上斜角的深度,默認(rèn)值為20
bevelSize: 2, //斜角與原始文本輪廓之間的延伸距離。默認(rèn)值為8
bevelSegments: 5 //斜角的分段數(shù)。默認(rèn)值為3
});
geometry.computeBoundingBox()
const centerOffset = - 0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x)
const material = new THREE.MeshPhongMaterial({ color: 0xffffff })
const textMesh = new THREE.Mesh(geometry, material)
textMesh.position.x = centerOffset
textMesh.position.y = 10
textMesh.position.z = 0
scene.add(textMesh)
}, (e) => {
console.log('progress', e)
}, (e) => {
console.log('err', e)
});