和其余 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 以及绘图的主要流程。其中也以一个实例讲解了整个绘制的过程,以加深对其的理解。