学习threejs,使用TrackballControls相机控制器

👨‍⚕️ 主页: gis分享者

👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用TrackballControls相机控制器,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.TrackballControls 相机控制器

TrackballControls是Three.js中的一个相机控件,它允许用户通过鼠标拖拽、滚轮缩放以及键盘移动相机,实现类似于球形的相机旋转操作。
TrackballControls 与 OrbitControls

TrackballControls 与 OrbitControls 相类似。然而,它不能恒定保持摄像机的up向量。 这意味着,如果摄像机绕过"北极"和"南极",则不会翻转以保持"右侧朝上"。

构造函数:

TrackballControls( camera : Camera, domElement : HTMLDOMElement )

camera: 渲染场景的摄像机。

domElement: 用于事件监听的HTML元素。

创建一个新的 TrackballControls 实例。

属性

.domElement : HTMLDOMElement

该 HTMLDOMElement 用于监听鼠标/触摸事件,该属性必须在构造函数中传入。在此处改变它将不会设置新的事件监听。
.dynamicDampingFactor : Number

设置阻尼的强度。仅在staticMoving设为false时考虑。默认为0.2。
.enabled : Boolean

是否启用控制器。
.keys : Array

该数组包含用于控制交互的按键代码。

当定义的第一个按键按下后,所有的鼠标交互(左/中/右键)表现为环绕。

当定义的第二个按键按下后,所有的鼠标交互(左/中/右键)表现为缩放。

当定义的第三个按键按下后,所有的鼠标交互(左/中/右键)表现为平移。

默认为KeyA, KeyS, KeyD,分别表示A, S, D。
.maxDistance : Number

你能够将相机向外移动多少,其默认值为Infinity。
.minDistance : Number

你能够将相机向内移动多少,其默认值为0。
.mouseButtons : Object

该对象包含由控件所使用的鼠标操作的引用。

  • .LEFT 指定给 THREE.MOUSE.ROTATE
  • .MIDDLE 指定给 THREE.MOUSE.ZOOM
  • .RIGHT 指定给 THREE.MOUSE.PAN

.noPan : Boolean

是否禁用平移,默认为false。
.noRotate : Boolean

是否禁用旋转,默认为false。
.noZoom : Boolean

是否禁用缩放,默认为false。
.object : Camera

正被控制的摄像机。
.panSpeed : Number

平移的速度,其默认值为0.3。
.rotateSpeed : Number

旋转的速度,其默认值为1.0。
.screen : Object

表示屏幕的属性。在handleResize()被调用时会自动设置。

  • left: 表示到屏幕左侧边界的偏移量(单位为像素)。
  • top: 表示到屏幕顶部边界的偏移量(单位为像素)。
  • width: 表示屏幕的宽度(单位为像素)。
  • height: 表示屏幕的高度(单位为像素)。

.staticMoving : Boolean

阻尼是否被禁用。默认为false。
.zoomSpeed : Number

缩放的速度,其默认值为1.2。

方法

.checkDistances () : undefined

确保控制器位于 [minDistance, maxDistance] 范围内。由update()调用。
.dispose () : undefined

若不再需要该控制器,则应当调用此函数。
.handleResize () : undefined

若应用程序窗口大小发生改变,则应当调用此函数。
.panCamera () : undefined

如有必要,执行平移。由update()调用。
.reset () : undefined

重置控制器到初始状态。
.rotateCamera () : undefined

如有必要,旋转相机。由update()调用。
.update () : undefined

更新控制器,常被用在动画循环中。
.zoomCamera () : undefined

如有必要,执行缩放。由update()调用。

事件
change

当摄像机被控制器变换后触发。
start

当交互(例如触摸)被初始化后触发。
end

当交互完成后触发。

二、🍀使用TrackballControls相机控制器

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景scene
  • 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
  • 4、创建THREE.SpotLight聚光灯光源spotLight,设置spotLight的位置信息,场景scene中添加spotLight。
  • 5、加载几何模型:创建THREE.OBJMTLLoader加载器loader,loader调用load方法加载'city.mtl'、'city.obj'模型。在load回调函数中,设置建筑物网格对象材质颜色和非建筑网格对象材质透明度、放射(光)颜色等信息。具体代码参考代码样例。
  • 6、加入THREE.TrackballControls相机控制器trackballControls,设置trackballControls相关参数。加入stats监控器,监控帧数信息。

