onSinglePanMove method

void onSinglePanMove(
  1. dynamic event,
  2. 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);
  }
}