onSinglePanMove method

dynamic onSinglePanMove(
  1. dynamic event,
  2. dynamic opState
)

Implementation

onSinglePanMove(event, opState) {
  if (enabled) {
    var 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.copy(unprojectOnTbPlane(camera, _center.x, _center.y, domElement));
            if (enableGrid) {
              drawGrid();
            }

            activateGizmos(false);
          } else {
            //continue with pan operation
            _currentCursorPosition.copy(unprojectOnTbPlane(camera, _center.x, _center.y, domElement));
            applyTransformMatrix(pan(_startCursorPosition, _currentCursorPosition));
          }
        }

        break;

      case State2.rotate:
        if (enableRotate) {
          if (restart) {
            //switch to rotate operation

            dispatchEvent(_endEvent);
            dispatchEvent(_startEvent);

            updateTbState(opState, true);
            _startCursorPosition.copy(unprojectOnTbSurface(camera, _center.x, _center.y, listenableKey, _tbRadius));

            if (enableGrid) {
              disposeGrid();
            }

            activateGizmos(true);
          } else {
            //continue with rotate operation
            _currentCursorPosition.copy(unprojectOnTbSurface(camera, _center.x, _center.y, listenableKey, _tbRadius));

            var distance = _startCursorPosition.distanceTo(_currentCursorPosition);
            var angle = _startCursorPosition.angleTo(_currentCursorPosition);
            var 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.copy(_cursorPosCurr);
              _cursorPosCurr.copy(_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, domElement).y * 0.5);
            _currentCursorPosition.copy(_startCursorPosition);

            if (enableGrid) {
              disposeGrid();
            }

            activateGizmos(false);
          } else {
            //continue with zoom operation
            var screenNotches = 8; //how many wheel notches corresponds to a full screen pan
            _currentCursorPosition.setY(getCursorNDC(_center.x, _center.y, domElement).y * 0.5);

            var movement = _currentCursorPosition.y - _startCursorPosition.y;

            num size = 1;

            if (movement < 0) {
              size = 1 / (Math.pow(scaleFactor, -movement * screenNotches));
            } else if (movement > 0) {
              size = Math.pow(scaleFactor, movement * screenNotches);
            }

            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, domElement).y * 0.5);
            _currentCursorPosition.copy(_startCursorPosition);

            if (enableGrid) {
              disposeGrid();
            }

            activateGizmos(false);
          } else {
            //continue with fov operation
            var screenNotches = 8; //how many wheel notches corresponds to a full screen pan
            _currentCursorPosition.setY(getCursorNDC(_center.x, _center.y, domElement).y * 0.5);

            var movement = _currentCursorPosition.y - _startCursorPosition.y;

            num size = 1;

            if (movement < 0) {
              size = 1 / (Math.pow(scaleFactor, -movement * screenNotches));
            } else if (movement > 0) {
              size = Math.pow(scaleFactor, movement * screenNotches);
            }

            _v3_1.setFromMatrixPosition(_cameraMatrixState);
            var x = _v3_1.distanceTo(_gizmos.position);
            var 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);

            var y = x * Math.tan(MathUtils.deg2rad * _fovState * 0.5);

            //calculate new fov
            var newFov = MathUtils.rad2deg * (Math.atan(y / xNew) * 2);

            //check min and max fov
            newFov = MathUtils.clamp(newFov, minFov, maxFov);

            var 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.copy(_gizmos.position).sub(camera.position).normalize().multiplyScalar(newDistance / x);
            _m4_1.makeTranslation(_offset.x, _offset.y, _offset.z);
          }
        }

        break;
    }

    dispatchEvent(_changeEvent);
  }
}