Files
lottie-flutter/lib/src/parser/animatable_transform_parser.dart

182 lines
5.8 KiB
Dart

import 'dart:ui';
import '../composition.dart';
import '../model/animatable/animatable_double_value.dart';
import '../model/animatable/animatable_integer_value.dart';
import '../model/animatable/animatable_path_value.dart';
import '../model/animatable/animatable_scale_value.dart';
import '../model/animatable/animatable_split_dimension_path_value.dart';
import '../model/animatable/animatable_transform.dart';
import '../model/animatable/animatable_value.dart';
import '../value/keyframe.dart';
import 'animatable_path_value_parser.dart';
import 'animatable_value_parser.dart';
import 'moshi/json_reader.dart';
class AnimatableTransformParser {
AnimatableTransformParser._();
static final JsonReaderOptions _names = JsonReaderOptions.of(
['a', 'p', 's', 'rz', 'r', 'o', 'so', 'eo', 'sk', 'sa']);
static final JsonReaderOptions _animatableNames = JsonReaderOptions.of(['k']);
static AnimatableTransform parse(
JsonReader reader, LottieComposition composition) {
AnimatablePathValue? anchorPoint;
AnimatableValue<Offset, Offset>? position;
AnimatableScaleValue? scale;
AnimatableDoubleValue? rotation;
AnimatableIntegerValue? opacity;
AnimatableDoubleValue? startOpacity;
AnimatableDoubleValue? endOpacity;
AnimatableDoubleValue? skew;
AnimatableDoubleValue? skewAngle;
var isObject = reader.peek() == Token.beginObject;
if (isObject) {
reader.beginObject();
}
while (reader.hasNext()) {
var name = reader.selectName(_names);
switch (name) {
case 0:
reader.beginObject();
while (reader.hasNext()) {
switch (reader.selectName(_animatableNames)) {
case 0:
anchorPoint =
AnimatablePathValueParser.parse(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
case 1:
position =
AnimatablePathValueParser.parseSplitPath(reader, composition);
break;
case 2:
scale = AnimatableValueParser.parseScale(reader, composition);
break;
case 3:
case 4:
if (name == 3) {
composition.addWarning("Lottie doesn't support 3D layers.");
}
// Sometimes split path rotation gets exported like:
// "rz": {
// "a": 1,
// "k": [
// {}
// ]
// },
// which doesn't parse to a real keyframe.
rotation = AnimatableValueParser.parseFloat(reader, composition);
if (rotation.keyframes.isEmpty) {
rotation.keyframes.add(Keyframe(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: 0.0,
endFrame: composition.endFrame));
} else if (rotation.keyframes.first.startValue == null) {
rotation.keyframes.first = Keyframe(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: 0.0,
endFrame: composition.endFrame);
}
break;
case 5:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 6:
startOpacity = AnimatableValueParser.parseFloat(reader, composition);
break;
case 7:
endOpacity = AnimatableValueParser.parseFloat(reader, composition);
break;
case 8:
skew = AnimatableValueParser.parseFloat(reader, composition);
break;
case 9:
skewAngle = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
}
}
if (isObject) {
reader.endObject();
}
if (isAnchorPointIdentity(anchorPoint)) {
anchorPoint = null;
}
if (isPositionIdentity(position)) {
position = null;
}
if (isRotationIdentity(rotation)) {
rotation = null;
}
if (isScaleIdentity(scale)) {
scale = null;
}
if (isSkewIdentity(skew)) {
skew = null;
}
if (isSkewAngleIdentity(skewAngle)) {
skewAngle = null;
}
return AnimatableTransform(
anchorPoint: anchorPoint,
position: position,
scale: scale,
rotation: rotation,
opacity: opacity,
startOpacity: startOpacity,
endOpacity: endOpacity,
skew: skew,
skewAngle: skewAngle);
}
static bool isAnchorPointIdentity(AnimatablePathValue? anchorPoint) {
return anchorPoint == null ||
(anchorPoint.isStatic &&
anchorPoint.keyframes.first.startValue == Offset.zero);
}
static bool isPositionIdentity(AnimatableValue<Offset, Offset>? position) {
return position == null ||
(position is! AnimatableSplitDimensionPathValue &&
position.isStatic &&
position.keyframes.first.startValue == Offset.zero);
}
static bool isRotationIdentity(AnimatableDoubleValue? rotation) {
return rotation == null ||
(rotation.isStatic && rotation.keyframes.first.startValue == 0.0);
}
static bool isScaleIdentity(AnimatableScaleValue? scale) {
return scale == null ||
(scale.isStatic &&
scale.keyframes.first.startValue == const Offset(1.0, 1.0));
}
static bool isSkewIdentity(AnimatableDoubleValue? skew) {
return skew == null ||
(skew.isStatic && skew.keyframes.first.startValue == 0.0);
}
static bool isSkewAngleIdentity(AnimatableDoubleValue? skewAngle) {
return skewAngle == null ||
(skewAngle.isStatic && skewAngle.keyframes.first.startValue == 0.0);
}
}