当前位置: 首页 > 工具软件 > voxel.js > 使用案例 >

three.js学习 函数使用方法散记2

寇宏义
2023-12-01

八 动态添加物体(基于投射基础上)

if (isShiftDown) {
                        //例子用shift按下与否判断增加减少物体

						if ( intersect.object != plane ) {

						    scene.remove(intersect.object);
                            //如果按下  投射的物体不是平面 删除物体

							objects.splice( objects.indexOf( intersect.object ), 1 );
                            //貌似是删除后 将剩余物体连接起来..
						}

					} else {

					    normalMatrix.getNormalMatrix(intersect.object.matrixWorld);

                        //获取点击物体的 法矩阵?

					    var normal = intersect.face.normal.clone();
                        //获取点击物体的 法向量
						normal.applyMatrix3( normalMatrix ).normalize();
                        //用法矩阵矩阵 单位化法向量?  数学不太好
						var voxel = new THREE.Mesh( cubeGeometry, cubeMaterial );
						voxel.position.addVectors( intersect.point, normal );
                        //新建物体 按照向量定位位置
						voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
						scene.add( voxel );
                        
						objects.push( voxel );

					}



九  渐变色做法

var geometry3 = new THREE.Geometry(),
					points = hilbert3D( new THREE.Vector3( 0,0,0 ), 200.0, 2, 0, 1, 2, 3, 4, 5, 6, 7 ),
                    //返回一系列的点
                    colors3 = [];

				for ( i = 0; i < points.length; i ++ ) {

					geometry3.vertices.push( points[ i ] );
                    //将点压进geometry
					colors3[i] = new THREE.Color(0xffffff);
					colors3[ i ].setHSL( i / points.length, 1.0, 0.5 );
				    //设置颜色数组的颜色 和 hsl
				}

				geometry3.colors = colors3;
                //设置geometry的颜色数组是color3

十 各种material 

参见canvas_materials.html..太多了


十一 用一个canvas浮动在three.js canvas上 标记物体和观察点的位置

meshdepthmaterial 貌似是通过距离决定物体的颜色,,不用添加灯光...

				var material = new THREE.MeshDepthMaterial( { side: THREE.DoubleSide, overdraw: true } );


十二 倒影的做法

image = document.createElement( 'canvas' );
				image.width = 480;
				image.height = 204;
                //视频canvas
				imageContext = image.getContext( '2d' );
				imageContext.fillStyle = '#000000';
				imageContext.fillRect(0, 0, 480, 204);
                 

				texture = new THREE.Texture( image );
				texture.minFilter = THREE.LinearFilter;
				texture.magFilter = THREE.LinearFilter;
                //视频纹理 (以canvas为参数)

				var material = new THREE.MeshBasicMaterial({ map: texture, overdraw: true });
                //视频纹理material 

				imageReflection = document.createElement( 'canvas' );
				imageReflection.width = 480;
				imageReflection.height = 204;

				imageReflectionContext = imageReflection.getContext( '2d' );
				imageReflectionContext.fillStyle = '#000000';
				imageReflectionContext.fillRect(0, 0, 480, 204);
                //倒影canvas

				imageReflectionGradient = imageReflectionContext.createLinearGradient( 0, 0, 0, 204 );
				imageReflectionGradient.addColorStop( 0.2, 'rgba(240, 240, 240, 1)' );
				imageReflectionGradient.addColorStop(1, 'rgba(240, 240, 240, 0.8)');
                //倒影canvas的fillstyle 调用倒影context.createLinearGradient

				textureReflection = new THREE.Texture( imageReflection );
				textureReflection.minFilter = THREE.LinearFilter;
				textureReflection.magFilter = THREE.LinearFilter;
                //倒影 纹理

				var materialReflection = new THREE.MeshBasicMaterial( { map: textureReflection, side: THREE.BackSide, overdraw: true } );

				//倒影material

				var plane = new THREE.PlaneGeometry( 480, 204, 4, 4 );

				mesh = new THREE.Mesh( plane, material );
				mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.5;
				scene.add(mesh);

				mesh = new THREE.Mesh( plane, materialReflection );
				mesh.position.y = -306;
				mesh.rotation.x = - Math.PI;
				mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.5;
				scene.add( mesh );


注意:需要在render函数里面调用canvas.context.drawimage

