和其餘 GUI 系統同樣,web 也提供了一個使用 canvas 來繪製圖形的基礎環境。利用 canvas 咱們能夠繪製矩形,三角形,直線,圓弧和曲線等比較複雜的圖形。具體能夠參考web
使用canvas來繪製圖形canvas
WebGL 本質上也是在 canvas 上做畫,只不過它基因而一個 3D 的場景。而在 ThreeJs 中,提供了一個套 Shape 和 Curve 相關的 API 來幫助咱們在 3D 場景中繪製出咱們想要的圖形。bash
圖形繪製通常流程爲:構造 Shape、構造 BufferGeometry 、構造 Mesh 並添加到場景中。ui
在構造 Shape 以前,咱們先來了解一下 ThreeJs 中的圖形繪製基礎。spa
圖形繪製的基礎有 3 個比較核心的類:Curve,Path 以及 Shape。以下是用於進行圖形繪製的一個比較全局的類圖。code
在實際的開發過程當中,咱們通常使用 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 );
複製代碼
上面經過 Shape 構造出了咱們想要的圖形,下一步咱們須要獲取圖形的全部點,並從這些點構造 BufferGeometry。
Shape 是間接繼承自 Curve ,Curve 定義了 getPoints() 的基礎。Shape 的 getPoints() 的具體實如今 CurvePath 中的實現,從而獲取構造這個圖形所須要的點。
var points = shape.getPoints();
var geometryPoints = new THREE.BufferGeometry().setFromPoints( subPoints );
複製代碼
拿到 BufferGeometry 就能夠構造出咱們要的物體了。這裏爲了效果上表達明顯一點,而且炫酷一點,就用 Line 逐段逐段繪製出了咱們前面所構造的圓。
效果圖以下:
實現代碼以下:
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();
}
複製代碼
代碼比較簡單,感興趣的能夠自行分析一下。
文章介紹的內容相對比較簡單,主要大體梳理了 ThreeJs 所提供的繪圖 API 以及繪圖的主要流程。其中也以一個實例講解了整個繪製的過程,以加深對其的理解。