- THREE.js 下载
- THREE.js 官方文档
- THREE.js 中文基础教程
- THREE.MeshLine 立体线条插件
- orbitcontrols 官方示例中的三轨控制插件
- THREE.js 效果示例
- Three.js入门指南(电子书)
例子
THREE.js + THREE.MeshLine 实现.
在head中引入js文件
<script src="js/three.js"></script>
<!-- OrbitControls 控制界面转动 -->
<script src="js/OrbitControls.js"></script>
<!-- MeshLine three的立体线段库 -->
<script src="js/THREE.MeshLine.js"></script>
.
在THREE.js中的三个主要组成 场景(scene)、相机(camera)和渲染器(renderer)
// 获取div
var container = document.getElementById( 'container' );
// 新建场景
var scene = new THREE.Scene();
// 新建相机
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, .1, 1000);
// 相机角度
camera.position.set( 0, 0, -10 );
// 渲染器 antialias抗锯齿 alpha透明度 setSize大小
var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild( renderer.domElement );
// 添加到页面
var controls = new THREE.OrbitControls( camera, renderer.domElement );
.
新建几何体geometry和三维向量(点)Vector3
// 创建曲线所有点集合
function createCurve() {
// clone 复制,add相加, p0原点, multiplyScalar相乘
var p0 = new THREE.Vector3(0,0,0);
var p1 = p0.clone().add( new THREE.Vector3( .5 - Math.random(), .5 - Math.random(), .5 - Math.random() ) );
var p2 = p1.clone().add( new THREE.Vector3( .5 - Math.random(), .5 - Math.random(), .5 - Math.random() ) );
var p3 = p2.clone().add( new THREE.Vector3( .5 - Math.random(), .5 - Math.random(), .5 - Math.random() ) );
p0.multiplyScalar( 5 + (Math.random() * 10) );
p1.multiplyScalar( 5 + (Math.random() * 10) );
p2.multiplyScalar( 5 + (Math.random() * 10) );
p3.multiplyScalar( 5 + (Math.random() * 10) );
// inc控制点的数量(inc越小,线段越平滑)
var inc = 0.001;
var points = [];
var res = new THREE.Vector3(0,0,0);
for( var j = 0; j <= 1; j += inc ) {
var i = ( 1 - j );
var ii = i * i;
var iii = ii * i;
var jj = j * j;
var jjj = jj * j;
res.set( 0, 0, 0 );
// multiplyScalar与传入的标量相乘
// add与传入的向量相加
// .clone() 为点的深度复制
res.add( p0.clone().multiplyScalar( iii ) );
res.add( p1.clone().multiplyScalar( 3 * j * ii ) );
res.add( p2.clone().multiplyScalar( 3 * jj * i ) );
res.add( p3.clone().multiplyScalar( jjj ) );
points.push( res.clone() );
}
points.push( p3.clone() );
// 新建几何体
var geometry = new THREE.BufferGeometry();
const pointsArray = new Array()
for (var j = 0; j < points.length - 1; j++) {
pointsArray.push(points[j].clone());
}
geometry.setFromPoints(pointsArray);
// 返回该线段
return geometry;
}
.
创建THREE.Mesh
-
创建一个MeshLine 并用.setGeometry()传递顶点,.setGeometry()第二个参数定义线段宽度
-
一个MeshLine需要MeshLineMaterial(线段材质)
-
最后使用MeshLine和MeshLineMaterial创建THREE.Mesh, 记得添加到scene
// 线材质参数
var Params = function() {
// 数量
this.amount = 100;
// 线条宽度为10
this.lineWidth = 10;
// 设置虚线的空隙大小,设置为零时,线段会连成一条线
this.dashArray = 0;
// 定义虚线开始的位置
this.dashOffset = 0;
// 虚线的空隙比例
this.dashRatio = 0.9;
// 设置为抛物线,none , linear, wavy
this.taper = 'parabolic';
// 是否有透视效果(false - 透视,true - 不透视)
this.sizeAttenuation = false;
};
var params = new Params();
// 颜色数组,随机颜色使用
var colors = [
0xed6a5a,0xf4f1bb, 0x9bc1bc,0x5ca4a9,0xe6ebe0,
0xf0b67f,0xfe5f55,0xd6d1b1,0xc7efcf,0xeef5db,
0x50514f,0xf25f5c,0xffe066,0x247ba0,0x70c1b3
];
// 线段生产,geometry
function makeLine( geometry ) {
var g = new MeshLine();
switch( params.taper ) {
// 设置线段宽度,setGeometry第一个参数是三维点的集合,第二个参数是每两个点之间的线段宽度变化函数
// 没有
case 'none': g.setGeometry( geometry ); break;
// 线性
case 'linear': g.setGeometry( geometry, function( p ) { return 1 - p; } ); break;
// 抛物线
case 'parabolic': g.setGeometry( geometry, function( p ) { return 1 * Math.pow( 4 * p * ( 1 - p ), 1 )} ); break;
// 波浪
case 'wavy': g.setGeometry( geometry, function( p ) { return 2 + Math.sin( 50 * p ) } ); break;
}
const resolution = new THREE.Vector2(window.innerWidth,window.innerHeight);
// 设置线段材质
var material = new MeshLineMaterial( {
// 随机颜色
color: new THREE.Color( colors[ Math.floor(Math.random()*colors.length) ] ),
// 透明度
opacity: 1,
// 虚线的线段之前空隙,为零则为实线
dashArray: params.dashArray,
// 虚线开始的位置
dashOffset: params.dashOffset,
// 虚线 的线段与空隙比例
dashRatio: params.dashRatio,
// 二维向量指定画布大小,必需
resolution: resolution,
// 线宽是否衰减(是否有透视效果)
sizeAttenuation: params.sizeAttenuation,
// 线宽
lineWidth: params.lineWidth,
// 摄像机近剪裁平面距离,跟随相机(sizeAttenuation为false时必须设置)
near: camera.near,
// 相机远剪裁平面距离,跟随相机(sizeAttenuation为false时必须设置)
far: camera.far,
// transparent: true
});
var mesh = new THREE.Mesh( g.geometry, material );
scene.add( mesh );
}
.
将新的场景绘制到浏览器中 renderer.render( scene, camera );
// 根据数量amount创建线段
function createLines() {
for( var j = 0; j < params.amount; j++ ) {
makeLine( createCurve() );
}
}
// 每一帧都自动刷新场景requestAnimationFrame
function render(){
requestAnimationFrame(render);
renderer.render(scene, camera);
}
createLines();
render();
附 css
*{ box-sizing: border-box; margin :0; padding: 0;}
body{ overflow: hidden; width: 100%; height: 100% ; background-color: #eeeeee; padding: 20px;}
#container{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; width: 100%; height: 100%;}
网友评论