Three.js學習筆記 本篇上一篇介紹的raycaster
和curves
(曲線)實現在canvas畫畫。
目前只支持畫線。
添加畫板
我們可以添加一個Plane
當做畫板,要足夠的大。
var geometry = new THREE.PlaneGeometry(10000, 10000, 20);
var material = new THREE.MeshBasicMaterial({
// 這里利用這兩個參數設置plane為透明
opacity: 0,
transparent: true
});
var ground = new THREE.Mesh(geometry, material);
ground.position.set(0, 0, 0);
array.push(ground);
scene.add(ground);
添加畫筆
然后添加一個raycaster
當做畫筆。利用raycaster
的intersectObjects()
方法獲取和射線相交對象,通過該對象的point
屬性獲取當前相交的交點坐標。
var helpPoint = new THREE.Vector3();
function render() {
stats.update();
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(array);
if(intersects.length > 0) {
//獲取畫筆和畫板的交點左邊,並保存到`helpPoint`中
helpPoint = intersects[0].point;
}
requestAnimationFrame(render);
renderer.render(scene, camera);
}
添加畫線事件
var v = []; //用來存儲要繪制曲線的點
var obj = new THREE.Object3D(); //用來存儲繪制好的曲線
//添加鼠標按下事件
//鼠標按下開始繪制
document.addEventListener('mousedown', onDocumentMouseDownLine, false);
function onDocumentMouseDownLine(event) {
event.preventDefault();
//初始化`v`,獲取的所有點的集合
v = [];
//添加鼠標移動事件,畫線
document.addEventListener('mousemove', onDocumentMouseMoveLine, false);
}
function onDocumentMouseMoveLine(event) {
event.preventDefault();
//將繪制過程中獲取的點放入`v`中
v.push(new THREE.Vector2(helpPoint.x, helpPoint.y));
}
//添加鼠標抬起事件
function onDocumentMouseUpLine(event) {
event.preventDefault();
//將繪制的曲線放入`obj`中
obj.add(line);
//初始化 v
v = [];
document.removeEventListener('mousemove', onDocumentMouseMoveLine, false);
}
畫2D線
function drawLine(v) {
// 用`v`中的點生成一條曲線
var curve = new THREE.SplineCurve(v);
var Linematerial = new THREE.LineBasicMaterial({
color: 0x000000
});
var path = new THREE.Path(curve.getPoints(1000));
Linegeometry = path.createPointsGeometry(1000);
//使用曲線在場景中繪制出曲線
line = new THREE.Line(Linegeometry, Linematerial);
scene.add(line);
}
function render() {
//因為創建SplineCurve必須要兩個點,所以要`v.length`大於2是才能調用drawLine()
if(v.length > 2) {
//要移除了場景中的線,實時畫新的線。直到鼠標抬起重置`v = []`
scene.remove(line);
drawLine(v);
//添加以前畫的所有線段
scene.add(obj);
}
}
畫3D線
同樣的我們也可以用上述方法畫3D的線,但是由於point
屬性只包含x
和y
軸的坐標。所以我們需要自定義另一個坐標軸的坐標。
這里我們可以自定義z
軸坐標(本例中設為了一個常量)。
//重寫`mousemove`鼠標移動方法
function onDocumentMouseMoveLine(event) {
event.preventDefault();
//因為下面要畫3D生成過稱中不允許出現重復的點,所以要去除重復的點
var temp = v[v.length - 1];
//這里我們將`z`軸坐標設為常量50
if(temp) {
if(temp.x == helpPoint.x && temp.y == helpPoint.y && temp.z == 50) {
return;
}
}
v.push(new THREE.Vector3(helpPoint.x, helpPoint.y, 50));
}
//重寫函數`drawLine(v)`
function drawLine(v) {
//這里使用`CatmullRomCurve3`生成曲線
var curve = new THREE.CatmullRomCurve3(v);
var extrudeSettings = {
curveSegments: 12,
steps: 200,
amount: 2,
extrudePath: curve
};
var pts = [];
pts.push(new THREE.Vector2(5, 5));
pts.push(new THREE.Vector2(5, -5));
pts.push(new THREE.Vector2(-5, -5));
pts.push(new THREE.Vector2(-5, 5));
var shape = new THREE.Shape(pts);
//使用`ExtrudeGeometry`來擴展或說是擠壓曲線,將曲線變成3D
var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
var material = new THREE.MeshBasicMaterial({
color: 0xff8000
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
ExtrudeGeometry
Constructor
var geometry = new THREE.ExtrudeGeometry(shapes,options);
Main Properties
shapes
:形狀或是一系列的形狀options
:選項參數
Options
curveSegments
:曲線上的點數steps
:用於細分曲線段數amount
:深度擠壓的形狀數extrudePath
:THREE.CurvePath,3D曲線來擴展