-
-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Problem
I've applied thorvg.flutter to existing usecases which already used lottie package. During this process, I found that the image size was not being rendered correctly.
Cause of Issue
During tests, I found that this issue occurs when ThorVG's Lottie widget with size un-specified is wrapped with a SizedBox that specifies its size. However, when the size is set directly on the Lottie widget itself, the issue does not occur.
// Error Case
SizedBox(
width: 250,
height: 250,
child: ThorVG.Lottie.network(
'https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json',
),
),
// Normal Case
ThorVG.Lottie.network(
width: 250,
height: 250,
'https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json',
),Looking into the ThorVG's Lottie implementation, I found that when neither width nor height is set, they are initialized to 0. As a result, subsequent calculated values such as renderWidth and renderHeight are also 0. This leads TVGCanvas to fall back to using info['w'] and info['h'] from the image metadata.
// ThorVG's Lottie constructor
static Lottie network(String src,
...) {
return Lottie(
width: width ?? 0,
height: height ?? 0,
...
);
}
// ThorVG's canvas size calculation
void _updateLottieSize() {
final info = jsonDecode(data);
setState(() {
lottieWidth = info['w'] ?? widget.width;
lottieHeight = info['h'] ?? widget.height;
});
}
void _updateCanvasSize() {
if (widget.width == 0 || widget.height == 0) {
setState(() {
width = lottieWidth.toDouble();
height = lottieHeight.toDouble();
});
return;
}
setState(() {
width = widget.width;
height = widget.height;
});
}
...In contrast, the Lottie package’s implementation addresses this by overriding methods that take the parent’s constraints, ensuring that an appropriate size is computed even when null size is provided. So Lottie package's widget could adapts correctly to its parent’s constraints.
/// Find a size for the render composition within the given constraints.
///
/// - The dimensions of the RenderLottie must fit within the constraints.
/// - The aspect ratio of the RenderLottie matches the intrinsic aspect
/// ratio of the Lottie animation.
/// - The RenderLottie's dimension are maximal subject to being smaller than
/// the intrinsic size of the composition.
Size _sizeForConstraints(BoxConstraints constraints) {
// Folds the given |width| and |height| into |constraints| so they can all
// be treated uniformly.
constraints = BoxConstraints.tightFor(
width: _width,
height: _height,
).enforce(constraints);
if (_drawable == null) {
return constraints.smallest;
}
return constraints
.constrainSizeAndAttemptToPreserveAspectRatio(_drawable!.size);
}
@override
double computeMinIntrinsicWidth(double height) {
assert(height >= 0.0);
if (_width == null && _height == null) {
return 0.0;
}
return _sizeForConstraints(BoxConstraints.tightForFinite(height: height))
.width;
}
@override
double computeMaxIntrinsicWidth(double height) {
assert(height >= 0.0);
return _sizeForConstraints(BoxConstraints.tightForFinite(height: height))
.width;
}
@override
double computeMinIntrinsicHeight(double width) {
assert(width >= 0.0);
if (_width == null && _height == null) {
return 0.0;
}
return _sizeForConstraints(BoxConstraints.tightForFinite(width: width))
.height;
}
@override
double computeMaxIntrinsicHeight(double width) {
assert(width >= 0.0);
return _sizeForConstraints(BoxConstraints.tightForFinite(width: width))
.height;
}Suggestion
Would it make sense to apply a similar approach for the case where the size is null, so that ThorVG Lottie widgets also adapt to their parent constraints?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status