| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import {TransformControls} from './TransformControls.js'
- import {MathUtils} from 'three'
- import type {ICamera, IObject3D, ISceneEvent, IWidget} from '../../core'
- import {iObjectCommons} from '../../core'
- import {uiDropdown, uiFolderContainer, uiSlider, uiToggle} from 'uiconfig.js'
-
- @uiFolderContainer('Transform Controls')
- export class TransformControls2 extends TransformControls implements IWidget, IObject3D {
- isWidget = true as const
- assetType = 'widget' as const
- setDirty = iObjectCommons.setDirty.bind(this)
- refreshUi = iObjectCommons.refreshUi.bind(this)
-
- object: IObject3D | undefined
- private _keyDownListener(event: KeyboardEvent) {
- if (!this.enabled) return
- if (!this.object) return
-
- switch (event.code) {
-
- case 'KeyQ':
- this.space = this.space === 'local' ? 'world' : 'local'
- break
-
- case 'ShiftLeft':
- this.translationSnap = 0.5
- this.rotationSnap = MathUtils.degToRad(15)
- this.scaleSnap = 0.25
- break
-
- case 'KeyW':
- this.mode = 'translate'
- break
-
- case 'KeyE':
- this.mode = 'rotate'
- break
-
- case 'KeyR':
- this.mode = 'scale'
- break
-
- case 'Equal':
- case 'NumpadAdd':
- case 'Plus':
- this.size = this.size + 0.1
- break
-
- case 'Minus':
- case 'NumpadSubtract':
- case 'Underscore':
- this.size = Math.max(this.size - 0.1, 0.1)
- break
-
- case 'KeyX':
- this.showX = !this.showX
- break
-
- case 'KeyY':
- this.showY = !this.showY
- break
-
- case 'KeyZ':
- this.showZ = !this.showZ
- break
-
- case 'Space':
- this.enabled = !this.enabled
- break
-
- default:
- return
- }
-
- this.setDirty({refreshScene: true, frameFade: true})
-
- }
-
- private _keyUpListener(event: KeyboardEvent) {
- if (!this.enabled) return
-
- // reset events
- switch (event.code) {
- case 'ShiftLeft':
- this.translationSnap = null
- this.rotationSnap = null
- this.scaleSnap = null
- break
-
- default:
- break
- }
-
- if (!this.object) return
-
- // non-reset events
- switch (event.code) {
- default:
- break
- }
-
- }
-
- constructor(camera: ICamera, canvas: HTMLCanvasElement) {
- super(camera, canvas)
-
- this.visible = false
- this.userData.bboxVisible = false
-
- this.size = 2
-
- this.addEventListener('objectChange', () => {
- this?.object?.setDirty({fadeFrame: false})
- // todo: do this.setDirty?
- })
- this.addEventListener('change', () => {
- this.setDirty({fadeFrame: false})
- })
-
- this._keyUpListener = this._keyUpListener.bind(this)
- this._keyDownListener = this._keyDownListener.bind(this)
- window.addEventListener('keydown', this._keyDownListener)
- window.addEventListener('keyup', this._keyUpListener)
- }
-
- dispose() {
- window.removeEventListener('keydown', this._keyDownListener)
- window.removeEventListener('keyup', this._keyUpListener)
- super.dispose()
- }
-
-
- // region properties
-
- enabled: boolean
-
- // axis: 'X' | 'Y' | 'Z' | 'E' | 'XY' | 'YZ' | 'XZ' | 'XYZ' | 'XYZE' | null
-
- // onChange not required for before since they fire 'change' event on changed. see TransformControls.js
-
- @uiDropdown('Mode', ['translate', 'rotate', 'scale'].map(label=>({label})))
- mode: 'translate' | 'rotate' | 'scale'
-
- translationSnap: number | null
- rotationSnap: number | null
- scaleSnap: number | null
-
- @uiDropdown('Space', ['world', 'local'].map(label=>({label})))
- space: 'world' | 'local'
- @uiSlider('Size', [0.1, 10], 0.1)
- size: number
- @uiToggle('Show X')
- showX: boolean
- @uiToggle('Show Y')
- showY: boolean
- @uiToggle('Show Z')
- showZ: boolean
-
- // dragging: boolean
-
- // endregion
-
-
- /**
- * Get the threejs object
- * @deprecated
- */
- get modelObject(): this {
- return this as any
- }
-
- // todo: https://helpx.adobe.com/after-effects/using/3d-transform-gizmo.html
-
- // region inherited type fixes
-
- traverse: (callback: (object: IObject3D) => void) => void
- traverseVisible: (callback: (object: IObject3D) => void) => void
- traverseAncestors: (callback: (object: IObject3D) => void) => void
- getObjectById: <T extends IObject3D = IObject3D>(id: number) => T | undefined
- getObjectByName: <T extends IObject3D = IObject3D>(name: string) => T | undefined
- getObjectByProperty: <T extends IObject3D = IObject3D>(name: string, value: string) => T | undefined
- copy: (source: this, recursive?: boolean, ...args: any[]) => this
- clone: (recursive?: boolean) => this
- remove: (...object: IObject3D[]) => this
- dispatchEvent: (event: ISceneEvent) => void
- parent: IObject3D | null
- children: IObject3D[]
-
- // endregion
- }
|