From f902e79cfdb9cee2f3f8e692a0714a8cf3f66aec Mon Sep 17 00:00:00 2001 From: tengge1 <930372551@qq.com> Date: Thu, 9 Jan 2020 22:08:33 +0800 Subject: [PATCH] ControlsManager --- ShadowEditor.Web/src/controls/BaseControls.js | 2 +- .../src/controls/ControlsManager.js | 47 ++- .../src/controls/EditorControls.js | 6 +- ShadowEditor.Web/src/controls/FreeControls.js | 312 +----------------- 4 files changed, 57 insertions(+), 310 deletions(-) diff --git a/ShadowEditor.Web/src/controls/BaseControls.js b/ShadowEditor.Web/src/controls/BaseControls.js index 6dfa8ed8..a97d1fa2 100644 --- a/ShadowEditor.Web/src/controls/BaseControls.js +++ b/ShadowEditor.Web/src/controls/BaseControls.js @@ -36,7 +36,7 @@ class BaseControls extends THREE.EventDispatcher { * @param {THREE.Object3D} target 目标 */ focus(target) { - scope.dispatchEvent(changeEvent); + } /** diff --git a/ShadowEditor.Web/src/controls/ControlsManager.js b/ShadowEditor.Web/src/controls/ControlsManager.js index b4947795..954fa479 100644 --- a/ShadowEditor.Web/src/controls/ControlsManager.js +++ b/ShadowEditor.Web/src/controls/ControlsManager.js @@ -1,7 +1,52 @@ import BaseControls from './BaseControls'; -class ControlsManager extends BaseControls { +import EditorControls from './EditorControls'; +import FreeControls from './FreeControls'; +const Controls = { + EditorControls, + FreeControls +}; + +/** + * 控制器管理器 + */ +class ControlsManager extends BaseControls { + constructor(camera, domElement) { + super(camera, domElement); + + this.current = new EditorControls(); + } + + /** + * 改变控制器模式 + * @param {String} modeName 模式 + */ + changeMode(modeName) { + if (!Controls[modeName]) { + console.warn(`ControlsManager: ${modeName} is not defined.`); + return; + } + this.current.disable(); + this.current = Controls[modeName]; + this.current.enable(); + } + + enable() { + this.current && this.current.enabled(); + } + + disable() { + this.current && this.current.disable(); + } + + focus(target) { + this.current && this.current.focus(target); + } + + dispose() { + this.current && this.current.disable(); + } } export default ControlsManager; \ No newline at end of file diff --git a/ShadowEditor.Web/src/controls/EditorControls.js b/ShadowEditor.Web/src/controls/EditorControls.js index f062ac9d..9bd234c9 100644 --- a/ShadowEditor.Web/src/controls/EditorControls.js +++ b/ShadowEditor.Web/src/controls/EditorControls.js @@ -1,3 +1,5 @@ +import BaseControls from './BaseControls'; + /** * @author qiao / https://github.com/qiao * @author mrdoob / http://mrdoob.com @@ -312,7 +314,7 @@ function EditorControls(object, domElement) { } -EditorControls.prototype = Object.create(THREE.EventDispatcher.prototype); -EditorControls.prototype.constructor = EditorControls; +EditorControls.prototype = Object.create(BaseControls.prototype); +EditorControls.prototype.constructor = BaseControls; export default EditorControls; \ No newline at end of file diff --git a/ShadowEditor.Web/src/controls/FreeControls.js b/ShadowEditor.Web/src/controls/FreeControls.js index db0720fa..bea66443 100644 --- a/ShadowEditor.Web/src/controls/FreeControls.js +++ b/ShadowEditor.Web/src/controls/FreeControls.js @@ -1,310 +1,10 @@ -function FreeControls(object, domElement) { +import BaseControls from './BaseControls'; - domElement = domElement !== undefined ? domElement : document; - - // API - - this.enabled = true; - this.center = new THREE.Vector3(); - this.panSpeed = 0.002; - this.zoomSpeed = 0.1; - this.rotationSpeed = 0.005; - - // internals - - var scope = this; - var vector = new THREE.Vector3(); - var delta = new THREE.Vector3(); - var box = new THREE.Box3(); - - var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2 }; - var state = STATE.NONE; - - var center = this.center; - var normalMatrix = new THREE.Matrix3(); - var pointer = new THREE.Vector2(); - var pointerOld = new THREE.Vector2(); - var spherical = new THREE.Spherical(); - var sphere = new THREE.Sphere(); - - // events - - var changeEvent = { type: 'change' }; - - this.focus = function (target) { - - var distance; - - box.setFromObject(target); - - if (box.isEmpty() === false) { - - box.getCenter(center); - distance = box.getBoundingSphere(sphere).radius; - - } else { - - // Focusing on an Group, AmbientLight, etc - - center.setFromMatrixPosition(target.matrixWorld); - distance = 0.1; - - } - - delta.set(0, 0, 1); - delta.applyQuaternion(object.quaternion); - delta.multiplyScalar(distance * 4); - - object.position.copy(center).add(delta); - - scope.dispatchEvent(changeEvent); - - }; - - this.pan = function (delta) { - - var distance = object.position.distanceTo(center); - - delta.multiplyScalar(distance * scope.panSpeed); - delta.applyMatrix3(normalMatrix.getNormalMatrix(object.matrix)); - - object.position.add(delta); - center.add(delta); - - scope.dispatchEvent(changeEvent); - - }; - - this.zoom = function (delta) { - - var distance = object.position.distanceTo(center); - - delta.multiplyScalar(distance * scope.zoomSpeed); - - if (delta.length() > distance) return; - - delta.applyMatrix3(normalMatrix.getNormalMatrix(object.matrix)); - - object.position.add(delta); - - scope.dispatchEvent(changeEvent); - - }; - - this.rotate = function (delta) { - - vector.copy(object.position).sub(center); - - spherical.setFromVector3(vector); - - spherical.theta += delta.x * scope.rotationSpeed; - spherical.phi += delta.y * scope.rotationSpeed; - - spherical.makeSafe(); - - vector.setFromSpherical(spherical); - - object.position.copy(center).add(vector); - - object.lookAt(center); - - scope.dispatchEvent(changeEvent); - - }; - - // mouse - - function onMouseDown(event) { - - if (scope.enabled === false) return; - - if (event.button === 0) { - - state = STATE.ROTATE; - - } else if (event.button === 1) { - - state = STATE.ZOOM; - - } else if (event.button === 2) { - - state = STATE.PAN; - - } - - pointerOld.set(event.clientX, event.clientY); - - domElement.addEventListener('mousemove', onMouseMove, false); - domElement.addEventListener('mouseup', onMouseUp, false); - domElement.addEventListener('mouseout', onMouseUp, false); - domElement.addEventListener('dblclick', onMouseUp, false); - - } - - function onMouseMove(event) { - - if (scope.enabled === false) return; - - pointer.set(event.clientX, event.clientY); - - var movementX = pointer.x - pointerOld.x; - var movementY = pointer.y - pointerOld.y; - - if (state === STATE.ROTATE) { - - scope.rotate(delta.set(- movementX, - movementY, 0)); - - } else if (state === STATE.ZOOM) { - - scope.zoom(delta.set(0, 0, movementY)); - - } else if (state === STATE.PAN) { - - scope.pan(delta.set(- movementX, movementY, 0)); - - } - - pointerOld.set(event.clientX, event.clientY); - - } - - function onMouseUp(event) { - - domElement.removeEventListener('mousemove', onMouseMove, false); - domElement.removeEventListener('mouseup', onMouseUp, false); - domElement.removeEventListener('mouseout', onMouseUp, false); - domElement.removeEventListener('dblclick', onMouseUp, false); - - state = STATE.NONE; - - } - - function onMouseWheel(event) { - - event.preventDefault(); - - // Normalize deltaY due to https://bugzilla.mozilla.org/show_bug.cgi?id=1392460 - scope.zoom(delta.set(0, 0, event.deltaY > 0 ? 1 : - 1)); - - } - - function contextmenu(event) { - - event.preventDefault(); - - } - - this.dispose = function () { - - domElement.removeEventListener('contextmenu', contextmenu, false); - domElement.removeEventListener('mousedown', onMouseDown, false); - domElement.removeEventListener('wheel', onMouseWheel, false); - - domElement.removeEventListener('mousemove', onMouseMove, false); - domElement.removeEventListener('mouseup', onMouseUp, false); - domElement.removeEventListener('mouseout', onMouseUp, false); - domElement.removeEventListener('dblclick', onMouseUp, false); - - domElement.removeEventListener('touchstart', touchStart, false); - domElement.removeEventListener('touchmove', touchMove, false); - - }; - - domElement.addEventListener('contextmenu', contextmenu, false); - domElement.addEventListener('mousedown', onMouseDown, false); - domElement.addEventListener('wheel', onMouseWheel, false); - - // touch - - var touches = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()]; - var prevTouches = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()]; - - var prevDistance = null; - - function touchStart(event) { - - if (scope.enabled === false) return; - - switch (event.touches.length) { - - case 1: - touches[0].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - touches[1].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - break; - - case 2: - touches[0].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - touches[1].set(event.touches[1].pageX, event.touches[1].pageY, 0).divideScalar(window.devicePixelRatio); - prevDistance = touches[0].distanceTo(touches[1]); - break; - - } - - prevTouches[0].copy(touches[0]); - prevTouches[1].copy(touches[1]); - - } - - - function touchMove(event) { - - if (scope.enabled === false) return; - - event.preventDefault(); - event.stopPropagation(); - - function getClosest(touch, touches) { - - var closest = touches[0]; - - for (var i in touches) { - - if (closest.distanceTo(touch) > touches[i].distanceTo(touch)) closest = touches[i]; - - } - - return closest; - - } - - switch (event.touches.length) { - - case 1: - touches[0].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - touches[1].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - scope.rotate(touches[0].sub(getClosest(touches[0], prevTouches)).multiplyScalar(- 1)); - break; - - case 2: - touches[0].set(event.touches[0].pageX, event.touches[0].pageY, 0).divideScalar(window.devicePixelRatio); - touches[1].set(event.touches[1].pageX, event.touches[1].pageY, 0).divideScalar(window.devicePixelRatio); - var distance = touches[0].distanceTo(touches[1]); - scope.zoom(delta.set(0, 0, prevDistance - distance)); - prevDistance = distance; - - - var offset0 = touches[0].clone().sub(getClosest(touches[0], prevTouches)); - var offset1 = touches[1].clone().sub(getClosest(touches[1], prevTouches)); - offset0.x = - offset0.x; - offset1.x = - offset1.x; - - scope.pan(offset0.add(offset1)); - - break; - - } - - prevTouches[0].copy(touches[0]); - prevTouches[1].copy(touches[1]); - - } - - domElement.addEventListener('touchstart', touchStart, false); - domElement.addEventListener('touchmove', touchMove, false); +/** + * 自由控制器 + */ +class FreeControls extends BaseControls { } -EditorControls.prototype = Object.create(THREE.EventDispatcher.prototype); -EditorControls.prototype.constructor = EditorControls; - -export default EditorControls; \ No newline at end of file +export default FreeControls; \ No newline at end of file