senangwebs-aframe-editor 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/.babelrc +3 -0
  2. package/.editorconfig +12 -0
  3. package/.eslintignore +2 -0
  4. package/.eslintrc +40 -0
  5. package/.github/workflows/ci.yml +39 -0
  6. package/.husky/pre-commit +4 -0
  7. package/.prettierignore +1 -0
  8. package/.prettierrc.json +5 -0
  9. package/.stylelintrc +12 -0
  10. package/LICENSE +21 -0
  11. package/README.md +75 -0
  12. package/assets/gltf.svg +49 -0
  13. package/dist/aframe-inspector.js +106250 -0
  14. package/dist/aframe-inspector.js.map +1 -0
  15. package/dist/aframe-inspector.min.js +29040 -0
  16. package/dist/aframe-inspector.min.js.LICENSE.txt +56 -0
  17. package/dist/aframe-inspector.min.js.map +1 -0
  18. package/examples/360video.html +48 -0
  19. package/examples/colors.html +18 -0
  20. package/examples/controllers.html +60 -0
  21. package/examples/embedded-zoom.html +78 -0
  22. package/examples/embedded.html +79 -0
  23. package/examples/empty.html +13 -0
  24. package/examples/index-aframe.html +66 -0
  25. package/examples/index.html +71 -0
  26. package/examples/supercraft.html +6 -0
  27. package/index.html +8 -0
  28. package/package.json +84 -0
  29. package/senangwebs-webverse-editor.png +0 -0
  30. package/src/components/AwesomeIcon.js +53 -0
  31. package/src/components/Collapsible.js +57 -0
  32. package/src/components/EntityRepresentation.js +83 -0
  33. package/src/components/Main.js +222 -0
  34. package/src/components/__tests__/Collapsible.test.js +30 -0
  35. package/src/components/components/AddComponent.js +104 -0
  36. package/src/components/components/CommonComponents.js +160 -0
  37. package/src/components/components/Component.js +151 -0
  38. package/src/components/components/ComponentsContainer.js +52 -0
  39. package/src/components/components/DefaultComponents.js +1 -0
  40. package/src/components/components/Mixins.js +83 -0
  41. package/src/components/components/PropertyRow.js +145 -0
  42. package/src/components/components/Sidebar.js +51 -0
  43. package/src/components/icons/BackViewIcon.js +27 -0
  44. package/src/components/icons/BottomViewIcon.js +26 -0
  45. package/src/components/icons/FrontViewIcon.js +23 -0
  46. package/src/components/icons/LeftViewIcon.js +24 -0
  47. package/src/components/icons/PerspectiveIcon.js +23 -0
  48. package/src/components/icons/PrimitiveBoxIcon.js +143 -0
  49. package/src/components/icons/PrimitiveConeIcon.js +44 -0
  50. package/src/components/icons/PrimitiveCylinderIcon.js +51 -0
  51. package/src/components/icons/PrimitiveEmptyEntityIcon.js +78 -0
  52. package/src/components/icons/PrimitiveImageIcon.js +86 -0
  53. package/src/components/icons/PrimitiveLightIcon.js +107 -0
  54. package/src/components/icons/PrimitivePlaneIcon.js +87 -0
  55. package/src/components/icons/PrimitiveSphereIcon.js +39 -0
  56. package/src/components/icons/PrimitiveTextIcon.js +89 -0
  57. package/src/components/icons/PrimitiveTorusIcon.js +31 -0
  58. package/src/components/icons/RightViewIcon.js +24 -0
  59. package/src/components/icons/TopViewIcon.js +24 -0
  60. package/src/components/modals/Modal.js +107 -0
  61. package/src/components/modals/ModalHelp.js +97 -0
  62. package/src/components/modals/ModalPrimitive.js +114 -0
  63. package/src/components/modals/ModalTextures.js +430 -0
  64. package/src/components/scenegraph/Entity.js +142 -0
  65. package/src/components/scenegraph/SceneGraph.js +337 -0
  66. package/src/components/scenegraph/Toolbar.js +147 -0
  67. package/src/components/viewport/CameraToolbar.js +122 -0
  68. package/src/components/viewport/TransformToolbar.js +102 -0
  69. package/src/components/viewport/ViewportHUD.js +33 -0
  70. package/src/components/widgets/BooleanWidget.js +49 -0
  71. package/src/components/widgets/ColorWidget.js +89 -0
  72. package/src/components/widgets/InputWidget.js +42 -0
  73. package/src/components/widgets/NumberWidget.js +179 -0
  74. package/src/components/widgets/SelectWidget.js +58 -0
  75. package/src/components/widgets/TextureWidget.js +252 -0
  76. package/src/components/widgets/Vec2Widget.js +55 -0
  77. package/src/components/widgets/Vec3Widget.js +58 -0
  78. package/src/components/widgets/Vec4Widget.js +61 -0
  79. package/src/components/widgets/index.js +9 -0
  80. package/src/index.js +301 -0
  81. package/src/lib/EditorControls.js +336 -0
  82. package/src/lib/Events.js +6 -0
  83. package/src/lib/TransformControls.js +1365 -0
  84. package/src/lib/assetsLoader.js +43 -0
  85. package/src/lib/assetsUtils.js +30 -0
  86. package/src/lib/cameras.js +121 -0
  87. package/src/lib/entity.js +556 -0
  88. package/src/lib/history.js +30 -0
  89. package/src/lib/raycaster.js +129 -0
  90. package/src/lib/shortcuts.js +211 -0
  91. package/src/lib/utils.js +118 -0
  92. package/src/lib/viewport.js +268 -0
  93. package/src/style/components.styl +275 -0
  94. package/src/style/entity.styl +22 -0
  95. package/src/style/help.styl +40 -0
  96. package/src/style/index.styl +358 -0
  97. package/src/style/lib.styl +41 -0
  98. package/src/style/primitiveModal.styl +90 -0
  99. package/src/style/scenegraph.styl +173 -0
  100. package/src/style/select.styl +71 -0
  101. package/src/style/textureModal.styl +220 -0
  102. package/src/style/viewport.styl +168 -0
  103. package/src/style/widgets.styl +71 -0
  104. package/webpack.config.js +65 -0
