onSinglePanMove method
void
onSinglePanMove(
- dynamic event,
- dynamic opState
Implementation
void onSinglePanMove(event, opState) {
if (enabled) {
final restart = opState != _state;
setCenter(event.clientX, event.clientY);
switch (opState) {
case State2.pan:
if (enablePan) {
if (restart) {
//switch to pan operation
dispatchEvent(_endEvent);
dispatchEvent(_startEvent);
updateTbState(opState, true);
_startCursorPosition.setFrom(unprojectOnTbPlane(camera, _center.x, _center.y));
if (enableGrid) {
drawGrid();
}
activateGizmos(false);
} else {
//continue with pan operation
_currentCursorPosition.setFrom(unprojectOnTbPlane(camera, _center.x, _center.y));
applyTransformMatrix(pan(_startCursorPosition, _currentCursorPosition));
}
}
break;
case State2.rotate:
if (enableRotate) {
if (restart) {
//switch to rotate operation
dispatchEvent(_endEvent);
dispatchEvent(_startEvent);
updateTbState(opState, true);
_startCursorPosition.setFrom(
unprojectOnTbSurface(
camera,
_center.x,
_center.y,
_tbRadius
)
);
if (enableGrid) {
disposeGrid();
}
activateGizmos(true);
} else {
//continue with rotate operation
_currentCursorPosition.setFrom(
unprojectOnTbSurface(
camera,
_center.x,
_center.y,
_tbRadius
)
);
final distance = _startCursorPosition.distanceTo(_currentCursorPosition);
final angle = _startCursorPosition.angleTo(_currentCursorPosition);
final amount = math.max(
distance / _tbRadius, angle); //effective rotation angle
applyTransformMatrix(rotate(
calculateRotationAxis(
_startCursorPosition, _currentCursorPosition),
amount));
if (enableAnimations) {
_timePrev = _timeCurrent;
_timeCurrent = DateTime.now().millisecondsSinceEpoch;
_anglePrev = _angleCurrent;
_angleCurrent = amount;
_cursorPosPrev.setFrom(_cursorPosCurr);
_cursorPosCurr.setFrom(_currentCursorPosition);
_wPrev = _wCurr;
_wCurr = calculateAngularSpeed(
_anglePrev,
_angleCurrent,
_timePrev,
_timeCurrent
);
}
}
}
break;
case State2.scale:
if (enableZoom) {
if (restart) {
//switch to zoom operation
dispatchEvent(_endEvent);
dispatchEvent(_startEvent);
updateTbState(opState, true);
_startCursorPosition.setY(
getCursorNDC(_center.x, _center.y).y *
0.5);
_currentCursorPosition.setFrom(_startCursorPosition);
if (enableGrid) {
disposeGrid();
}
activateGizmos(false);
} else {
//continue with zoom operation
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
_currentCursorPosition.setY(
getCursorNDC(_center.x, _center.y).y *
0.5);
final movement =
_currentCursorPosition.y - _startCursorPosition.y;
double size = 1;
if (movement < 0) {
size =
1 / (math.pow(scaleFactor, -movement * screenNotches));
} else if (movement > 0) {
size = math.pow(scaleFactor, movement * screenNotches).toDouble();
}
applyTransformMatrix(
scale(size, _gizmos.position));
}
}
break;
case State2.fov:
if (enableZoom && camera is PerspectiveCamera) {
if (restart) {
//switch to fov operation
dispatchEvent(_endEvent);
dispatchEvent(_startEvent);
updateTbState(opState, true);
_startCursorPosition.setY(
getCursorNDC(_center.x, _center.y).y *
0.5);
_currentCursorPosition.setFrom(_startCursorPosition);
if (enableGrid) {
disposeGrid();
}
activateGizmos(false);
} else {
//continue with fov operation
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
_currentCursorPosition.setY(
getCursorNDC(_center.x, _center.y).y *
0.5);
final movement =
_currentCursorPosition.y - _startCursorPosition.y;
double size = 1;
if (movement < 0) {
size =
1 / (math.pow(scaleFactor, -movement * screenNotches));
} else if (movement > 0) {
size = math.pow(scaleFactor, movement * screenNotches).toDouble();
}
_v3_1.setFromMatrixPosition(_cameraMatrixState);
final x = _v3_1.distanceTo(_gizmos.position);
double xNew = x /size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
//check min and max distance
xNew = MathUtils.clamp(xNew, minDistance, maxDistance);
final y = x * math.tan(MathUtils.deg2rad * _fovState * 0.5);
//calculate fov
double newFov = MathUtils.rad2deg * (math.atan(y / xNew) * 2);
//check min and max fov
newFov = MathUtils.clamp(newFov, minFov, maxFov);
final newDistance = y / math.tan(MathUtils.deg2rad * (newFov / 2));
size = x / newDistance;
_v3_2.setFromMatrixPosition(_gizmoMatrixState);
setFov(newFov);
applyTransformMatrix(scale(size, _v3_2, false));
//adjusting distance
_offset
.setFrom(_gizmos.position)
.sub(camera.position)
.normalize()
.scale(newDistance / x);
_m4_1.makeTranslation(_offset.x, _offset.y, _offset.z);
}
}
break;
}
dispatchEvent(_changeEvent);
}
}