ThreeJs 圖形繪製基礎

1、前言

和其餘 GUI 系統同樣,web 也提供了一個使用 canvas 來繪製圖形的基礎環境。利用 canvas 咱們能夠繪製矩形,三角形,直線,圓弧和曲線等比較複雜的圖形。具體能夠參考web

使用canvas來繪製圖形canvas

WebGL 本質上也是在 canvas 上做畫,只不過它基因而一個 3D 的場景。而在 ThreeJs 中,提供了一個套 Shape 和 Curve 相關的 API 來幫助咱們在 3D 場景中繪製出咱們想要的圖形。bash

2、圖形繪製主要流程

圖形繪製通常流程爲:構造 Shape、構造 BufferGeometry 、構造 Mesh 並添加到場景中。ui

1.構造 Shape

在構造 Shape 以前,咱們先來了解一下 ThreeJs 中的圖形繪製基礎。spa

圖形繪製的基礎有 3 個比較核心的類:Curve,Path 以及 Shape。以下是用於進行圖形繪製的一個比較全局的類圖。code

圖形繪製類圖.jpg

在實際的開發過程當中,咱們通常使用 Shape 來繪製出咱們想要的形狀,和 canvas 同樣,也能夠繪製出矩形、三角形、直線、圓弧等,甚至能夠一併繪製出更復雜的圖形,如魚形、剪刀等。cdn

而在上圖中,Shape 繼承自 Path,Path 又間接繼承自 Curve,Path 封裝了各類繪製圖形的 API 接口,如 :blog

lineTo: 繪製直線繼承

quadraticCurveTo: 二次貝塞爾曲線接口

bezierCurveTo: 三次貝塞爾曲線

arc: 弧線

ellipse: 橢圓

......

在 Path 的各繪製 API 中,又是進步構造相應的曲線,如 new 一個 LineCurve,CubicBezierCurve 等,從而完成曲線的構造。

有了這些圖形繪製的 API,在 3D 場景中,利用這些 API 不只能夠繪製 2D 的圖形,還能夠繪製 3D 的圖形。上面類圖中,***Curve 帶後綴 3 的都是進行 3D 的圖形繪製,其餘天然就都是 2D 的繪製了。

以下,咱們利用 Bezier 來構造一個圓。關於如何用 Bezier 來構造圓,就不在這裏展開了。

var circleRadius = 40;
				var circleShape = new THREE.Shape();
				circleShape.moveTo( 0, circleRadius );

				circleShape.quadraticCurveTo( circleRadius, circleRadius, circleRadius, 0 );
				circleShape.quadraticCurveTo( circleRadius, - circleRadius, 0, - circleRadius );
				circleShape.quadraticCurveTo( - circleRadius, - circleRadius, - circleRadius, 0 );
				circleShape.quadraticCurveTo( - circleRadius, circleRadius, 0, circleRadius );

複製代碼

2. 構造 BufferGeometry

上面經過 Shape 構造出了咱們想要的圖形,下一步咱們須要獲取圖形的全部點,並從這些點構造 BufferGeometry。

Shape 是間接繼承自 Curve ,Curve 定義了 getPoints() 的基礎。Shape 的 getPoints() 的具體實如今 CurvePath 中的實現,從而獲取構造這個圖形所須要的點。

var points = shape.getPoints();
var geometryPoints = new THREE.BufferGeometry().setFromPoints( subPoints );
複製代碼

3. 構造網格

拿到 BufferGeometry 就能夠構造出咱們要的物體了。這裏爲了效果上表達明顯一點,而且炫酷一點,就用 Line 逐段逐段繪製出了咱們前面所構造的圓。

效果圖以下:

畫圓的 gif

實現代碼以下:

function addLineShape( shape, color, x, y, z, rx, ry, rz, s ) {

					// lines

					shape.autoClose = true;

					var points = shape.getPoints();

					console.log( "addLineShape ", points );
					let length = points.length;

					let val = 0;

					function drawLine(  ) {

						if(val == length) return;

						let subPoints1 = points[val];
						let subPoints2 = points[(val + 1) % length];

						let subPoints = [];
						subPoints.push(subPoints1);
						subPoints.push(subPoints2);

						var geometryPoints = new THREE.BufferGeometry().setFromPoints( subPoints );

						// solid line

						var line = new THREE.Line( geometryPoints, new THREE.LineBasicMaterial( { color: color } ) );
						line.position.set( x, y, z );
						line.rotation.set( rx, ry, rz );
						line.scale.set( s, s, s );
						scene.add( line );

						val++;

						setTimeout(drawLine,16);
					}

					drawLine();
}
複製代碼

代碼比較簡單,感興趣的能夠自行分析一下。

3、總結

文章介紹的內容相對比較簡單,主要大體梳理了 ThreeJs 所提供的繪圖 API 以及繪圖的主要流程。其中也以一個實例講解了整個繪製的過程,以加深對其的理解。

相關文章
相關標籤/搜索