なぜホイールを改造するのですか?私はちょうどTrackballControls.jsコードを再利用して、あなたが望むようにそれを変更します。カメラを回転させるためにマウスを押してドラッグしたくない場合は、イベントハンドリングの動作を変更し、デフォルトで回転モードを有効にしますこれ - 汚い - codepen。
/**
* @author Eberhard Graether/http://egraether.com/
* @author Mark Lundin/http://mark-lundin.com
* @author Simone Manini/http://daron1337.github.io
* @author Luca Antiga/http://lantiga.github.io
*/
THREE.MyTrackballControls = function (object, domElement) {
var _this = this;
var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
this.object = object;
this.domElement = (domElement !== undefined) ? domElement : document;
// API
this.enabled = true;
this.screen = { left: 0, top: 0, width: 0, height: 0 };
this.rotateSpeed = 1.0;
this.zoomSpeed = 1.2;
this.panSpeed = 0.3;
this.noRotate = false;
this.noZoom = false;
this.noPan = false;
this.staticMoving = false;
this.dynamicDampingFactor = 0.2;
this.minDistance = 0;
this.maxDistance = Infinity;
this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
// internals
this.target = new THREE.Vector3();
var EPS = 0.000001;
var lastPosition = new THREE.Vector3();
var _state = STATE.ROTATE,
_prevState = STATE.NONE,
_eye = new THREE.Vector3(),
_movePrev = new THREE.Vector2(),
_moveCurr = new THREE.Vector2(),
_lastAxis = new THREE.Vector3(),
_lastAngle = 0,
_zoomStart = new THREE.Vector2(),
_zoomEnd = new THREE.Vector2(),
_touchZoomDistanceStart = 0,
_touchZoomDistanceEnd = 0,
_panStart = new THREE.Vector2(),
_panEnd = new THREE.Vector2();
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
this.up0 = this.object.up.clone();
// events
var changeEvent = { type: 'change' };
var startEvent = { type: 'start' };
var endEvent = { type: 'end' };
// methods
this.handleResize = function() {
if (this.domElement === document) {
this.screen.left = 0;
this.screen.top = 0;
this.screen.width = window.innerWidth;
this.screen.height = window.innerHeight;
} else {
var box = this.domElement.getBoundingClientRect();
// adjustments come from similar code in the jquery offset() function
var d = this.domElement.ownerDocument.documentElement;
this.screen.left = box.left + window.pageXOffset - d.clientLeft;
this.screen.top = box.top + window.pageYOffset - d.clientTop;
this.screen.width = box.width;
this.screen.height = box.height;
}
};
this.handleEvent = function (event) {
if (typeof this[ event.type ] == 'function') {
this[ event.type ](event);
}
};
var getMouseOnScreen = (function() {
var vector = new THREE.Vector2();
return function getMouseOnScreen(pageX, pageY) {
vector.set(
(pageX - _this.screen.left)/_this.screen.width,
(pageY - _this.screen.top)/_this.screen.height
);
return vector;
};
}());
var getMouseOnCircle = (function() {
var vector = new THREE.Vector2();
return function getMouseOnCircle(pageX, pageY) {
vector.set(
((pageX - _this.screen.width * 0.5 - _this.screen.left)/(_this.screen.width * 0.5)),
((_this.screen.height + 2 * (_this.screen.top - pageY))/_this.screen.width) // screen.width intentional
);
return vector;
};
}());
this.rotateCamera = (function() {
var axis = new THREE.Vector3(),
quaternion = new THREE.Quaternion(),
eyeDirection = new THREE.Vector3(),
objectUpDirection = new THREE.Vector3(),
objectSidewaysDirection = new THREE.Vector3(),
moveDirection = new THREE.Vector3(),
angle;
return function rotateCamera() {
moveDirection.set(_moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0);
angle = moveDirection.length();
if (angle) {
_eye.copy(_this.object.position).sub(_this.target);
eyeDirection.copy(_eye).normalize();
objectUpDirection.copy(_this.object.up).normalize();
objectSidewaysDirection.crossVectors(objectUpDirection, eyeDirection).normalize();
objectUpDirection.setLength(_moveCurr.y - _movePrev.y);
objectSidewaysDirection.setLength(_moveCurr.x - _movePrev.x);
moveDirection.copy(objectUpDirection.add(objectSidewaysDirection));
axis.crossVectors(moveDirection, _eye).normalize();
angle *= _this.rotateSpeed;
quaternion.setFromAxisAngle(axis, angle);
_eye.applyQuaternion(quaternion);
_this.object.up.applyQuaternion(quaternion);
_lastAxis.copy(axis);
_lastAngle = angle;
} else if (! _this.staticMoving && _lastAngle) {
_lastAngle *= Math.sqrt(1.0 - _this.dynamicDampingFactor);
_eye.copy(_this.object.position).sub(_this.target);
quaternion.setFromAxisAngle(_lastAxis, _lastAngle);
_eye.applyQuaternion(quaternion);
_this.object.up.applyQuaternion(quaternion);
}
_movePrev.copy(_moveCurr);
};
}());
this.zoomCamera = function() {
var factor;
if (_state === STATE.TOUCH_ZOOM_PAN) {
factor = _touchZoomDistanceStart/_touchZoomDistanceEnd;
_touchZoomDistanceStart = _touchZoomDistanceEnd;
_eye.multiplyScalar(factor);
} else {
factor = 1.0 + (_zoomEnd.y - _zoomStart.y) * _this.zoomSpeed;
if (factor !== 1.0 && factor > 0.0) {
_eye.multiplyScalar(factor);
}
if (_this.staticMoving) {
_zoomStart.copy(_zoomEnd);
} else {
_zoomStart.y += (_zoomEnd.y - _zoomStart.y) * this.dynamicDampingFactor;
}
}
};
this.panCamera = (function() {
var mouseChange = new THREE.Vector2(),
objectUp = new THREE.Vector3(),
pan = new THREE.Vector3();
return function panCamera() {
mouseChange.copy(_panEnd).sub(_panStart);
if (mouseChange.lengthSq()) {
mouseChange.multiplyScalar(_eye.length() * _this.panSpeed);
pan.copy(_eye).cross(_this.object.up).setLength(mouseChange.x);
pan.add(objectUp.copy(_this.object.up).setLength(mouseChange.y));
_this.object.position.add(pan);
_this.target.add(pan);
if (_this.staticMoving) {
_panStart.copy(_panEnd);
} else {
_panStart.add(mouseChange.subVectors(_panEnd, _panStart).multiplyScalar(_this.dynamicDampingFactor));
}
}
};
}());
this.checkDistances = function() {
if (! _this.noZoom || ! _this.noPan) {
if (_eye.lengthSq() > _this.maxDistance * _this.maxDistance) {
_this.object.position.addVectors(_this.target, _eye.setLength(_this.maxDistance));
_zoomStart.copy(_zoomEnd);
}
if (_eye.lengthSq() < _this.minDistance * _this.minDistance) {
_this.object.position.addVectors(_this.target, _eye.setLength(_this.minDistance));
_zoomStart.copy(_zoomEnd);
}
}
};
this.update = function() {
_eye.subVectors(_this.object.position, _this.target);
if (! _this.noRotate) {
_this.rotateCamera();
}
if (! _this.noZoom) {
_this.zoomCamera();
}
if (! _this.noPan) {
_this.panCamera();
}
_this.object.position.addVectors(_this.target, _eye);
_this.checkDistances();
_this.object.lookAt(_this.target);
if (lastPosition.distanceToSquared(_this.object.position) > EPS) {
_this.dispatchEvent(changeEvent);
lastPosition.copy(_this.object.position);
}
};
this.reset = function() {
_state = STATE.NONE;
_prevState = STATE.NONE;
_this.target.copy(_this.target0);
_this.object.position.copy(_this.position0);
_this.object.up.copy(_this.up0);
_eye.subVectors(_this.object.position, _this.target);
_this.object.lookAt(_this.target);
_this.dispatchEvent(changeEvent);
lastPosition.copy(_this.object.position);
};
// listeners
function keydown(event) {
if (_this.enabled === false) return;
window.removeEventListener('keydown', keydown);
_prevState = _state;
if (_state !== STATE.NONE) {
return;
} else if (event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate) {
_state = STATE.ROTATE;
} else if (event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom) {
_state = STATE.ZOOM;
} else if (event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan) {
_state = STATE.PAN;
}
}
function keyup(event) {
if (_this.enabled === false) return;
_state = _prevState;
window.addEventListener('keydown', keydown, false);
}
function mousedown(event) {
if (_this.enabled === false) return;
event.preventDefault();
event.stopPropagation();
if (_state === STATE.NONE) {
_state = event.button;
}
if (_state === STATE.ROTATE && ! _this.noRotate) {
_moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
_movePrev.copy(_moveCurr);
} else if (_state === STATE.ZOOM && ! _this.noZoom) {
_zoomStart.copy(getMouseOnScreen(event.pageX, event.pageY));
_zoomEnd.copy(_zoomStart);
} else if (_state === STATE.PAN && ! _this.noPan) {
_panStart.copy(getMouseOnScreen(event.pageX, event.pageY));
_panEnd.copy(_panStart);
}
//added by default
//document.addEventListener('mousemove', mousemove, false);
//document.addEventListener('mouseup', mouseup, false);
_this.dispatchEvent(startEvent);
}
function mousemove(event) {
if (_this.enabled === false) return;
event.preventDefault();
event.stopPropagation();
if (_state === STATE.ROTATE && ! _this.noRotate) {
_movePrev.copy(_moveCurr);
_moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
} else if (_state === STATE.ZOOM && ! _this.noZoom) {
_zoomEnd.copy(getMouseOnScreen(event.pageX, event.pageY));
} else if (_state === STATE.PAN && ! _this.noPan) {
_panEnd.copy(getMouseOnScreen(event.pageX, event.pageY));
}
}
function mouseup(event) {
if (_this.enabled === false) return;
event.preventDefault();
event.stopPropagation();
//_state = STATE.NONE;
//document.removeEventListener('mousemove', mousemove);
//document.removeEventListener('mouseup', mouseup);
_this.dispatchEvent(endEvent);
}
function mousewheel(event) {
if (_this.enabled === false) return;
event.preventDefault();
event.stopPropagation();
switch (event.deltaMode) {
case 2:
// Zoom in pages
_zoomStart.y -= event.deltaY * 0.025;
break;
case 1:
// Zoom in lines
_zoomStart.y -= event.deltaY * 0.01;
break;
default:
// undefined, 0, assume pixels
_zoomStart.y -= event.deltaY * 0.00025;
break;
}
_this.dispatchEvent(startEvent);
_this.dispatchEvent(endEvent);
}
function touchstart(event) {
if (_this.enabled === false) return;
switch (event.touches.length) {
case 1:
_state = STATE.TOUCH_ROTATE;
_moveCurr.copy(getMouseOnCircle(event.touches[ 0 ].pageX, event.touches[ 0 ].pageY));
_movePrev.copy(_moveCurr);
break;
default: // 2 or more
_state = STATE.TOUCH_ZOOM_PAN;
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy);
var x = (event.touches[ 0 ].pageX + event.touches[ 1 ].pageX)/2;
var y = (event.touches[ 0 ].pageY + event.touches[ 1 ].pageY)/2;
_panStart.copy(getMouseOnScreen(x, y));
_panEnd.copy(_panStart);
break;
}
_this.dispatchEvent(startEvent);
}
function touchmove(event) {
if (_this.enabled === false) return;
event.preventDefault();
event.stopPropagation();
switch (event.touches.length) {
case 1:
_movePrev.copy(_moveCurr);
_moveCurr.copy(getMouseOnCircle(event.touches[ 0 ].pageX, event.touches[ 0 ].pageY));
break;
default: // 2 or more
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
_touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy);
var x = (event.touches[ 0 ].pageX + event.touches[ 1 ].pageX)/2;
var y = (event.touches[ 0 ].pageY + event.touches[ 1 ].pageY)/2;
_panEnd.copy(getMouseOnScreen(x, y));
break;
}
}
function touchend(event) {
if (_this.enabled === false) return;
switch (event.touches.length) {
case 0:
_state = STATE.NONE;
break;
case 1:
_state = STATE.TOUCH_ROTATE;
_moveCurr.copy(getMouseOnCircle(event.touches[ 0 ].pageX, event.touches[ 0 ].pageY));
_movePrev.copy(_moveCurr);
break;
}
_this.dispatchEvent(endEvent);
}
function contextmenu(event) {
if (_this.enabled === false) return;
event.preventDefault();
}
this.dispose = function() {
this.domElement.removeEventListener('contextmenu', contextmenu, false);
this.domElement.removeEventListener('mousedown', mousedown, false);
this.domElement.removeEventListener('wheel', mousewheel, false);
this.domElement.removeEventListener('touchstart', touchstart, false);
this.domElement.removeEventListener('touchend', touchend, false);
this.domElement.removeEventListener('touchmove', touchmove, false);
document.removeEventListener('mousemove', mousemove, false);
document.removeEventListener('mouseup', mouseup, false);
window.removeEventListener('keydown', keydown, false);
window.removeEventListener('keyup', keyup, false);
};
this.domElement.addEventListener('contextmenu', contextmenu, false);
this.domElement.addEventListener('mousedown', mousedown, false);
this.domElement.addEventListener('wheel', mousewheel, false);
this.domElement.addEventListener('touchstart', touchstart, false);
this.domElement.addEventListener('touchend', touchend, false);
this.domElement.addEventListener('touchmove', touchmove, false);
window.addEventListener('keydown', keydown, false);
window.addEventListener('keyup', keyup, false);
this.handleResize();
// force an update at start
this.update();
document.addEventListener('mousemove', mousemove, false);
document.addEventListener('mouseup', mouseup, false);
};
THREE.MyTrackballControls.prototype = Object.create(THREE.EventDispatcher.prototype);
THREE.MyTrackballControls.prototype.constructor = THREE.MyTrackballControls;
if (! Detector.webgl) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 1, 1000);
camera.position.z = 500;
controls = new THREE.MyTrackballControls(camera);
controls.rotateSpeed = 2.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noPan = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render);
// world
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
var geometry = new THREE.CylinderGeometry(0, 10, 100, 16, 1);
var material = new THREE.MeshPhongMaterial({ color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading });
for (var i = 0; i < 200; i ++) {
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) * 500;
mesh.position.y = (Math.random() - 0.5) * 500;
mesh.position.z = (Math.random() - 0.5) * 500;
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
scene.add(mesh);
}
// lights
light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
light = new THREE.DirectionalLight(0x002288);
light.position.set(-1, -1, -1);
scene.add(light);
light = new THREE.AmbientLight(0x222222);
scene.add(light);
renderer = new THREE.WebGLRenderer({ antialias: false });
renderer.setClearColor(scene.fog.color);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.getElementById('container');
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild(stats.domElement);
//
window.addEventListener('resize', onWindowResize, false);
//
render();
}
function onWindowResize() {
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame(animate);
controls.update();
}
function render() {
renderer.render(scene, camera);
stats.update();
}
私はこのコードを試してみましたが、私は「でプロパティを読み取ることができません 『更新』:THREE.MyTrackballControls.render THREE.MyTrackballControls.dispatchEvent THREE.MyTrackballControls.update」と言うエラーメッセージを取得しておく作業ライブ例を –
私が作成したcodepenリンクには、これ以上はありません:https://codepen.io/leefsmp/pen/zEvaBK –