transformMatrix property

Matrix4 get transformMatrix

The total transformation matrix for the component. This matrix combines translation, rotation, reflection and scale transforms into a single entity. The matrix is cached and gets recalculated only as necessary.

The returned matrix must not be modified by the user.

Implementation

Matrix4 get transformMatrix {
  if (_recalculate) {
    // The transforms below are equivalent to:
    //   _transformMatrix = Matrix4.identity()
    //       .. translate(_position.x, _position.y)
    //       .. rotateZ(_angle)
    //       .. scale(_scale.x, _scale.y, 1)
    //       .. translate(_offset.x, _offset.y);
    if (_recalculateRotation) {
      _cosAngle = math.cos(_angle);
      _sinAngle = math.sin(_angle);
      _recalculateRotation = false;
    }
    final cosAngle = _cosAngle;
    final sinAngle = _sinAngle;
    final scaleX = _scale.x;
    final scaleY = _scale.y;
    final offsetX = _offset.x;
    final offsetY = _offset.y;
    final storage = _transformMatrix.storage;
    storage[0] = cosAngle * scaleX;
    storage[1] = sinAngle * scaleX;
    storage[4] = -sinAngle * scaleY;
    storage[5] = cosAngle * scaleY;
    storage[12] = _position.x + storage[0] * offsetX + storage[4] * offsetY;
    storage[13] = _position.y + storage[1] * offsetX + storage[5] * offsetY;
    _recalculate = false;
  }
  return _transformMatrix;
}
set transformMatrix (Matrix4 value)

Implementation

set transformMatrix(Matrix4 value) {
  assert(
    value.storage[2] == 0 &&
        value.storage[3] == 0 &&
        value.storage[6] == 0 &&
        value.storage[7] == 0 &&
        value.storage[8] == 0 &&
        value.storage[9] == 0 &&
        value.storage[10] == 1 &&
        value.storage[11] == 0 &&
        value.storage[14] == 0 &&
        value.storage[15] == 1,
    'The provided matrix is not a valid 2D transformation',
  );
  final storage = _transformMatrix.storage;
  storage.setAll(0, value.storage);

  final xAxisX = storage[0];
  final xAxisY = storage[1];
  final yAxisX = storage[4];
  final yAxisY = storage[5];
  final double scaleX;
  final double scaleY;
  final double angle;
  final scaleXSquared = xAxisX * xAxisX + xAxisY * xAxisY;
  if (scaleXSquared == 0) {
    scaleX = 0;
    scaleY = math.sqrt(yAxisX * yAxisX + yAxisY * yAxisY);
    angle = math.atan2(-yAxisX, yAxisY);
  } else {
    scaleX = math.sqrt(scaleXSquared);
    scaleY = (xAxisX * yAxisY - xAxisY * yAxisX) / scaleX;
    angle = math.atan2(xAxisY, xAxisX);
  }
  final offsetX = _offset.x;
  final offsetY = _offset.y;

  _isBatchUpdating = true;
  _angle = angle;
  _recalculateRotation = true;
  _scale.setValues(scaleX, scaleY);
  _position.setValues(
    storage[12] - (xAxisX * offsetX + yAxisX * offsetY),
    storage[13] - (xAxisY * offsetX + yAxisY * offsetY),
  );
  _isBatchUpdating = false;
  _recalculate = false;
  notifyListeners();
}