@@ -0,0 +1,211 @@
1
+ import Events from './Events';
2
+ import {
3
+ removeSelectedEntity,
4
+ cloneSelectedEntity,
5
+ cloneEntity
6
+ } from './entity';
7
+ import { getOS } from './utils';
8
+
9
+ const os = getOS();
10
+
11
+ function shouldCaptureKeyEvent(event) {
12
+ return (
13
+ event.target.closest('#cameraToolbar') ||
14
+ (event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA')
15
+ );
16
+ }
17
+
18
+ export const Shortcuts = {
19
+ enabled: false,
20
+ shortcuts: {
21
+ default: {},
22
+ modules: {}
23
+ },
24
+ onKeyUp: function (event) {
25
+ if (!shouldCaptureKeyEvent(event) || !AFRAME.INSPECTOR.opened) {
26
+ return;
27
+ }
28
+
29
+ var keyCode = event.keyCode;
30
+
31
+ // h: help
32
+ if (keyCode === 72) {
33
+ Events.emit('openhelpmodal');
34
+ }
35
+
36
+ // esc: unselect entity
37
+ if (keyCode === 27) {
38
+ if (this.inspector.selectedEntity) {
39
+ this.inspector.selectEntity(null);
40
+ }
41
+ }
42
+
43
+ // w: translate
44
+ if (keyCode === 87) {
45
+ Events.emit('transformmodechange', 'translate');
46
+ }
47
+
48
+ // e: rotate
49
+ if (keyCode === 69) {
50
+ Events.emit('transformmodechange', 'rotate');
51
+ }
52
+
53
+ // r: scale
54
+ if (keyCode === 82) {
55
+ Events.emit('transformmodechange', 'scale');
56
+ }
57
+
58
+ // o: transform space
59
+ if (keyCode === 79) {
60
+ Events.emit('transformspacechange');
61
+ }
62
+
63
+ // g: toggle grid
64
+ if (keyCode === 71) {
65
+ Events.emit('togglegrid');
66
+ }
67
+
68
+ // n: new entity
69
+ if (keyCode === 78) {
70
+ Events.emit('entitycreate', { element: 'a-entity', components: {} });
71
+ }
72
+
73
+ // backspace & delete: remove selected entity
74
+ if (keyCode === 8 || keyCode === 46) {
75
+ removeSelectedEntity();
76
+ }
77
+
78
+ // d: clone selected entity
79
+ if (keyCode === 68) {
80
+ cloneSelectedEntity();
81
+ }
82
+
83
+ // f: Focus on selected entity.
84
+ if (keyCode === 70) {
85
+ const selectedEntity = AFRAME.INSPECTOR.selectedEntity;
86
+ if (selectedEntity !== undefined && selectedEntity !== null) {
87
+ Events.emit('objectfocus', selectedEntity.object3D);
88
+ }
89
+ }
90
+
91
+ if (keyCode === 49) {
92
+ Events.emit('cameraperspectivetoggle');
93
+ } else if (keyCode === 50) {
94
+ Events.emit('cameraorthographictoggle', 'left');
95
+ } else if (keyCode === 51) {
96
+ Events.emit('cameraorthographictoggle', 'right');
97
+ } else if (keyCode === 52) {
98
+ Events.emit('cameraorthographictoggle', 'top');
99
+ } else if (keyCode === 53) {
100
+ Events.emit('cameraorthographictoggle', 'bottom');
101
+ } else if (keyCode === 54) {
102
+ Events.emit('cameraorthographictoggle', 'back');
103
+ } else if (keyCode === 55) {
104
+ Events.emit('cameraorthographictoggle', 'front');
105
+ }
106
+
107
+ for (var moduleName in this.shortcuts.modules) {
108
+ var shortcutsModule = this.shortcuts.modules[moduleName];
109
+ if (
110
+ shortcutsModule[keyCode] &&
111
+ (!shortcutsModule[keyCode].mustBeActive ||
112
+ (shortcutsModule[keyCode].mustBeActive &&
113
+ AFRAME.INSPECTOR.modules[moduleName].active))
114
+ ) {
115
+ this.shortcuts.modules[moduleName][keyCode].callback();
116
+ }
117
+ }
118
+ },
119
+ onKeyDown: function (event) {
120
+ if (!shouldCaptureKeyEvent(event) || !AFRAME.INSPECTOR.opened) {
121
+ return;
122
+ }
123
+
124
+ if (
125
+ (event.ctrlKey && os !== 'macos') ||
126
+ (event.metaKey && os === 'macos')
127
+ ) {
128
+ if (
129
+ AFRAME.INSPECTOR.selectedEntity &&
130
+ document.activeElement.tagName !== 'INPUT'
131
+ ) {
132
+ // c: copy selected entity
133
+ if (event.keyCode === 67) {
134
+ AFRAME.INSPECTOR.entityToCopy = AFRAME.INSPECTOR.selectedEntity;
135
+ }
136
+
137
+ // v: paste copied entity
138
+ if (event.keyCode === 86) {
139
+ cloneEntity(AFRAME.INSPECTOR.entityToCopy);
140
+ }
141
+ }
142
+
143
+ // s: focus search input
144
+ if (event.keyCode === 83) {
145
+ event.preventDefault();
146
+ event.stopPropagation();
147
+ document.getElementById('filter').focus();
148
+ }
149
+ }
150
+
151
+ // 0: toggle sidebars visibility
152
+ if (event.keyCode === 48) {
153
+ Events.emit('togglesidebar', { which: 'all' });
154
+ event.preventDefault();
155
+ event.stopPropagation();
156
+ }
157
+ },
158
+ enable: function () {
159
+ if (this.enabled) {
160
+ this.disable();
161
+ }
162
+
163
+ window.addEventListener('keydown', this.onKeyDown, false);
164
+ window.addEventListener('keyup', this.onKeyUp, false);
165
+ this.enabled = true;
166
+ },
167
+ disable: function () {
168
+ window.removeEventListener('keydown', this.onKeyDown);
169
+ window.removeEventListener('keyup', this.onKeyUp);
170
+ this.enabled = false;
171
+ },
172
+ checkModuleShortcutCollision: function (keyCode, moduleName, mustBeActive) {
173
+ if (
174
+ this.shortcuts.modules[moduleName] &&
175
+ this.shortcuts.modules[moduleName][keyCode]
176
+ ) {
177
+ console.warn(
178
+ 'Keycode <%s> already registered as shortcut within the same module',
179
+ keyCode
180
+ );
181
+ }
182
+ },
183
+ registerModuleShortcut: function (
184
+ keyCode,
185
+ callback,
186
+ moduleName,
187
+ mustBeActive
188
+ ) {
189
+ if (this.checkModuleShortcutCollision(keyCode, moduleName, mustBeActive)) {
190
+ return;
191
+ }
192
+
193
+ if (!this.shortcuts.modules[moduleName]) {
194
+ this.shortcuts.modules[moduleName] = {};
195
+ }
196
+
197
+ if (mustBeActive !== false) {
198
+ mustBeActive = true;
199
+ }
200
+
201
+ this.shortcuts.modules[moduleName][keyCode] = {
202
+ callback,
203
+ mustBeActive
204
+ };
205
+ },
206
+ init: function (inspector) {
207
+ this.inspector = inspector;
208
+ this.onKeyDown = this.onKeyDown.bind(this);
209
+ this.onKeyUp = this.onKeyUp.bind(this);
210
+ }
211
+ };
@@ -0,0 +1,118 @@
1
+ export function getNumber(value) {
2
+ return parseFloat(value.toFixed(3));
3
+ }
4
+
5
+ export function getMajorVersion(version) {
6
+ var major = version.split('.');
7
+ var clean = false;
8
+ for (var i = 0; i < major.length; i++) {
9
+ if (clean) {
10
+ major[i] = 0;
11
+ } else if (major[i] !== '0') {
12
+ clean = true;
13
+ }
14
+ }
15
+ return major.join('.');
16
+ }
17
+
18
+ export function equal(var1, var2) {
19
+ var keys1;
20
+ var keys2;
21
+ var type1 = typeof var1;
22
+ var type2 = typeof var2;
23
+ if (type1 !== type2) {
24
+ return false;
25
+ }
26
+ if (type1 !== 'object' || var1 === null || var2 === null) {
27
+ return var1 === var2;
28
+ }
29
+ keys1 = Object.keys(var1);
30
+ keys2 = Object.keys(var2);
31
+ if (keys1.length !== keys2.length) {
32
+ return false;
33
+ }
34
+ for (var i = 0; i < keys1.length; i++) {
35
+ if (!equal(var1[keys1[i]], var2[keys2[i]])) {
36
+ return false;
37
+ }
38
+ }
39
+ return true;
40
+ }
41
+
42
+ export function getOS() {
43
+ var userAgent = window.navigator.userAgent;
44
+ var platform = window.navigator.platform;
45
+ var macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];
46
+ var windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];
47
+ var iosPlatforms = ['iPhone', 'iPad', 'iPod'];
48
+ var os = null;
49
+
50
+ if (macosPlatforms.indexOf(platform) !== -1) {
51
+ os = 'macos';
52
+ } else if (iosPlatforms.indexOf(platform) !== -1) {
53
+ os = 'ios';
54
+ } else if (windowsPlatforms.indexOf(platform) !== -1) {
55
+ os = 'windows';
56
+ } else if (/Android/.test(userAgent)) {
57
+ os = 'android';
58
+ } else if (!os && /Linux/.test(platform)) {
59
+ os = 'linux';
60
+ }
61
+
62
+ return os;
63
+ }
64
+
65
+ export function injectCSS(url) {
66
+ var link = document.createElement('link');
67
+ link.href = url;
68
+ link.type = 'text/css';
69
+ link.rel = 'stylesheet';
70
+ link.media = 'screen,print';
71
+ link.setAttribute('data-aframe-inspector', 'style');
72
+ document.head.appendChild(link);
73
+ }
74
+
75
+ export function injectJS(url, onLoad, onError) {
76
+ var link = document.createElement('script');
77
+ link.src = url;
78
+ link.charset = 'utf-8';
79
+ link.setAttribute('data-aframe-inspector', 'style');
80
+
81
+ if (onLoad) {
82
+ link.addEventListener('load', onLoad);
83
+ }
84
+
85
+ if (onError) {
86
+ link.addEventListener('error', onError);
87
+ }
88
+
89
+ document.head.appendChild(link);
90
+ }
91
+
92
+ export function saveString(text, filename, mimeType) {
93
+ saveBlob(new Blob([text], { type: mimeType }), filename);
94
+ }
95
+
96
+ export function saveBlob(blob, filename) {
97
+ var link = document.createElement('a');
98
+ link.style.display = 'none';
99
+ document.body.appendChild(link);
100
+ const url = URL.createObjectURL(blob);
101
+ link.href = url;
102
+ link.download = filename || 'ascene.html';
103
+ link.click();
104
+ URL.revokeObjectURL(url);
105
+ link.remove();
106
+ }
107
+
108
+ // Compares 2 vector objects up to size 4
109
+ // Expect v1 and v2 to take format {x: number, y: number, z: number, w:number}
110
+ // Smaller vectors (ie. vec2) should work as well since their z & w vals will be the same (undefined)
111
+ export function areVectorsEqual(v1, v2) {
112
+ return (
113
+ Object.is(v1.x, v2.x) &&
114
+ Object.is(v1.y, v2.y) &&
115
+ Object.is(v1.z, v2.z) &&
116
+ Object.is(v1.w, v2.w)
117
+ );
118
+ }
@@ -0,0 +1,268 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import TransformControls from './TransformControls.js';
3
+ import EditorControls from './EditorControls.js';
4
+
5
+ import { initRaycaster } from './raycaster';
6
+ import Events from './Events';
7
+
8
+ /**
9
+ * Transform controls stuff mostly.
10
+ */
11
+ export function Viewport(inspector) {
12
+ // Initialize raycaster and picking in differentpmodule.
13
+ const mouseCursor = initRaycaster(inspector);
14
+ const sceneEl = inspector.sceneEl;
15
+
16
+ sceneEl.addEventListener('camera-set-active', (event) => {
17
+ // If we're in edit mode, save the newly active camera and activate when exiting.
18
+ if (inspector.opened) {
19
+ inspector.cameras.original = event.detail.cameraEl;
20
+ }
21
+ });
22
+
23
+ // Helpers.
24
+ const sceneHelpers = inspector.sceneHelpers;
25
+ const grid = new THREE.GridHelper(30, 60, 0xaaaaaa, 0x262626);
26
+ sceneHelpers.add(grid);
27
+
28
+ const selectionBox = new THREE.BoxHelper();
29
+ selectionBox.material.depthTest = false;
30
+ selectionBox.material.transparent = true;
31
+ selectionBox.material.color.set(0x1faaf2);
32
+ selectionBox.visible = false;
33
+ sceneHelpers.add(selectionBox);
34
+
35
+ function updateHelpers(object) {
36
+ object.traverse((node) => {
37
+ if (inspector.helpers[node.uuid] && inspector.helpers[node.uuid].update) {
38
+ inspector.helpers[node.uuid].update();
39
+ }
40
+ });
41
+ }
42
+
43
+ const camera = inspector.camera;
44
+ const transformControls = new THREE.TransformControls(
45
+ camera,
46
+ inspector.container
47
+ );
48
+ transformControls.size = 0.75;
49
+ transformControls.addEventListener('objectChange', (evt) => {
50
+ const object = transformControls.object;
51
+ if (object === undefined) {
52
+ return;
53
+ }
54
+
55
+ selectionBox.setFromObject(object);
56
+
57
+ updateHelpers(object);
58
+
59
+ // Emit update event for watcher.
60
+ let component;
61
+ let value;
62
+ if (evt.mode === 'translate') {
63
+ component = 'position';
64
+ value = `${object.position.x} ${object.position.y} ${object.position.z}`;
65
+ } else if (evt.mode === 'rotate') {
66
+ component = 'rotation';
67
+ const d = THREE.MathUtils.radToDeg;
68
+ value = `${d(object.rotation.x)} ${d(object.rotation.y)} ${d(
69
+ object.rotation.z
70
+ )}`;
71
+ } else if (evt.mode === 'scale') {
72
+ component = 'scale';
73
+ value = `${object.scale.x} ${object.scale.y} ${object.scale.z}`;
74
+ }
75
+
76
+ // We need to call setAttribute for component attrValue to be up to date,
77
+ // so that entity.flushToDOM() works correctly when duplicating an entity.
78
+ transformControls.object.el.setAttribute(component, value);
79
+
80
+ Events.emit('entityupdate', {
81
+ component: component,
82
+ entity: transformControls.object.el,
83
+ property: '',
84
+ value: value
85
+ });
86
+ });
87
+
88
+ transformControls.addEventListener('mouseDown', () => {
89
+ controls.enabled = false;
90
+ });
91
+
92
+ transformControls.addEventListener('mouseUp', () => {
93
+ controls.enabled = true;
94
+ });
95
+
96
+ sceneHelpers.add(transformControls);
97
+
98
+ Events.on('entityupdate', (detail) => {
99
+ const object = detail.entity.object3D;
100
+ if (
101
+ inspector.selected === object &&
102
+ inspector.selectedEntity.object3DMap.mesh
103
+ ) {
104
+ selectionBox.setFromObject(inspector.selected);
105
+ }
106
+ });
107
+
108
+ // Controls need to be added *after* main logic.
109
+ const controls = new THREE.EditorControls(camera, inspector.container);
110
+ controls.center.set(0, 1.6, 0);
111
+ controls.rotationSpeed = 0.0035;
112
+ controls.zoomSpeed = 0.05;
113
+ controls.setAspectRatio(sceneEl.canvas.width / sceneEl.canvas.height);
114
+ controls.addEventListener('change', () => {
115
+ transformControls.update(true); // true is updateScale
116
+ Events.emit('camerachanged');
117
+ });
118
+
119
+ Events.on('cameratoggle', (data) => {
120
+ controls.setCamera(data.camera);
121
+ transformControls.setCamera(data.camera);
122
+ updateAspectRatio();
123
+ });
124
+
125
+ function disableControls() {
126
+ mouseCursor.disable();
127
+ transformControls.dispose();
128
+ controls.enabled = false;
129
+ }
130
+
131
+ function enableControls() {
132
+ mouseCursor.enable();
133
+ transformControls.activate();
134
+ controls.enabled = true;
135
+ }
136
+ enableControls();
137
+
138
+ Events.on('inspectorcleared', () => {
139
+ controls.center.set(0, 0, 0);
140
+ });
141
+
142
+ Events.on('transformmodechange', (mode) => {
143
+ transformControls.setMode(mode);
144
+ });
145
+
146
+ Events.on('translationsnapchanged', (dist) => {
147
+ transformControls.setTranslationSnap(dist);
148
+ });
149
+
150
+ Events.on('rotationsnapchanged', (dist) => {
151
+ transformControls.setRotationSnap(dist);
152
+ });
153
+
154
+ Events.on('transformspacechanged', (space) => {
155
+ transformControls.setSpace(space);
156
+ });
157
+
158
+ Events.on('objectselect', (object) => {
159
+ selectionBox.visible = false;
160
+ transformControls.detach();
161
+ if (object && object.el) {
162
+ if (object.el.getObject3D('mesh')) {
163
+ selectionBox.setFromObject(object);
164
+ selectionBox.visible = true;
165
+ } else if (object.el.hasAttribute('gltf-model')) {
166
+ const listener = (event) => {
167
+ if (event.target !== object.el) return; // we got an event for a child, ignore
168
+ selectionBox.setFromObject(object);
169
+ selectionBox.visible = true;
170
+ object.el.removeEventListener('model-loaded', listener);
171
+ };
172
+ object.el.addEventListener('model-loaded', listener);
173
+ }
174
+
175
+ transformControls.attach(object);
176
+ }
177
+ });
178
+
179
+ Events.on('objectfocus', (object) => {
180
+ controls.focus(object);
181
+ });
182
+
183
+ Events.on('geometrychanged', (object) => {
184
+ if (object !== null) {
185
+ selectionBox.setFromObject(object);
186
+ }
187
+ });
188
+
189
+ Events.on('entityupdate', (detail) => {
190
+ const object = detail.entity.object3D;
191
+ if (inspector.selected === object) {
192
+ // Hack because object3D always has geometry :(
193
+ if (
194
+ object.geometry &&
195
+ ((object.geometry.vertices && object.geometry.vertices.length > 0) ||
196
+ (object.geometry.attributes &&
197
+ object.geometry.attributes.position &&
198
+ object.geometry.attributes.position.array.length))
199
+ ) {
200
+ selectionBox.setFromObject(object);
201
+ }
202
+ }
203
+
204
+ transformControls.update();
205
+ if (object instanceof THREE.PerspectiveCamera) {
206
+ object.updateProjectionMatrix();
207
+ }
208
+
209
+ updateHelpers(object);
210
+ });
211
+
212
+ function updateAspectRatio() {
213
+ if (!inspector.opened) return;
214
+ // Modifying aspect for perspective camera is done by aframe a-scene.resize function
215
+ // when the perspective camera is the active camera, so we actually do it a second time here,
216
+ // but we need to modify it ourself when we switch from ortho camera to perspective camera (updateAspectRatio() is called in cameratoggle handler).
217
+ const camera = inspector.camera;
218
+ const aspect =
219
+ inspector.container.offsetWidth / inspector.container.offsetHeight;
220
+ if (camera.isPerspectiveCamera) {
221
+ camera.aspect = aspect;
222
+ } else if (camera.isOrthographicCamera) {
223
+ const frustumSize = camera.top - camera.bottom;
224
+ camera.left = (-frustumSize * aspect) / 2;
225
+ camera.right = (frustumSize * aspect) / 2;
226
+ camera.top = frustumSize / 2;
227
+ camera.bottom = -frustumSize / 2;
228
+ }
229
+
230
+ controls.setAspectRatio(aspect); // for zoom in/out to work correctly for orthographic camera
231
+ camera.updateProjectionMatrix();
232
+
233
+ const cameraHelper = inspector.helpers[camera.uuid];
234
+ if (cameraHelper) cameraHelper.update();
235
+ }
236
+
237
+ inspector.sceneEl.addEventListener('rendererresize', updateAspectRatio);
238
+
239
+ Events.on('gridvisibilitychanged', (showGrid) => {
240
+ grid.visible = showGrid;
241
+ });
242
+
243
+ Events.on('togglegrid', () => {
244
+ grid.visible = !grid.visible;
245
+ });
246
+
247
+ Events.on('inspectortoggle', (active) => {
248
+ if (active) {
249
+ enableControls();
250
+ AFRAME.scenes[0].camera = inspector.camera;
251
+ Array.prototype.slice
252
+ .call(document.querySelectorAll('.a-enter-vr,.rs-base'))
253
+ .forEach((element) => {
254
+ element.style.display = 'none';
255
+ });
256
+ } else {
257
+ disableControls();
258
+ inspector.cameras.original.setAttribute('camera', 'active', 'true');
259
+ AFRAME.scenes[0].camera =
260
+ inspector.cameras.original.getObject3D('camera');
261
+ Array.prototype.slice
262
+ .call(document.querySelectorAll('.a-enter-vr,.rs-base'))
263
+ .forEach((element) => {
264
+ element.style.display = 'block';
265
+ });
266
+ }
267
+ });
268
+ }