three.js实现线条,平面,球体相互运动文档说明

概况如下:

1、SphereGeometry实现球体,球体材质使用MeshBasicMaterial定义color来实现;

2、THREE.ShapeGeometry将二维点组成的平面图形转换为面,THREE.Vector2获取二维圆面周上的点;

3、MeshLine实现圆圈;

效果图如下:

初始化场景、相机、渲染器,设置相机位置,初始化光源,光源采用点光源PointLight,设置光源位置为场景中心位置,并将光源加入场景中。

// 初始化场景
var scene = new THREE.Scene();
// 初始化相机,第一个参数为摄像机视锥体垂直视野角度,第二个参数为摄像机视锥体长宽比,
// 第三个参数为摄像机视锥体近端面,第四个参数为摄像机视锥体远端面
var camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000);
// 设置相机位置,对应参数分别表示x,y,z位置
camera.position.set(0, 0, 400);
var renderer = new THREE.WebGLRenderer({
	  alpha: true,
	  antialias: true
});

设置场景窗口尺寸,并且初始化控制器,窗口尺寸默认与浏览器窗口尺寸保持一致,最后将渲染器加载到dom中。

// 设置窗口尺寸,第一个参数为宽度,第二个参数为高度
renderer.setSize(dom.clientWidth, dom.clientHeight);
// 初始化控制器
var orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);
// 将渲染器加载到dom中
dom.appendChild(renderer.domElement);

实现圆圈方法,通过MeshLine来实现。

// 画圆圈函数
/* circle 圆圈半径
 * circleSegements 圆圈分段数量
 * circleRap 圆弧分片数
 * color 圆圈颜色
 * lineWidth 圆圈线条宽度
 * opacity 圆圈线条颜色
 */
var drawCircle = function (circle, circleSegements, circleRap, color, lineWidth, opacity) {
	var group = new THREE.Group();
	var points = [];
	var average = circleSegements / circleRap;
	for (var i = 0; i < circleSegements; i ++) {
		if (i % average == 0 && points.length) {
			var shape = new THREE.Shape(points);
			var geometry = new THREE.ShapeGeometry(shape);
			var line = new MeshLine();
			line.setGeometry(geometry);
			var material = new MeshLineMaterial({
	    		color: color,
	    		lineWidth: lineWidth,
	    		transparent: true,
	    		opacity: opacity
	    	})
			var arc = new THREE.Mesh(line.geometry, material);
			group.add(arc);
			points = [];
		}
		if (i % (average * 2) < average) {
			points.push(new THREE.Vector2(circle * Math.cos(Math.PI * 2 * i / circleSegements), circle * Math.sin(Math.PI * 2 * i / circleSegements)))
		}
	}
	return group;
}

圆圈和球体运动方法。

// 圆圈和球体运动函数
var circleBallFun = function () {
	var lineColor = '#38d3f5';
	var ring1 = drawCircle(40, 100, 20, lineColor, 2, 1);
	var ring2 = drawCircle(30, 100, 20, lineColor, 2, 1);
	scene.add(ring1);
	scene.add(ring2);
	// 添加球体
	var centerBallRadio = 20;
	var centerBallRange = 5;
	var shapeRadioMax = 20;
    // 创建球体
    var centerBall = new THREE.Mesh(new THREE.SphereGeometry(centerBallRadio, 50, 50), new THREE.MeshBasicMaterial({
        color: '#017e68'
    }));
    centerBall.position.z = centerBallRadio + centerBallRange;
    scene.add(centerBall);
    // 添加平面圆圈
    var shapeRadio = 0;
    var shapeOpacity = 1;
    var shapeCircle = drawCircleShape(shapeRadio, 100, lineColor, shapeOpacity);
    scene.add(shapeCircle);
    var type = 'up';
    function animation () {
    	if (centerBall.position.z >= centerBallRadio + 2 * centerBallRange) {
    		type = 'down';
    		shapeRadio = 0;
    		shapeOpacity = 1;
    	}
    	if (centerBall.position.z <= centerBallRadio + centerBallRange) {
    		type = 'up';
    	}
    	if (type == 'up') {
    		centerBall.position.z += 0.1;
    		scene.remove(shapeCircle);
    		shapeRadio += shapeRadioMax / 50;
    		shapeOpacity -= 0.02;
    		shapeCircle = drawCircleShape(shapeRadio, 100, lineColor, shapeOpacity);
    		scene.add(shapeCircle);
    	} else {
    		centerBall.position.z -= 0.1;
    	}
    	ring1.rotation.z -= 0.01;
    	ring2.rotation.z += 0.01;
    	requestAnimationFrame(animation);
    }
    animation();
}

圆圈,圆面,球体position值来实现位置的确认,动画使用requestAnimationFrame来实现。

// 执行函数
var render = function () {
	scene.rotation.x = -1.2;
    renderer.render(scene, camera);
    orbitcontrols.update();
    requestAnimationFrame(render);
}

预览地址:朵朵视野-Three.js模拟圆圈与球体运动

下载地址:朵朵视野-Three.js模拟圆圈与球体运动