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();
}