three.js实现世界地图城市标记文档说明

概况如下:

1、THREE.Shape绘制世界地图平面地图;

2、THREE.ExtrudeGeometry将绘制的平面沿着Z轴拉伸,实现3d效果;

3、THREE.CylinderGeometry实现在平面地图上添加圆锥体;

4、THREE.SphereGeometry实现在平面地图上添加球体;

5、THREE.CanvasTexture通过canvas实现在平面地图上添加文字说明;

效果图如下:

初始化场景、相机、渲染器,设置相机位置,初始化光源。

// 初始化场景
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);

绘制世界地图平面方法

// 绘制世界平面地图函数
var drawShape = function (pos, averageX, averageY) {
	var shape = new THREE.Shape();
	shape.moveTo(pos[0][0] - averageX, pos[0][1] - averageY);
	pos.forEach(function (item) {
		shape.lineTo(item[0] - averageX, item[1] - averageY);
	})
	return shape;
}

将平面地图沿着z轴拉伸转换配置参数

// ExturdeGeometry配置参数
var options = {
	depth: 3, // 定义图形拉伸的深度,默认100
	steps: 0, // 拉伸面方向分为多少级,默认为1
	bevelEnabled: true, // 表示是否有斜角,默认为true
	bevelThickness: 0, // 斜角的深度,默认为6
	bevelSize: 0, // 表示斜角的高度,高度会叠加到正常高度
	bebelSegments: 0, // 斜角的分段数,分段数越高越平滑,默认为1
	curveSegments: 0 // 拉伸体沿深度方向分为多少段,默认为1
}

将平面地图沿着z轴拉伸转换为3d方法

// 将shape转换为ExtrudeGeometry
var transition3d = function (shapeObj, identify) {
	var geometry = new THREE.ExtrudeGeometry(shapeObj, options);
    var material1 = new THREE.MeshBasicMaterial({
    	color: faceColor
    });
    var material2 = new THREE.MeshBasicMaterial({
    	color: sideColor
    });
    // 绘制地图
    shapeGeometryObj['shapeGeometry' + identify] = new THREE.Mesh(geometry, [material1, material2]);
    // 将地图加入场景
    scene.add(shapeGeometryObj['shapeGeometry' + identify])
}

世界地图上添加标记方法,分别用圆锥体和球体,提示文字信息通过canvas实现

/** 绘制标记函数
 * pos表示经纬度信息
 * textValue表示标记内容
 * fontColor表示标记字体颜色
 * fontSize表示字体大小
**/
var drawMarkingFont = function (option, markingIndex) {
	var average = getAverage();
	var cityX = option.pos[0];
	var cityY = option.pos[1];
	var markingGroup = new THREE.Group();
	// 圆锥体
	var cylinder = new THREE.Mesh(
		new THREE.CylinderGeometry(circularRadio, 0, circularHeight, 50, 50, false),
		new THREE.MeshBasicMaterial({
			color: markingColor
		})
	)
	// 球体
	var ball = new THREE.Mesh(
		new THREE.SphereGeometry(circularRadio, 30, 30),
		new THREE.MeshBasicMaterial({
			color: markingColor
		})
	)
	ball.position.set(cityX, cityY, circularHeight + zHeight);
	cylinder.position.set(cityX, cityY, circularHeight / 2 + zHeight);
	cylinder.rotation.x = 1.5;
	// 添加文字说明
	var textLength = option.textValue.split('').length;
	var texture = new THREE.CanvasTexture(getCanvasFont(textLength * option.fontSize * average, option.fontSize * average, option.textValue, option.fontColor));
	var fontMesh = new THREE.Sprite(
		new THREE.SpriteMaterial({
			map: texture
		})
	)
	fontMesh.scale.x = option.fontSize / average * textLength;
	fontMesh.scale.y = option.fontSize / average;
	// 定义提示文字显示位置
	fontMesh.position.set(cityX, cityY, circularHeight + circularRadio / 2 + zHeight / 2 + option.fontSize / average + 0.5);
	markingGroup.add(ball);
	markingGroup.add(cylinder);
	markingGroup.add(fontMesh);
	markingObj['markingGroup' + markingIndex] = markingGroup;
	scene.add(markingGroup);
}

世界地图和柱状体通过position值来实现位置的确认,动画使用requestAnimationFrame来实现。

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

预览地址:朵朵视野-Three.js实现世界地图城市标记

下载地址:朵朵视野-Three.js实现世界地图城市标记