2. ☘️代码样例

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>学习threejs,使用TrackballControls相机控制器</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/OBJLoader.js"></script>
    <script type="text/javascript" src="../libs/MTLLoader.js"></script>
    <script type="text/javascript" src="../libs/OBJMTLLoader.js"></script>
    <script type="text/javascript" src="../libs/stats.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <script type="text/javascript" src="../libs/chroma.js"></script>
    <script type="text/javascript" src="../libs/TrackballControls.js"></script>

    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

    // 初始化
    function init() {


        var clock = new THREE.Clock();

        var stats = initStats();

        // 创建三维场景
        var scene = new THREE.Scene();

        // 创建相机
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);


        // 创建渲染器,并设置大小
        var webGLRenderer = new THREE.WebGLRenderer();
        webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0));
        webGLRenderer.setSize(window.innerWidth, window.innerHeight);
        webGLRenderer.shadowMapEnabled = true;

        // 定义相机位置和方向
        camera.position.x = 100;
        camera.position.y = 100;
        camera.position.z = 300;
        camera.lookAt(new THREE.Vector3(0, 0, 0));


        var trackballControls = new THREE.TrackballControls(camera);
		
		// 设置TrackballControls相机控制器的参数
        trackballControls.rotateSpeed = 1.0;
        trackballControls.zoomSpeed = 1.0;
        trackballControls.panSpeed = 1.0;
//        trackballControls.noZoom=false;
//        trackballControls.noPan=false;
        trackballControls.staticMoving = true;
//        trackballControls.dynamicDampingFactor=0.3;

        var ambientLight = new THREE.AmbientLight(0x383838);
        scene.add(ambientLight);

        // 添加聚光灯光源,并设置投影
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(300, 300, 300);
        spotLight.intensity = 1;
        scene.add(spotLight);

        // 渲染器绑定html要素
        document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);

        var step = 0;
        var controls = new function () {
        };

        var gui = new dat.GUI();
        var mesh;

        var loader = new THREE.OBJMTLLoader();
        var load = function (object) {
            var scale = chroma.scale(['red', 'green', 'blue']);
            setRandomColors(object, scale);
            mesh = object;
            scene.add(mesh);
        };


        loader.load('../assets/models/city.obj', '../assets/models/city.mtl', load);
        function setCamControls() {
        }

        render();

        function setRandomColors(object, scale) {
            var children = object.children;
            if (children && children.length > 0) {
                children.forEach(function (e) {
                    setRandomColors(e, scale)
                });
            } else {
                // no children assume contains a mesh
                if (object instanceof THREE.Mesh) {
                    object.material.color = new THREE.Color(scale(Math.random()).hex());
                    if (object.material.name.indexOf("building") == 0) {
                        object.material.emissive = new THREE.Color(0x444444);
                        object.material.transparent = true;
                        object.material.opacity = 0.8;
                    }
                }
            }
        }


        function render() {
            stats.update();
            var delta = clock.getDelta();
            trackballControls.update(delta);
            requestAnimationFrame(render);
            webGLRenderer.render(scene, camera)
        }

        function initStats() {

            var stats = new Stats();
            stats.setMode(0); // 0: fps, 1: ms

            // Align top-left
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';

            document.getElementById("Stats-output").appendChild(stats.domElement);

            return stats;
        }
    }
    window.onload = init;
</script>
</body>
</html>

效果如下:

相关推荐
gis分享者3 天前
学习threejs,使用PointLight点光源
threejs·点光源·pointlight
gis分享者7 天前
学习threejs,使用HemisphereLight半球光
threejs·hemispherelight·半球光
gis分享者11 天前
学习threejs,使用Lensflare模拟镜头眩光
threejs·lensflare·眩光
gis分享者14 天前
学习threejs,tga格式图片文件贴图
threejs·贴图·tga·tgaloader
gis分享者14 天前
学习threejs,pvr格式图片文件贴图
threejs·贴图·pvr
gis分享者1 个月前
学习threejs,使用OrbitControls相机控制器
threejs·相机·相机控制器·orbitcontrols
不系舟1781 个月前
threejs 实现镜面反射,只反射指定物体,背景透明
threejs
gis分享者1 个月前
学习threejs,使用RollControls相机控制器
threejs·相机控制器·rollcontrols
gis分享者1 个月前
学习threejs,使用FlyControls相机控制器
threejs·相机控制器·flycontrols