这里是工作中遇到的一些使用ThreeJS的例子,要学理论可以参看:Three.js入门指南1、设置面的透明度var material = new THREE.MeshBasicMaterial({transparent:true});material.opacity = 0.5;
1
2
2、画虚线只能画一次,如果画两次,第一次从A到B,第二次从B到A,虚线就会变成实线,因为两次画的线段和空缺刚好互补3、给立方体画上虚线边框思路,遍历立方体的所有顶点,对每一个顶点,画上与其相接的三条边,每条边画一半长度。function drawUnVisiableBorder(){ for(var i=0 ; i< cube.geometry.vertices.length ; i ++ ){ var v1 = new THREE.Vector3(); v1.copy(cube.geometry.vertices); var v2 = new THREE.Vector3(); v2.copy(v1); v2.x = -v2.x/2; DrawDashLine(v1,v2); var v2 = new THREE.Vector3(); v2.copy(v1); v2.y = -v2.y/2; DrawDashLine(v1,v2); var v2 = new THREE.Vector3(); v2.copy(v1); v2.z = -v2.z/2; DrawDashLine(v1,v2); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
4、画虚线function initObject(){ var geometry = new THREE.Geometry(); /** * vertexColors: false 关闭使用点颜色来生成线的颜色,这个值默认是false,如果设置为true,那么后面设置的color将不起作用 * dashSize:30 点长度30个单位 * gapSize:20 点与点之间间隔长度20个单位 * @type {THREE.LineDashedMaterial} */ var material = new THREE.LineDashedMaterial({ vertexColors: false,dashSize:30,gapSize:20,color:0x839848}); var p1 = new THREE.Vector3(0, 0,0); var p2 = new THREE.Vector3(500,300,0); geometry.vertices.push(p1); geometry.vertices.push(p2); /** * 虚线记得加上这句,用于计算上面设置的点和间隔长度,不设置则线表现为实线 */ geometry.computeLineDistances(); var line = new THREE.Line(geometry,material,THREE.LineSegments ); scene.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
5、画渐变线function initObject(){ var geometry = new THREE.Geometry(); /** * vertexColors: true 这个设置为true,表示使用端点颜色 * @type {THREE.LineBasicMaterial} */ var material = new THREE.LineBasicMaterial({ vertexColors: true }); var p1 = new THREE.Vector3(0, 0,0); var p2 = new THREE.Vector3(500,300,0); geometry.vertices.push(p1); geometry.vertices.push(p2); /** * 将端点颜色加到geometry.colors中,这是一个数组,对应线的端点 */ var color1 = new THREE.Color(0x3966FF); var color2 = new THREE.Color(0x629729 ); geometry.colors.push(color1,color2); var line = new THREE.Line(geometry,material,THREE.LineSegments ); scene.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
6、使用组打包 var group = new THREE.Group(); function initObject(){ var p1 = new THREE.Vector3(0,-300,0); var p2 = new THREE.Vector3(0,300,0); var line1 = drawLine(p1,p2); group.add(line1); var p3 = new THREE.Vector3(-500,0,0); var p4 = new THREE.Vector3(500,0,0); var line2 = drawLine(p3,p4); group.add(line2); scene.add(group); } /** * 画线函数 * @param v1 端点1 * @param v2 端点2 * @returns {THREE.Line} 返回一条线条 */ function drawLine(v1,v2){...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
打包后对象可以一起操作7、响应事件可以使用Raycaster对象获得鼠标点击处的对象数组。 /**首先,要给document注册事件*/ function initRenerer(){ renderer = new THREE.WebGLRenderer({antialias : true}); renderer.setSize(window.innerWidth,window.innerHeight); document.body.appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF,1.0); document.addEventListener("mousedown",onMouseDown,false); } /**使用射线投影获得点击的形状,再对形状进行处理*/ var mouse = new THREE.Vector3(); var raycaster = new THREE.Raycaster(); function onMouseDown(event){ event.preventDefault(); //将屏幕像素坐标转化成camare坐标 mouse.x = (event.clientX/renderer.domElement.clientWidth)*2-1; mouse.y = - (event.clientY/renderer.domElement.clientHeight)*2+1; //设置射线的起点是相机 raycaster.setFromCamera( mouse, camera ); //将射线投影到屏幕,如果scene.children里的某个或多个形状相交,则返回这些形状 //第二个参数是设置是否递归,默认是false,也就是不递归。当scene里面添加了Group对象的实例时,就需要设置这个参数为true //第一个参数不传scene.children也可以,传一个group.children或一个形状数组都可以(这样可以实现一些特别的效果如点击内部的效果) //另外,因为返回的是一个数组,所以遍历数组就可以获得所有相交的对象,当元素重叠时,特别有用 var intersects = raycaster.intersectObjects(scene.children,true); if(intersects.length>0){ var currObj = intersects[0].object; console.log(currObj); currObj.material.color = new THREE.Color(0x493048); currObj.position.x += 50; } render(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
8、JavaScript设置默认参数可以使用arguments对象function DrawLine(v1,v2,colorValue,depthTest){ if(!arguments[2]) colorValue = 0x000000; if(!arguments[3]) depthTest = true; }
1
2
3
4
5
9、深度测试属性一个立方体,怎么设置为看得见得边为实线,看不见的边为虚线?可以通过设置边的depthTest属性来实现。 /** * 画实线 * */ function DrawLine(v1,v2){ var geometry = new THREE.Geometry(); //设置depthTest属性为true,表示被挡住的边就看不见 var lineMaterial = new THREE.LineBasicMaterial({ vertexColors: false,depthTest:true,color:0x894834}); var p1 = new THREE.Vector3(); p1.copy(v1); var p2 = new THREE.Vector3(); p2.copy(v2); geometry.vertices.push(p1); geometry.vertices.push(p2); var line = new THREE.Line(geometry,lineMaterial,THREE.LineSegments ); return line; } /** * 画虚线 * */ function DrawDashLine(v1,v2){ var geometry = new THREE.Geometry(); //设置depthTest属性为false,表示被挡住的边也看得见 var lineMaterial = new THREE.LineDashedMaterial({ color:0x010101 ,dashSize:5,gapSize:10,depthTest:false }); var p1 = new THREE.Vector3(); p1.copy(v1); var p2 = new THREE.Vector3(); p2.copy(v2); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.computeLineDistances(); var line = new THREE.Line(geometry,lineMaterial,THREE.LineSegments); cube_Border_Group.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
用上面两个函数,给立方体每条边都画上,就可以实现效果了。10、设置多边形偏移如果只设置第九点,你会发现有几条边即可以看见实线,也可以看见虚线,两种重叠到一起,又 若隐若现。这时可以给正方形设置polygonOffset属性。 /** * 画立方体 * */ function drawCube(){ var geometry = new THREE.BoxGeometry( 100, 100,100); geometry.colorsNeedUpdate = true; //下面设置了polygonOffset:true,polygonOffsetFactor:0.5 var material = new THREE.MeshBasicMaterial({color:0xCCCCCC,transparent:false,polygonOffset:true,polygonOffsetFactor:0.5}); ..... }
1
2
3
4
5
6
7
8
9
10
11
12
11、添加网格参考 scene.add( new THREE.GridHelper( 500, 25 ) );
1
2
添加上面语句之后,屏幕中心会显示一个边长为500的水平面,水平面规格为25*2512、消除锯齿创建renderer的时候加上antialias参数renderer = new THREE.WebGLRenderer({antialias:true});
1
13、设置屏幕背景颜色renderer.setClearColor(0x348934,0.7);
1
第一个参数是颜色,第二个参数是透明度。屏幕背景默认是黑色的,所以透明度的值越小,屏幕月暗。14、将鼠标移动转换成转动首先要算出鼠标移动的速度:function onMouseMove(event){ var xDisp = event.clientX - prevX; var yDisp = event.clientY - prevY; //do something prevX = event.clientX; prevY = event.clientY; render(); }
1
2
3
4
5
6
7
8
9
10
11
onMouseMove不停的触发,相当于单位时间内触发一次,所以,单位时间内的位移即是速度。求出了鼠标的移动的速度,就可以乘以一定的系数转化成形状的转动,具体的系数可以尝试得出。15、移动轨迹修正由于照相机的位置不同,有时候threejs的坐标轴和屏幕的坐标轴并不一样,这时候,就要通过速度合成来修正物体移动轨迹。如下图,照相机位置在右上前方,可以看到,x轴都不是与屏幕平行的。http://img.blog.csdn.net/20160810141014533如果我们只是增加或减少物体的position.x,那么物体是斜向下运动的,所以我们要在y轴方向设置个速度加以修正。function onCubeDrag(event){ var xDisp = event.clientX - prevX; var yDisp = event.clientY - prevY; cube_Border_Axis_Group.position.x += xDisp; //将三维坐标的移动转换成2D坐标的移动,0.4这个系数是根据视角得出 cube_Border_Axis_Group.position.y += xDisp*(0.4); cube_Border_Axis_Group.position.y -= yDisp; prevX = event.clientX; prevY = event.clientY; render(); }
1
2
3
4
5
6
7
8
9
10
11
12
16、立体缩放 function onDocumentMouseWheel(event){ if(event.wheelDelta>0){ //判断滚轮滚动方向 cube_Border_Axis_Group.scale.multiplyScalar(1.02); }else{ cube_Border_Axis_Group.scale.multiplyScalar(0.98); } render(); }
1
2
3
4
5
6
7
8
17、创建2D文字 /** *使用示例:创建XYZ * */ function createXYZText(){ //创建Z var spritey = makeTextSprite( "Z", { fontsize: 100} ); spritey.position.set(0,10,200); scene.add(spritey); //创建X spritey = makeTextSprite( "X", { fontsize: 100 } ); spritey.position.set(230,30,0); scene.add(spritey); //创建Y spritey = makeTextSprite( "Y", { fontsize: 100} ); spritey.position.set(0,200,0); scene.add(spritey); } /** * 创建永远面向相机的2D文字 * */ function makeTextSprite( message, parameters ) { if ( parameters === undefined ) parameters = {}; var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial"; var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18; var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4; var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] : { r:0, g:0, b:0, a:1.0 }; var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.font = "Bold " + fontsize + "px " + fontface; var metrics = context.measureText( message ); var textWidth = metrics.width; context.lineWidth = borderThickness; context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)"; context.fillText( message, borderThickness, fontsize + borderThickness); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false } ); var sprite = new THREE.Sprite( spriteMaterial ); sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize); return sprite; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
参考three-js-2d-text-sprite-labels18、创建圆柱function drawCylinder(topRadius,bottomRadius ,height){ //四个参数分别是上底面半径、下底面半径,高度,半径段数 var geometry = new THREE.CylinderGeometry(topRadius,bottomRadius,height,16); var material = new THREE.MeshBasicMaterial({visible:true,color:0x879378}); var cylinder = new THREE.Mesh(geometry,material); return cylinder; }
1
2
3
4
5
6
7
可以看到material设置了visible属性,这提醒我们可以设置圆柱体的可见性,为什么要这样做呢?因为在Threejs中,线本身是二维的,没有办法设置粗细,导致有时候,要选择一条线很难,这时,可以在线外面包一层不可见的圆柱,这样线就很好操作了。19、旋转参考系(世界坐标旋转)/** * 旋转参考系 * @param object 需要旋转的对象 * @param axis 旋转轴,是一个向量,new Vetor3(1,0,0)表示绕x轴顺时针旋转,Vetor3(1,0,0)表示绕X轴逆时针旋转 * @param radians 旋转的角度 */ function rotateAroundWorldAxis(object, axis, radians) { rotWorldMatrix = new THREE.Matrix4(); rotWorldMatrix.makeRotationAxis(axis.normalize(), radians); // old code for Three.JS pre r54: // rotWorldMatrix.multiply(object.matrix); // new code for Three.JS r55+: rotWorldMatrix.multiply(object.matrix); // pre-multiply object.matrix = rotWorldMatrix; // old code for Three.js pre r49: // object.rotation.getRotationFromMatrix(object.matrix, object.scale); // old code for Three.js pre r59: // object.rotation.setEulerFromRotationMatrix(object.matrix); // code for r59+: object.rotation.setFromRotationMatrix(object.matrix); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
物体动的效果可以是物体本身在动,比如,风车的转动;也可以是世界在动,比如,仰望星空,斗转星移。上面的代码和直接转动物体是一样的:object.rotation.z += Math.PI*5/ 180;
1
2
3
20、找例子别忘了github
1
2
2、画虚线只能画一次,如果画两次,第一次从A到B,第二次从B到A,虚线就会变成实线,因为两次画的线段和空缺刚好互补3、给立方体画上虚线边框思路,遍历立方体的所有顶点,对每一个顶点,画上与其相接的三条边,每条边画一半长度。function drawUnVisiableBorder(){ for(var i=0 ; i< cube.geometry.vertices.length ; i ++ ){ var v1 = new THREE.Vector3(); v1.copy(cube.geometry.vertices); var v2 = new THREE.Vector3(); v2.copy(v1); v2.x = -v2.x/2; DrawDashLine(v1,v2); var v2 = new THREE.Vector3(); v2.copy(v1); v2.y = -v2.y/2; DrawDashLine(v1,v2); var v2 = new THREE.Vector3(); v2.copy(v1); v2.z = -v2.z/2; DrawDashLine(v1,v2); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
4、画虚线function initObject(){ var geometry = new THREE.Geometry(); /** * vertexColors: false 关闭使用点颜色来生成线的颜色,这个值默认是false,如果设置为true,那么后面设置的color将不起作用 * dashSize:30 点长度30个单位 * gapSize:20 点与点之间间隔长度20个单位 * @type {THREE.LineDashedMaterial} */ var material = new THREE.LineDashedMaterial({ vertexColors: false,dashSize:30,gapSize:20,color:0x839848}); var p1 = new THREE.Vector3(0, 0,0); var p2 = new THREE.Vector3(500,300,0); geometry.vertices.push(p1); geometry.vertices.push(p2); /** * 虚线记得加上这句,用于计算上面设置的点和间隔长度,不设置则线表现为实线 */ geometry.computeLineDistances(); var line = new THREE.Line(geometry,material,THREE.LineSegments ); scene.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
5、画渐变线function initObject(){ var geometry = new THREE.Geometry(); /** * vertexColors: true 这个设置为true,表示使用端点颜色 * @type {THREE.LineBasicMaterial} */ var material = new THREE.LineBasicMaterial({ vertexColors: true }); var p1 = new THREE.Vector3(0, 0,0); var p2 = new THREE.Vector3(500,300,0); geometry.vertices.push(p1); geometry.vertices.push(p2); /** * 将端点颜色加到geometry.colors中,这是一个数组,对应线的端点 */ var color1 = new THREE.Color(0x3966FF); var color2 = new THREE.Color(0x629729 ); geometry.colors.push(color1,color2); var line = new THREE.Line(geometry,material,THREE.LineSegments ); scene.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
6、使用组打包 var group = new THREE.Group(); function initObject(){ var p1 = new THREE.Vector3(0,-300,0); var p2 = new THREE.Vector3(0,300,0); var line1 = drawLine(p1,p2); group.add(line1); var p3 = new THREE.Vector3(-500,0,0); var p4 = new THREE.Vector3(500,0,0); var line2 = drawLine(p3,p4); group.add(line2); scene.add(group); } /** * 画线函数 * @param v1 端点1 * @param v2 端点2 * @returns {THREE.Line} 返回一条线条 */ function drawLine(v1,v2){...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
打包后对象可以一起操作7、响应事件可以使用Raycaster对象获得鼠标点击处的对象数组。 /**首先,要给document注册事件*/ function initRenerer(){ renderer = new THREE.WebGLRenderer({antialias : true}); renderer.setSize(window.innerWidth,window.innerHeight); document.body.appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF,1.0); document.addEventListener("mousedown",onMouseDown,false); } /**使用射线投影获得点击的形状,再对形状进行处理*/ var mouse = new THREE.Vector3(); var raycaster = new THREE.Raycaster(); function onMouseDown(event){ event.preventDefault(); //将屏幕像素坐标转化成camare坐标 mouse.x = (event.clientX/renderer.domElement.clientWidth)*2-1; mouse.y = - (event.clientY/renderer.domElement.clientHeight)*2+1; //设置射线的起点是相机 raycaster.setFromCamera( mouse, camera ); //将射线投影到屏幕,如果scene.children里的某个或多个形状相交,则返回这些形状 //第二个参数是设置是否递归,默认是false,也就是不递归。当scene里面添加了Group对象的实例时,就需要设置这个参数为true //第一个参数不传scene.children也可以,传一个group.children或一个形状数组都可以(这样可以实现一些特别的效果如点击内部的效果) //另外,因为返回的是一个数组,所以遍历数组就可以获得所有相交的对象,当元素重叠时,特别有用 var intersects = raycaster.intersectObjects(scene.children,true); if(intersects.length>0){ var currObj = intersects[0].object; console.log(currObj); currObj.material.color = new THREE.Color(0x493048); currObj.position.x += 50; } render(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
8、JavaScript设置默认参数可以使用arguments对象function DrawLine(v1,v2,colorValue,depthTest){ if(!arguments[2]) colorValue = 0x000000; if(!arguments[3]) depthTest = true; }
1
2
3
4
5
9、深度测试属性一个立方体,怎么设置为看得见得边为实线,看不见的边为虚线?可以通过设置边的depthTest属性来实现。 /** * 画实线 * */ function DrawLine(v1,v2){ var geometry = new THREE.Geometry(); //设置depthTest属性为true,表示被挡住的边就看不见 var lineMaterial = new THREE.LineBasicMaterial({ vertexColors: false,depthTest:true,color:0x894834}); var p1 = new THREE.Vector3(); p1.copy(v1); var p2 = new THREE.Vector3(); p2.copy(v2); geometry.vertices.push(p1); geometry.vertices.push(p2); var line = new THREE.Line(geometry,lineMaterial,THREE.LineSegments ); return line; } /** * 画虚线 * */ function DrawDashLine(v1,v2){ var geometry = new THREE.Geometry(); //设置depthTest属性为false,表示被挡住的边也看得见 var lineMaterial = new THREE.LineDashedMaterial({ color:0x010101 ,dashSize:5,gapSize:10,depthTest:false }); var p1 = new THREE.Vector3(); p1.copy(v1); var p2 = new THREE.Vector3(); p2.copy(v2); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.computeLineDistances(); var line = new THREE.Line(geometry,lineMaterial,THREE.LineSegments); cube_Border_Group.add(line); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
用上面两个函数,给立方体每条边都画上,就可以实现效果了。10、设置多边形偏移如果只设置第九点,你会发现有几条边即可以看见实线,也可以看见虚线,两种重叠到一起,又 若隐若现。这时可以给正方形设置polygonOffset属性。 /** * 画立方体 * */ function drawCube(){ var geometry = new THREE.BoxGeometry( 100, 100,100); geometry.colorsNeedUpdate = true; //下面设置了polygonOffset:true,polygonOffsetFactor:0.5 var material = new THREE.MeshBasicMaterial({color:0xCCCCCC,transparent:false,polygonOffset:true,polygonOffsetFactor:0.5}); ..... }
1
2
3
4
5
6
7
8
9
10
11
12
11、添加网格参考 scene.add( new THREE.GridHelper( 500, 25 ) );
1
2
添加上面语句之后,屏幕中心会显示一个边长为500的水平面,水平面规格为25*2512、消除锯齿创建renderer的时候加上antialias参数renderer = new THREE.WebGLRenderer({antialias:true});
1
13、设置屏幕背景颜色renderer.setClearColor(0x348934,0.7);
1
第一个参数是颜色,第二个参数是透明度。屏幕背景默认是黑色的,所以透明度的值越小,屏幕月暗。14、将鼠标移动转换成转动首先要算出鼠标移动的速度:function onMouseMove(event){ var xDisp = event.clientX - prevX; var yDisp = event.clientY - prevY; //do something prevX = event.clientX; prevY = event.clientY; render(); }
1
2
3
4
5
6
7
8
9
10
11
onMouseMove不停的触发,相当于单位时间内触发一次,所以,单位时间内的位移即是速度。求出了鼠标的移动的速度,就可以乘以一定的系数转化成形状的转动,具体的系数可以尝试得出。15、移动轨迹修正由于照相机的位置不同,有时候threejs的坐标轴和屏幕的坐标轴并不一样,这时候,就要通过速度合成来修正物体移动轨迹。如下图,照相机位置在右上前方,可以看到,x轴都不是与屏幕平行的。http://img.blog.csdn.net/20160810141014533如果我们只是增加或减少物体的position.x,那么物体是斜向下运动的,所以我们要在y轴方向设置个速度加以修正。function onCubeDrag(event){ var xDisp = event.clientX - prevX; var yDisp = event.clientY - prevY; cube_Border_Axis_Group.position.x += xDisp; //将三维坐标的移动转换成2D坐标的移动,0.4这个系数是根据视角得出 cube_Border_Axis_Group.position.y += xDisp*(0.4); cube_Border_Axis_Group.position.y -= yDisp; prevX = event.clientX; prevY = event.clientY; render(); }
1
2
3
4
5
6
7
8
9
10
11
12
16、立体缩放 function onDocumentMouseWheel(event){ if(event.wheelDelta>0){ //判断滚轮滚动方向 cube_Border_Axis_Group.scale.multiplyScalar(1.02); }else{ cube_Border_Axis_Group.scale.multiplyScalar(0.98); } render(); }
1
2
3
4
5
6
7
8
17、创建2D文字 /** *使用示例:创建XYZ * */ function createXYZText(){ //创建Z var spritey = makeTextSprite( "Z", { fontsize: 100} ); spritey.position.set(0,10,200); scene.add(spritey); //创建X spritey = makeTextSprite( "X", { fontsize: 100 } ); spritey.position.set(230,30,0); scene.add(spritey); //创建Y spritey = makeTextSprite( "Y", { fontsize: 100} ); spritey.position.set(0,200,0); scene.add(spritey); } /** * 创建永远面向相机的2D文字 * */ function makeTextSprite( message, parameters ) { if ( parameters === undefined ) parameters = {}; var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial"; var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18; var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4; var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] : { r:0, g:0, b:0, a:1.0 }; var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.font = "Bold " + fontsize + "px " + fontface; var metrics = context.measureText( message ); var textWidth = metrics.width; context.lineWidth = borderThickness; context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)"; context.fillText( message, borderThickness, fontsize + borderThickness); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false } ); var sprite = new THREE.Sprite( spriteMaterial ); sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize); return sprite; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
参考three-js-2d-text-sprite-labels18、创建圆柱function drawCylinder(topRadius,bottomRadius ,height){ //四个参数分别是上底面半径、下底面半径,高度,半径段数 var geometry = new THREE.CylinderGeometry(topRadius,bottomRadius,height,16); var material = new THREE.MeshBasicMaterial({visible:true,color:0x879378}); var cylinder = new THREE.Mesh(geometry,material); return cylinder; }
1
2
3
4
5
6
7
可以看到material设置了visible属性,这提醒我们可以设置圆柱体的可见性,为什么要这样做呢?因为在Threejs中,线本身是二维的,没有办法设置粗细,导致有时候,要选择一条线很难,这时,可以在线外面包一层不可见的圆柱,这样线就很好操作了。19、旋转参考系(世界坐标旋转)/** * 旋转参考系 * @param object 需要旋转的对象 * @param axis 旋转轴,是一个向量,new Vetor3(1,0,0)表示绕x轴顺时针旋转,Vetor3(1,0,0)表示绕X轴逆时针旋转 * @param radians 旋转的角度 */ function rotateAroundWorldAxis(object, axis, radians) { rotWorldMatrix = new THREE.Matrix4(); rotWorldMatrix.makeRotationAxis(axis.normalize(), radians); // old code for Three.JS pre r54: // rotWorldMatrix.multiply(object.matrix); // new code for Three.JS r55+: rotWorldMatrix.multiply(object.matrix); // pre-multiply object.matrix = rotWorldMatrix; // old code for Three.js pre r49: // object.rotation.getRotationFromMatrix(object.matrix, object.scale); // old code for Three.js pre r59: // object.rotation.setEulerFromRotationMatrix(object.matrix); // code for r59+: object.rotation.setFromRotationMatrix(object.matrix); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
物体动的效果可以是物体本身在动,比如,风车的转动;也可以是世界在动,比如,仰望星空,斗转星移。上面的代码和直接转动物体是一样的:object.rotation.z += Math.PI*5/ 180;
1
2
3
20、找例子别忘了github