three.js 通过 CSS3DRenderer 实现全景浏览 (转)

  上一篇是通过WebGlRenderer渲染器,加上几何贴图实现的一张全景浏览,但是会出现,图片的大小和画质会被改变,导致渲染的不清晰,那么本篇是通过CSS3DRenderer来实现全景浏览,和上次不同的是这次是六张图,分别铺满一个立方体盒子的六个面。

è¿éåå¾çæè¿°

示例
https://ithanmang.gitee.io/threejs/home/example/css3drenderer/index.html
效果
è¿éåå¾çæè¿°

代码:

<!DOCTYPE html>
<html>

	<head>
		<title>three.js css3d - panorama</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				margin: 0;
				overflow: hidden;
			}
		</style>
	</head>

	<body>
		<script src="https://ithanmang.gitee.io/threejs/home/libs/build/three-r93.js"></script>
		<script src="https://ithanmang.gitee.io/threejs/home/libs/examples/js/renderers/CSS3DRenderer.js"></script>

		<script>
			var camera, scene, renderer;

			/* 相机聚焦点 */
			var target = new THREE.Vector3();

			/* lon:经度, lat:维度  经纬度是相机的聚焦点 */
			var lon = 90,
				lat = 0;

			/* 相机聚焦点,弧度制 */
			var phi = 0,
				theta = 0;

			/* 移动端输入的x,y */
			var touchX, touchY;

			/* 图片路径 */
			var src = 'https://ithanmang.gitee.io/threejs/home/example/css3drenderer/images/siximg/par.front.jpg';

			/* 因为图片加载比较慢可以先设置一个背景图 */
			document.body.style.backgroundImage = 'url(' + src + ")";
			document.body.style.backgroundRepeat = 'no-repeat';
			document.body.style.backgroundSize = window.innerWidth + 'px ' + window.innerHeight + 'px';

			var img = new Image();
			img.src = src;

			/* 图片加载完之后调用 */
			img.onload = function() {

				init(img.width, src);
				animate();

			};

			function init(width, imageSrc) {

				img = null;

				camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);

				scene = new THREE.Scene();

				/* 图片路径 */
				let src = 'https://ithanmang.gitee.io/threejs/home/example/css3drenderer/images/siximg/par.';

				/* 图片格式 */
				let format = '.jpg';

				/* 以下六个面 拼接成立方体 */
				var sides = [{
						url: src + 'left' + format,
						position: [-width / 2, 0, 0],
						/* 左 */
						rotation: [0, Math.PI / 2, 0]
					},
					{
						url: src + 'right' + format,
						position: [width / 2, 0, 0],
						/* 右 */
						rotation: [0, -Math.PI / 2, 0]
					},
					{
						url: src + 'top' + format,
						position: [0, width / 2, 0],
						/* 上 */
						rotation: [Math.PI / 2, 0, Math.PI]
					},
					{
						url: src + 'bottom' + format,
						position: [0, -width / 2, 0],
						/* 下 */
						rotation: [-Math.PI / 2, 0, Math.PI]
					},
					{
						url: src + 'back' + format,
						position: [0, 0, width / 2],
						/* 后 */
						rotation: [0, Math.PI, 0]
					},
					{
						url: src + 'front' + format,
						position: [0, 0, -width / 2],
						/* 前 */
						rotation: [0, 0, 0]
					}
				];

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

					var side = sides[i];

					var element = document.createElement('img');

					element.width = width + 6;
					element.src = side.url;

					var css3Loader = new THREE.CSS3DObject(element);
					css3Loader.position.fromArray(side.position);
					css3Loader.rotation.fromArray(side.rotation);

					scene.add(css3Loader);

				}

				renderer = new THREE.CSS3DRenderer();
				renderer.setSize(window.innerWidth, window.innerHeight);
				document.body.appendChild(renderer.domElement);

				document.addEventListener('mousedown', onDocumentMouseDown, false);
				document.addEventListener('wheel', onDocumentMouseWheel, false);

				document.addEventListener('touchstart', onDocumentTouchStart, false);
				document.addEventListener('touchmove', onDocumentTouchMove, false);

				window.addEventListener('resize', onWindowResize, false);

			}

			function onWindowResize() {

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize(window.innerWidth, window.innerHeight);

			}

			function onDocumentMouseDown(event) {

				event.preventDefault();

				document.body.style.cursor = 'move';

				document.addEventListener('mousemove', onDocumentMouseMove, false);
				document.addEventListener('mouseup', onDocumentMouseUp, false);

			}

			function onDocumentMouseMove(event) {

				var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
				var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

				/* 拖动速度随相机视角的变动而变动 */
				var speed = camera.fov * 0.0015;

				/* 经纬度平移速度 */
				lon -= movementX * speed;
				lat += movementY * speed;

			}

			function onDocumentMouseUp(event) {

				event.preventDefault();

				document.body.style.cursor = 'auto';

				document.removeEventListener('mousemove', onDocumentMouseMove);
				document.removeEventListener('mouseup', onDocumentMouseUp);

			}

			function onDocumentMouseWheel(event) {

				/* 缩放速度 */
				var speed = 0.008;

				var fov = camera.fov + event.deltaY * speed;

				/* 角度缩放最值 */
				camera.fov = THREE.Math.clamp(fov, 45, 95);

				camera.updateProjectionMatrix();

			}

			function onDocumentTouchStart(event) {

				event.preventDefault();

				var touch = event.touches[0];

				touchX = touch.screenX;
				touchY = touch.screenY;

			}

			function onDocumentTouchMove(event) {

				event.preventDefault();

				var touch = event.touches[0];

				lon -= (touch.screenX - touchX) * 0.1;
				lat += (touch.screenY - touchY) * 0.1;

				touchX = touch.screenX;
				touchY = touch.screenY;

			}

			function animate() {

				requestAnimationFrame(animate);

				lat = Math.max(-85, Math.min(85, lat));
				phi = THREE.Math.degToRad(90 - lat);
				theta = THREE.Math.degToRad(lon);

				target.x = Math.sin(phi) * Math.cos(theta);
				target.y = Math.cos(phi);
				target.z = Math.sin(phi) * Math.sin(theta);

				camera.lookAt(target);

				renderer.render(scene, camera);

			}
		</script>
	</body>

</html>

说明:

(1)偶然看到一个例子,感觉蛮有趣的,可以运行,留作自己收藏;

(2)修改了一下需要引入的资源的路径,可以直接运行;

(3)文章的作者注释比较详细,看起来也会比较方便;

(4)转载地址:https://blog.csdn.net/ithanmang/article/details/82013276

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值