part of dart._engine; // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /// A surface that transforms its children using CSS transform. class PersistedTransform extends PersistedContainerSurface implements ui.TransformEngineLayer { PersistedTransform(PersistedTransform? super.oldLayer, this._matrixStorage); /// The storage representing the transform of this surface. final Float32List _matrixStorage; /// The matrix representing the transform of this surface. Matrix4 get matrix4 => _matrix4 ??= Matrix4.fromFloat32List(_matrixStorage); Matrix4? _matrix4; @override void recomputeTransformAndClip() { transform = parent!.transform!.multiplied(matrix4); projectedClip = null; } /// Cached inverse of transform on this node. Unlike [transform], this /// Matrix only contains local transform (not chain multiplied since root). Matrix4? _localTransformInverse; @override Matrix4? get localTransformInverse { _localTransformInverse ??= Matrix4.tryInvert(matrix4); return _localTransformInverse; } @override DomElement createElement() { final DomElement element = domDocument.createElement('flt-transform'); setElementStyle(element, 'position', 'absolute'); setElementStyle(element, 'transform-origin', '0 0 0'); return element; } @override void apply() { rootElement!.style.transform = float64ListToCssTransform(_matrixStorage); } @override void update(PersistedTransform oldSurface) { super.update(oldSurface); if (identical(oldSurface._matrixStorage, _matrixStorage)) { // The matrix storage is identical, so we can copy the matrices from the // old surface to avoid recomputing them. _matrix4 = oldSurface._matrix4; _localTransformInverse = oldSurface._localTransformInverse; return; } bool matrixChanged = false; for (int i = 0; i < _matrixStorage.length; i++) { if (_matrixStorage[i] != oldSurface._matrixStorage[i]) { matrixChanged = true; break; } } if (matrixChanged) { apply(); } else { // The matrix storage hasn't changed, so we can copy the matrices from the // old surface to avoid recomputing them. _matrix4 = oldSurface._matrix4; _localTransformInverse = oldSurface._localTransformInverse; } } }