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);
final m = _transformMatrix.storage;
final cosA = math.cos(_angle);
final sinA = math.sin(_angle);
m[0] = cosA * _scale.x;
m[1] = sinA * _scale.x;
m[4] = -sinA * _scale.y;
m[5] = cosA * _scale.y;
m[12] = _position.x + m[0] * _offset.x + m[4] * _offset.y;
m[13] = _position.y + m[1] * _offset.x + m[5] * _offset.y;
_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',
);
_transformMatrix.setFrom(value);
_recalculate = false;
final storage = _transformMatrix.storage;
_isBatchUpdating = true;
final determinant = storage[0] * storage[5] - storage[1] * storage[4];
_scale.x = math.sqrt(storage[0] * storage[0] + storage[1] * storage[1]);
if (_scale.x == 0) {
_angle = math.atan2(-storage[4], storage[5]);
_scale.y = math.sqrt(storage[4] * storage[4] + storage[5] * storage[5]);
} else {
_angle = math.atan2(storage[1], storage[0]);
_scale.y = determinant / _scale.x;
}
_position.x =
storage[12] - (storage[0] * _offset.x + storage[4] * _offset.y);
_position.y =
storage[13] - (storage[1] * _offset.x + storage[5] * _offset.y);
_isBatchUpdating = false;
notifyListeners();
}