当前位置:   article > 正文

TransformControls 是 Three.js 中的一个类,用于在网页中进行 3D 场景中物体的交互式操作。

TransformControls 是 Three.js 中的一个类,用于在网页中进行 3D 场景中物体的交互式操作。

demo案例

TransformControls 是 Three.js 中的一个类,用于在网页中进行 3D 场景中物体的交互式操作。让我们来详细讲解它的输入参数、输出、属性和方法:
在这里插入图片描述

输入参数:

TransformControls 构造函数通常接受两个参数:

  1. camera(THREE.Camera):用于渲染场景的摄像机。这个参数是必需的。

  2. domElement(HTMLElement):控制器将附加到的 HTML 元素。通常是渲染器的 DOM 元素。这个参数是可选的,如果未提供,则控制器将附加到文档主体上。

输出:

TransformControls 实例:表示变换控制器的对象,初始化为指定的摄像机,并附加到指定的 DOM 元素(如果未提供元素,则附加到文档主体)。

属性:

  1. object(THREE.Object3D):由变换控制器操作的对象。

  2. enabled(布尔值):指示控制器当前是否已启用或禁用。

  3. space(字符串):指定变换空间(‘local’ 或 ‘world’),其中应用变换。

  4. size(数字):以像素为单位的变换控制器的大小。

  5. dragging(布尔值):指示用户当前是否正在拖动控制器。

  6. showX(布尔值)、showY(布尔值)、showZ(布尔值):指示是否显示沿 X、Y 和 Z 轴的控制手柄。

  7. mode(字符串):变换模式(‘translate’、‘rotate’ 或 ‘scale’)。

  8. camera(THREE.Camera):控制器使用的摄像机。

  9. domElement(HTMLElement):控制器附加到的 DOM 元素。

方法:

  1. attach(object: THREE.Object3D):将控制器附加到指定的对象以进行操作。

  2. detach():将控制器从任何对象中分离,有效地停止操作,直到附加新对象为止。

  3. dispose():移除控制器,释放资源。

  4. update():更新控制器。应该在渲染循环中的每一帧中调用。

  5. setMode(mode: String):将变换模式设置为 ‘translate’、‘rotate’ 或 ‘scale’ 中的一种。

  6. setSize(size: Number):设置变换控制器的大小(以像素为单位)。

  7. setSpace(space: String):将变换空间设置为 ‘local’ 或 ‘world’。

TransformControls 具体来说,它可以实现以下功能:

  1. 平移(Translate):您可以移动物体,使其沿着三维空间中的 X、Y 或 Z 轴移动。这对于调整物体在场景中的位置非常有用。

  2. 旋转(Rotate):您可以围绕物体的原点或者某一指定点进行旋转操作,改变物体的方向或朝向。

  3. 缩放(Scale):您可以调整物体的大小,使其放大或缩小。这在场景中创建视觉效果或者调整物体大小时非常有用。

  4. 设置变换空间(Set Transform Space):您可以选择将变换应用于物体的局部坐标系(Local Space)还是全局坐标系(World Space)。在局部坐标系中进行变换会受到物体当前旋转的影响,而在全局坐标系中进行变换则会忽略物体的旋转。

  5. 多轴控制(Multiple Axis Control):您可以单独控制每个轴上的变换,以便更精确地调整物体的位置、旋转或缩放。

  6. 实时交互(Real-time Interaction):变换控制器提供实时的交互式体验,您可以通过拖动控制器上的手柄来直接调整物体的变换参数。

  7. 自定义设置(Customization):您可以通过控制器的属性来自定义其外观和行为,例如控制手柄的显示、设置控制器的大小等。