if ( video.readyState === video.HAVE_ENOUGH_DATA ) {

					imageContext.drawImage( video, 0, 0 );

					if ( texture ) texture.needsUpdate = true;
					if ( textureReflection ) textureReflection.needsUpdate = true;

				}
			    //用以更新视频canvas 视频canvas context drawimage用video为参数 
			    //video = document.getElementById( 'video' );


				imageReflectionContext.drawImage( image, 0, 0 );
				imageReflectionContext.fillStyle = imageReflectionGradient;
				imageReflectionContext.fillRect(0, 0, 480, 204);
			    //倒影canvas content.drawimage用视频canvas做参数
                //fillstyle为上面定义的渐变


十三  three.spritematerial

var material = new THREE.SpriteMaterial();
						particle = new THREE.Sprite( material );
scene.add(particle);

//material 没有参数 但是生成的的particle是一个有宽度的点,用scale可以进行缩放

十四 用sparks控制对象的动画   

sparksEmitter = new SPARKS.Emitter(new SPARKS.SteadyCounter(160));

				emitterpos = new THREE.Vector3();

				sparksEmitter.addInitializer(new SPARKS.Position( new SPARKS.PointZone( emitterpos ) ) );
				sparksEmitter.addInitializer(new SPARKS.Lifetime(0,2));
				sparksEmitter.addInitializer(new SPARKS.Target(null, setTargetParticle));

				sparksEmitter.addInitializer(new SPARKS.Velocity(new SPARKS.PointZone(new THREE.Vector3(0,-50,10))));

				// TOTRY Set velocity to move away from centroid

				sparksEmitter.addAction(new SPARKS.Age());
                //貌似是定义了动画的生命周期,删除会出现大量的对象,  应该是默认了一个比较低的值
				//sparksEmitter.addAction(new SPARKS.Accelerate(0.2));
				sparksEmitter.addAction(new SPARKS.Move());
                //貌似是控制动画对象的动作,删除不会对外扩散
				sparksEmitter.addAction(new SPARKS.RandomDrift(50,50,2000));
                //貌似是控制动画对象的某个轴运动 删除后例子中对象不会向摄像机方向扩散
				sparksEmitter.addCallback("created", onParticleCreated);
                //对象的创建函数
				sparksEmitter.addCallback("dead", onParticleDead);
                //对象的结束函数
				sparksEmitter.start();

十五 接十四 shape对象getPointAt()可以返回轨迹的点   来控制sparks动画的对象的位置  主要在render函数里面
heartShape = new THREE.Shape();

				heartShape.moveTo( x + 25, y + 25 );
				heartShape.bezierCurveTo( x + 25, y + 25, x + 20, y, x, y );
				heartShape.bezierCurveTo( x - 30, y, x - 30, y + 35,x - 30,y + 35 );
				heartShape.bezierCurveTo( x - 30, y + 55, x - 10, y + 77, x + 25, y + 95 );
				heartShape.bezierCurveTo( x + 60, y + 77, x + 80, y + 55, x + 80, y + 35 );
				heartShape.bezierCurveTo( x + 80, y + 35, x + 80, y, x + 50, y );
				heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
一个shape

var pointOnShape = heartShape.getPointAt( timeOnShapePath/*索引*/ );//获取点

				emitterpos.x = pointOnShape.x * 5 - 100;
				emitterpos.y = -pointOnShape.y * 5 + 400;//设置位置
render函数里面调用

十六 用tween来控制实体动画

//该函数是自己定义的 每次创建实体都将创建的实体传入函数  然后调用
			function initParticle( particle, delay ) {

				var particle = this instanceof THREE.Sprite ? this : particle;
				var delay = delay !== undefined ? delay : 0;

				particle.position.set( 0, 0, 0 )
				particle.scale.x = particle.scale.y = Math.random() * 32 + 16;

				new TWEEN.Tween( particle )
					.delay( delay )
					.to( {}, 10000 )
					.onComplete( initParticle )
					.start();
                //设置动画结束后重新开始

				new TWEEN.Tween( particle.position )
					.delay( delay )
					.to( { x: Math.random() * 4000 - 2000, y: Math.random() * 1000 - 500, z: Math.random() * 4000 - 2000 }, 10000 )
					.start();
                //设置物体的位置
				new TWEEN.Tween( particle.scale )
					.delay( delay )
					.to( { x: 0, y: 0 }, 10000 )
					.start();
			    //控制物体的缩放   
			    //一个new tween 控制一种动画(位置 大小 也许一个tween也可以控制多种动画)要在render函数里调用 tween.update();


			}