<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - transform controls</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="main.css">
	</head>
	<body>

		<div id="info">
			"W" translate | "E" rotate | "R" scale | "+/-" adjust size<br />
			"Q" toggle world/local space |  "Shift" snap to grid<br />
			"X" toggle X | "Y" toggle Y | "Z" toggle Z | "Spacebar" toggle enabled<br />
			"Esc" reset current transform<br />
			"C" toggle camera | "V" random zoom
		</div>

		<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>

		<script type="module">

			import * as THREE from 'three';

			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
			import { TransformControls } from 'three/addons/controls/TransformControls.js';

			let cameraPersp, cameraOrtho, currentCamera;
			let scene, renderer, control, orbit;

			init();
			render();

			function init() {

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				document.body.appendChild( renderer.domElement );

				const aspect = window.innerWidth / window.innerHeight;

				cameraPersp = new THREE.PerspectiveCamera( 50, aspect, 0.01, 30000 );
				cameraOrtho = new THREE.OrthographicCamera( - 600 * aspect, 600 * aspect, 600, - 600, 0.01, 30000 );
				currentCamera = cameraPersp;

				currentCamera.position.set( 5, 2.5, 5 );

				scene = new THREE.Scene();
				scene.add( new THREE.GridHelper( 5, 10, 0x888888, 0x444444 ) );

				const ambientLight = new THREE.AmbientLight( 0xffffff );
				scene.add( ambientLight );

				const light = new THREE.DirectionalLight( 0xffffff, 4 );
				light.position.set( 1, 1, 1 );
				scene.add( light );

				const texture = new THREE.TextureLoader().load( 'textures/crate.gif', render );
				texture.colorSpace = THREE.SRGBColorSpace;
				texture.anisotropy = renderer.capabilities.getMaxAnisotropy();

				const geometry = new THREE.BoxGeometry();
				const material = new THREE.MeshLambertMaterial( { map: texture } );

				orbit = new OrbitControls( currentCamera, renderer.domElement );
				orbit.update();
				orbit.addEventListener( 'change', render );

				control = new TransformControls( currentCamera, renderer.domElement );
				control.addEventListener( 'change', render );

				control.addEventListener( 'dragging-changed', function ( event ) {

					orbit.enabled = ! event.value;

				} );

				const mesh = new THREE.Mesh( geometry, material );
				scene.add( mesh );

				control.attach( mesh );
				scene.add( control );

				window.addEventListener( 'resize', onWindowResize );

				window.addEventListener( 'keydown', function ( event ) {

					switch ( event.keyCode ) {

						case 81: // Q
							control.setSpace( control.space === 'local' ? 'world' : 'local' );
							break;

						case 16: // Shift
							control.setTranslationSnap( 100 );
							control.setRotationSnap( THREE.MathUtils.degToRad( 15 ) );
							control.setScaleSnap( 0.25 );
							break;

						case 87: // W
							control.setMode( 'translate' );
							break;

						case 69: // E
							control.setMode( 'rotate' );
							break;

						case 82: // R
							control.setMode( 'scale' );
							break;

						case 67: // C
							const position = currentCamera.position.clone();

							currentCamera = currentCamera.isPerspectiveCamera ? cameraOrtho : cameraPersp;
							currentCamera.position.copy( position );

							orbit.object = currentCamera;
							control.camera = currentCamera;

							currentCamera.lookAt( orbit.target.x, orbit.target.y, orbit.target.z );
							onWindowResize();
							break;

						case 86: // V
							const randomFoV = Math.random() + 0.1;
							const randomZoom = Math.random() + 0.1;

							cameraPersp.fov = randomFoV * 160;
							cameraOrtho.bottom = - randomFoV * 500;
							cameraOrtho.top = randomFoV * 500;

							cameraPersp.zoom = randomZoom * 5;
							cameraOrtho.zoom = randomZoom * 5;
							onWindowResize();
							break;

						case 187:
						case 107: // +, =, num+
							control.setSize( control.size + 0.1 );
							break;

						case 189:
						case 109: // -, _, num-
							control.setSize( Math.max( control.size - 0.1, 0.1 ) );
							break;

						case 88: // X
							control.showX = ! control.showX;
							break;

						case 89: // Y
							control.showY = ! control.showY;
							break;

						case 90: // Z
							control.showZ = ! control.showZ;
							break;

						case 32: // Spacebar
							control.enabled = ! control.enabled;
							break;

						case 27: // Esc
							control.reset();
							break;

					}

				} );

				window.addEventListener( 'keyup', function ( event ) {

					switch ( event.keyCode ) {

						case 16: // Shift
							control.setTranslationSnap( null );
							control.setRotationSnap( null );
							control.setScaleSnap( null );
							break;

					}

				} );

			}

			function onWindowResize() {

				const aspect = window.innerWidth / window.innerHeight;

				cameraPersp.aspect = aspect;
				cameraPersp.updateProjectionMatrix();

				cameraOrtho.left = cameraOrtho.bottom * aspect;
				cameraOrtho.right = cameraOrtho.top * aspect;
				cameraOrtho.updateProjectionMatrix();

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

				render();

			}

			function render() {

				renderer.render( scene, currentCamera );

			}

		</script>

	</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222

本内容来源于小豆包,想要更多内容请跳转小豆包 》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/327232
推荐阅读
相关标签
  

闽ICP备14008679号