十七  画闪光点点的画法

function generateSprite() {//调用spritematerial

				var canvas = document.createElement( 'canvas' );
				canvas.width = 16;
				canvas.height = 16;

				var context = canvas.getContext( '2d' );
				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
				gradient.addColorStop( 0, 'rgba(255,255,255,1)' );
				gradient.addColorStop( 0.2, 'rgba(0,255,255,1)' );
				gradient.addColorStop( 0.4, 'rgba(0,0,64,1)' );
				gradient.addColorStop( 1, 'rgba(0,0,0,1)' );

				context.fillStyle = gradient;
				context.fillRect( 0, 0, canvas.width, canvas.height );

				return canvas;//返回canvas作为纹理

			}

十八 不用tween 不用sparks也可控制实体动画 将实体保存在数组里,在render函数里循环设置每个实体的位置大小等,,,不过貌似没有用tween sparks优化的好..动起来卡卡的..而且应该设置延时比较不方便

新建实体

for ( var ix = 0; ix < AMOUNTX; ix ++ ) {

					for ( var iy = 0; iy < AMOUNTY; iy ++ ) {

						particle = particles[ i ++ ] = new THREE.Sprite( material );//保存进数组
						particle.position.x = ix * SEPARATION - ( ( AMOUNTX * SEPARATION ) / 2 );
						particle.position.z = iy * SEPARATION - ( ( AMOUNTY * SEPARATION ) / 2 );
						scene.add( particle );

					}

				}
render函数里调用

for ( var ix = 0; ix < AMOUNTX; ix ++ ) {

					for ( var iy = 0; iy < AMOUNTY; iy ++ ) {

						particle = particles[ i++ ];
						particle.position.y = ( Math.sin( ( ix + count ) * 0.3 ) * 50 ) +
							( Math.sin( ( iy + count ) * 0.5 ) * 50 );
						particle.scale.x = particle.scale.y = ( Math.sin( ( ix + count ) * 0.3 ) + 1 ) * 4 +
							( Math.sin( ( iy + count ) * 0.5 ) + 1 ) * 4;

					}

				}				count += 0.1;

十九 正20面体geometry

geometry = new THREE.IcosahedronGeometry( 100, 1 );//第一个参数是半径 第二个参数叫detial 貌似+1顶点数目就*2

				material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } );//之后mesh

二十 css3d

包含 <script src="js/renderers/CSS3DRenderer.js"></script>

renderer = new THREE.CSS3DRenderer();

var side = sides[ i ];

					var element = document.createElement( 'img' );
					element.width = 1027; // 2 pixels extra to close the gap.
					element.src = side.url;

					var object = new THREE.CSS3DObject( element );//我有特殊的新建对象的方法
					object.position.fromArray( side.position );//可以读取json数据设置位置 scale等等
					object.rotation.fromArray( side.rotation );
					scene.add( object );

通过设置html元素的css样式  添加成css3dobject  来控制html元素

二十一   trackballcontrol使用

<script src="js/controls/TrackballControls.js"></script>

controls = new THREE.TrackballControls( camera );//将camera传入当参数 控制摄像机(观察点)的移动

				controls.rotateSpeed = 1.0;
				controls.zoomSpeed = 1.2;
				controls.panSpeed = 0.8;

				controls.noZoom = false;
				controls.noPan = false;

				controls.staticMoving = false;
				controls.dynamicDampingFactor = 0.3;

				controls.keys = [ 65, 83, 68 ];

二十二 css3d sprite对象使用(css3drender 中的纹理使用方法吧 好像比较麻烦 )

var sprite = document.createElement('img');
                //新建一个img对象
				sprite.addEventListener( 'load', function ( event ) {

					for ( var i = 0, j = 0; i < particlesTotal; i ++, j += 3 ) {

					    var canvas = document.createElement('canvas');
                        //新建canvas
						canvas.width = sprite.width;
						canvas.height = sprite.height;

						var context = canvas.getContext( '2d' );
						context.drawImage( sprite, 0, 0 );
                        //canvas用img元素来画图
						var object = new THREE.CSS3DSprite(canvas);
                        //css3dsprite对象用canvas作为参数
						object.position.x = Math.random() * 4000 - 2000,
						object.position.y = Math.random() * 4000 - 2000,
						object.position.z = Math.random() * 4000 - 2000
						scene.add( object );

						objects.push( object );

					}

					transition();

				}, false );
				sprite.src = 'textures/sprite.png';


 类似资料: