public static LottieComposition Parse(JsonReader reader) { var scale = Utils.Utils.DpScale(); float startFrame = 0f; float endFrame = 0f; float frameRate = 0f; Dictionary <long, Layer> layerMap = new Dictionary <long, Layer>(); List <Layer> layers = new List <Layer>(); int width = 0; int height = 0; Dictionary <string, List <Layer> > precomps = new Dictionary <string, List <Layer> >(); Dictionary <string, LottieImageAsset> images = new Dictionary <string, LottieImageAsset>(); Dictionary <string, Font> fonts = new Dictionary <string, Font>(); Dictionary <int, FontCharacter> characters = new Dictionary <int, FontCharacter>(); var composition = new LottieComposition(); reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "w": width = reader.NextInt(); break; case "h": height = reader.NextInt(); break; case "ip": startFrame = reader.NextDouble(); break; case "op": endFrame = reader.NextDouble() - 0.01f; break; case "fr": frameRate = reader.NextDouble(); break; case "v": var version = reader.NextString(); var versions = Regex.Split(version, "\\."); var majorVersion = int.Parse(versions[0]); var minorVersion = int.Parse(versions[1]); var patchVersion = int.Parse(versions[2]); if (!Utils.Utils.IsAtLeastVersion(majorVersion, minorVersion, patchVersion, 4, 4, 0)) { composition.AddWarning("Lottie only supports bodymovin >= 4.4.0"); } break; case "layers": ParseLayers(reader, composition, layers, layerMap); break; case "assets": ParseAssets(reader, composition, precomps, images); break; case "fonts": ParseFonts(reader, fonts); break; case "chars": ParseChars(reader, composition, characters); break; default: reader.SkipValue(); break; } } reader.EndObject(); int scaledWidth = (int)(width * scale); int scaledHeight = (int)(height * scale); SKRect bounds = new SKRect(0, 0, scaledWidth, scaledHeight); composition.Init(bounds, startFrame, endFrame, frameRate, layers, layerMap, precomps, images, characters, fonts); return(composition); }
public static AnimatableTransform Parse(JsonReader reader, LottieComposition composition) { AnimatablePathValue anchorPoint = null; IAnimatableValue <Vector?, Vector?> position = null; AnimatableScaleValue scale = null; AnimatableFloatValue rotation = null; AnimatableIntegerValue opacity = null; AnimatableFloatValue startOpacity = null; AnimatableFloatValue endOpacity = null; var isObject = reader.Peek() == JsonToken.StartObject; if (isObject) { reader.BeginObject(); } while (reader.HasNext()) { switch (reader.NextName()) { case "a": reader.BeginObject(); while (reader.HasNext()) { if (reader.NextName().Equals("k")) { anchorPoint = AnimatablePathValueParser.Parse(reader, composition); } else { reader.SkipValue(); } } reader.EndObject(); break; case "p": position = AnimatablePathValueParser.ParseSplitPath(reader, composition); break; case "s": scale = AnimatableValueParser.ParseScale(reader, composition); break; case "rz": composition.AddWarning("Lottie doesn't support 3D layers."); rotation = AnimatableValueParser.ParseFloat(reader, composition); break; case "r": rotation = AnimatableValueParser.ParseFloat(reader, composition); if (rotation.Keyframes.Count == 0) { rotation.Keyframes.Add(new Keyframe <float?>(composition, 0f, 0f, null, 0f, composition.EndFrame)); } else if (rotation.Keyframes[0].StartValue == null) { rotation.Keyframes[0] = new Keyframe <float?>(composition, 0f, 0f, null, 0f, composition.EndFrame); } break; case "o": opacity = AnimatableValueParser.ParseInteger(reader, composition); break; case "so": startOpacity = AnimatableValueParser.ParseFloat(reader, composition); break; case "eo": endOpacity = AnimatableValueParser.ParseFloat(reader, composition); break; default: reader.SkipValue(); break; } } if (isObject) { reader.EndObject(); } if (anchorPoint == null) { // Cameras don't have an anchor point property. Although we don't support them, at least // we won't crash. Debug.WriteLine( "Layer has no transform property. You may be using an unsupported layer type such as a camera.", LottieLog.Tag); anchorPoint = new AnimatablePathValue(); } if (scale == null) { // Somehow some community animations don't have scale in the transform. scale = new AnimatableScaleValue(new ScaleXy(1f, 1f)); } if (opacity == null) { // Repeaters have start/end opacity instead of opacity opacity = new AnimatableIntegerValue(); } return(new AnimatableTransform( anchorPoint, position, scale, rotation, opacity, startOpacity, endOpacity)); }
//private static readonly int SaveFlags = BitmapCanvas.ClipSaveFlag | BitmapCanvas.ClipToLayerSaveFlag | BitmapCanvas.MatrixSaveFlag; internal static BaseLayer ForModel(Layer layerModel, ILottieDrawable drawable, LottieComposition composition) { switch (layerModel.GetLayerType()) { case Layer.LayerType.Shape: return(new ShapeLayer(drawable, layerModel)); case Layer.LayerType.PreComp: return(new CompositionLayer(drawable, layerModel, composition.GetPrecomps(layerModel.RefId), composition)); case Layer.LayerType.Solid: return(new SolidLayer(drawable, layerModel)); case Layer.LayerType.Image: return(new ImageLayer(drawable, layerModel)); case Layer.LayerType.Null: return(new NullLayer(drawable, layerModel)); case Layer.LayerType.Text: return(new TextLayer(drawable, layerModel)); case Layer.LayerType.Unknown: default: // Do nothing LottieLog.Warn("Unknown layer type " + layerModel.GetLayerType()); return(null); } }
public PathKeyframe(LottieComposition composition, Keyframe <Vector2?> keyframe) : base(composition, keyframe.StartValue, keyframe.EndValue, keyframe.Interpolator, keyframe.StartFrame, keyframe.EndFrame) { _pointKeyFrame = keyframe; CreatePath(); }
public void Put(int rawRes, LottieComposition composition) { Put(rawRes.ToString(), composition); }
public static AnimatableFloatValue ParseFloat(JsonReader reader, LottieComposition composition) { return(ParseFloat(reader, composition, true)); }
internal static ShapePath NewInstance(JsonObject json, LottieComposition composition) { var animatableShapeValue = AnimatableShapeValue.Factory.NewInstance(json.GetNamedObject("ks"), composition); return(new ShapePath(json.GetNamedString("nm"), (int)json.GetNamedNumber("ind"), animatableShapeValue)); }
internal CompositionLayer(LottieDrawable lottieDrawable, Layer layerModel, List <Layer> layerModels, LottieComposition composition) : base(lottieDrawable, layerModel) { var timeRemapping = layerModel.TimeRemapping; if (timeRemapping != null) { _timeRemapping = timeRemapping.CreateAnimation(); AddAnimation(_timeRemapping); _timeRemapping.ValueChanged += OnValueChanged; } else { _timeRemapping = null; } var layerMap = new Dictionary <long, BaseLayer>(composition.Layers.Count); BaseLayer mattedLayer = null; for (var i = layerModels.Count - 1; i >= 0; i--) { var lm = layerModels[i]; var layer = ForModel(lm, lottieDrawable, composition); if (layer == null) { continue; } layerMap[layer.LayerModel.Id] = layer; if (mattedLayer != null) { mattedLayer.MatteLayer = layer; mattedLayer = null; } else { _layers.Insert(0, layer); switch (lm.GetMatteType()) { case Layer.MatteType.Add: case Layer.MatteType.Invert: mattedLayer = layer; break; } } } foreach (var layer in layerMap) { var layerView = layer.Value; // This shouldn't happen but it appears as if sometimes on pre-lollipop devices when // compiled with d8, layerView is null sometimes. // https://github.com/airbnb/lottie-android/issues/524 if (layerView == null) { continue; } if (layerMap.TryGetValue(layerView.LayerModel.ParentId, out BaseLayer parentLayer)) { layerView.ParentLayer = parentLayer; } } }
internal static IContentModel Parse(JsonReader reader, LottieComposition composition) { string type = null; reader.BeginObject(); // Unfortunately, for an ellipse, d is before "ty" which means that it will get parsed // before we are in the ellipse parser. // "d" is 2 for normal and 3 for reversed. int d = 2; while (reader.HasNext()) { switch (reader.NextName()) { case "ty": type = reader.NextString(); goto typeLoop; case "d": d = reader.NextInt(); break; default: reader.SkipValue(); break; } } typeLoop: if (type == null) { return(null); } IContentModel model = null; switch (type) { case "gr": model = ShapeGroupParser.Parse(reader, composition); break; case "st": model = ShapeStrokeParser.Parse(reader, composition); break; case "gs": model = GradientStrokeParser.Parse(reader, composition); break; case "fl": model = ShapeFillParser.Parse(reader, composition); break; case "gf": model = GradientFillParser.Parse(reader, composition); break; case "tr": model = AnimatableTransformParser.Parse(reader, composition); break; case "sh": model = ShapePathParser.Parse(reader, composition); break; case "el": model = CircleShapeParser.Parse(reader, composition, d); break; case "rc": model = RectangleShapeParser.Parse(reader, composition); break; case "tm": model = ShapeTrimPathParser.Parse(reader, composition); break; case "sr": model = PolystarShapeParser.Parse(reader, composition); break; case "mm": model = MergePathsParser.Parse(reader); composition.AddWarning("Animation contains merge paths. Merge paths must be manually enabled by calling EnableMergePaths()."); break; case "rp": model = RepeaterParser.Parse(reader, composition); break; default: Debug.WriteLine("Unknown shape type " + type, LottieLog.Tag); break; } while (reader.HasNext()) { reader.SkipValue(); } reader.EndObject(); return(model); }
// Creates a string that describes the Lottie. public Stats(LottieComposition lottieComposition) { if (lottieComposition == null) { return; } Name = lottieComposition.Name; Version = lottieComposition.Version; Width = lottieComposition.Width; Height = lottieComposition.Height; Duration = lottieComposition.Duration; // Get the layers stored in assets. var layersInAssets = from asset in lottieComposition.Assets where asset.Type == Asset.AssetType.LayerCollection let layerCollection = (LayerCollectionAsset)asset from layer in layerCollection.Layers.GetLayersBottomToTop() select layer; foreach (var layer in lottieComposition.Layers.GetLayersBottomToTop().Concat(layersInAssets)) { switch (layer.Type) { case Layer.LayerType.PreComp: PreCompLayerCount++; break; case Layer.LayerType.Solid: SolidLayerCount++; break; case Layer.LayerType.Image: ImageLayerCount++; break; case Layer.LayerType.Null: NullLayerCount++; break; case Layer.LayerType.Shape: ShapeLayerCount++; VisitShapeLayer((ShapeLayer)layer); break; case Layer.LayerType.Text: TextLayerCount++; break; default: throw new InvalidOperationException(); } foreach (var mask in layer.Masks) { MaskCount++; switch (mask.Mode) { case Mask.MaskMode.Add: MaskAddCount++; break; case Mask.MaskMode.Darken: MaskDarkenCount++; break; case Mask.MaskMode.Difference: MaskDifferenceCount++; break; case Mask.MaskMode.Intersect: MaskIntersectCount++; break; case Mask.MaskMode.Lighten: MaskLightenCount++; break; case Mask.MaskMode.Subtract: MaskSubtractCount++; break; } } MaskCount += layer.Masks.Length; } }
internal static IAnimatableValue <Vector2?, Vector2?> CreateAnimatablePathOrSplitDimensionPath(JsonObject json, LottieComposition composition) { if (json.ContainsKey("k")) { return(new AnimatablePathValue(json["k"], composition)); } return(new AnimatableSplitDimensionPathValue(AnimatableFloatValue.Factory.NewInstance(json.GetNamedObject("x"), composition), AnimatableFloatValue.Factory.NewInstance(json.GetNamedObject("y"), composition))); }
/// <summary> /// Returns either an <see cref="AnimatablePathValue"/> or an <see cref="AnimatableSplitDimensionPathValue"/>. /// </summary> /// <param name="reader"></param> /// <param name="composition"></param> /// <returns></returns> internal static IAnimatableValue <Vector2?, Vector2?> ParseSplitPath(JsonReader reader, LottieComposition composition) { AnimatablePathValue pathAnimation = null; AnimatableFloatValue xAnimation = null; AnimatableFloatValue yAnimation = null; bool hasExpressions = false; reader.BeginObject(); while (reader.Peek() != JsonToken.EndObject) { switch (reader.NextName()) { case "k": pathAnimation = Parse(reader, composition); break; case "x": if (reader.Peek() == JsonToken.String) { hasExpressions = true; reader.SkipValue(); } else { xAnimation = AnimatableValueParser.ParseFloat(reader, composition); } break; case "y": if (reader.Peek() == JsonToken.String) { hasExpressions = true; reader.SkipValue(); } else { yAnimation = AnimatableValueParser.ParseFloat(reader, composition); } break; default: reader.SkipValue(); break; } } reader.EndObject(); if (hasExpressions) { composition.AddWarning("Lottie doesn't support expressions."); } if (pathAnimation != null) { return(pathAnimation); } return(new AnimatableSplitDimensionPathValue(xAnimation, yAnimation)); }
internal static AnimatableIntegerValue ParseInteger(JsonReader reader, LottieComposition composition) { return(new AnimatableIntegerValue(Parse(reader, composition, IntegerParser.Instance))); }
internal static PolystarShape Parse(JsonReader reader, LottieComposition composition) { string name = null; PolystarShape.Type type = PolystarShape.Type.Polygon; AnimatableFloatValue points = null; IAnimatableValue <Vector2?, Vector2?> position = null; AnimatableFloatValue rotation = null; AnimatableFloatValue outerRadius = null; AnimatableFloatValue outerRoundedness = null; AnimatableFloatValue innerRadius = null; AnimatableFloatValue innerRoundedness = null; bool hidden = false; while (reader.HasNext()) { switch (reader.NextName()) { case "nm": name = reader.NextString(); break; case "sy": type = (PolystarShape.Type)reader.NextInt(); break; case "pt": points = AnimatableValueParser.ParseFloat(reader, composition, false); break; case "p": position = AnimatablePathValueParser.ParseSplitPath(reader, composition); break; case "r": rotation = AnimatableValueParser.ParseFloat(reader, composition, false); break; case "or": outerRadius = AnimatableValueParser.ParseFloat(reader, composition); break; case "os": outerRoundedness = AnimatableValueParser.ParseFloat(reader, composition, false); break; case "ir": innerRadius = AnimatableValueParser.ParseFloat(reader, composition); break; case "is": innerRoundedness = AnimatableValueParser.ParseFloat(reader, composition, false); break; case "hd": hidden = reader.NextBoolean(); break; default: reader.SkipValue(); break; } } return(new PolystarShape(name, type, points, position, rotation, innerRadius, outerRadius, innerRoundedness, outerRoundedness, hidden)); }
internal static AnimatableGradientColorValue ParseGradientColor(JsonReader reader, LottieComposition composition, int points) { return(new(Parse(reader, composition, new GradientColorParser(points)))); }
public static Layer Parse(JsonReader reader, LottieComposition composition) { string layerName = null; Layer.LayerType layerType = Layer.LayerType.Unknown; string refId = null; long layerId = 0; int solidWidth = 0; int solidHeight = 0; Color solidColor; int preCompWidth = 0; int preCompHeight = 0; long parentId = -1; float timeStretch = 1f; float startFrame = 0f; float inFrame = 0f; float outFrame = 0f; string cl = null; Layer.MatteType matteType = Layer.MatteType.None; AnimatableTransform transform = null; AnimatableTextFrame text = null; AnimatableTextProperties textProperties = null; AnimatableFloatValue timeRemapping = null; List <Mask> masks = new List <Mask>(); List <IContentModel> shapes = new List <IContentModel>(); reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "nm": layerName = reader.NextString(); break; case "ind": layerId = reader.NextInt(); break; case "refId": refId = reader.NextString(); break; case "ty": int layerTypeInt = reader.NextInt(); if (layerTypeInt < (int)Layer.LayerType.Unknown) { layerType = (Layer.LayerType)layerTypeInt; } else { layerType = Layer.LayerType.Unknown; } break; case "parent": parentId = reader.NextInt(); break; case "sw": solidWidth = (int)(reader.NextInt() * Utils.Utils.DpScale()); break; case "sh": solidHeight = (int)(reader.NextInt() * Utils.Utils.DpScale()); break; case "sc": solidColor = Utils.Utils.GetSolidColorBrush(reader.NextString()); break; case "ks": transform = AnimatableTransformParser.Parse(reader, composition); break; case "tt": matteType = (Layer.MatteType)reader.NextInt(); break; case "masksProperties": reader.BeginArray(); while (reader.HasNext()) { masks.Add(MaskParser.Parse(reader, composition)); } reader.EndArray(); break; case "shapes": reader.BeginArray(); while (reader.HasNext()) { var shape = ContentModelParser.Parse(reader, composition); if (shape != null) { shapes.Add(shape); } } reader.EndArray(); break; case "t": reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "d": text = AnimatableValueParser.ParseDocumentData(reader, composition); break; case "a": reader.BeginArray(); if (reader.HasNext()) { textProperties = AnimatableTextPropertiesParser.Parse(reader, composition); } while (reader.HasNext()) { reader.SkipValue(); } reader.EndArray(); break; default: reader.SkipValue(); break; } } reader.EndObject(); break; case "ef": reader.BeginArray(); List <string> effectNames = new List <string>(); while (reader.HasNext()) { reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "nm": effectNames.Add(reader.NextString()); break; default: reader.SkipValue(); break; } } reader.EndObject(); } reader.EndArray(); composition.AddWarning("Lottie doesn't support layer effects. If you are using them for " + " fills, strokes, trim paths etc. then try adding them directly as contents " + " in your shape. Found: " + effectNames); break; case "sr": timeStretch = reader.NextDouble(); break; case "st": startFrame = reader.NextDouble(); break; case "w": preCompWidth = (int)(reader.NextInt() * Utils.Utils.DpScale()); break; case "h": preCompHeight = (int)(reader.NextInt() * Utils.Utils.DpScale()); break; case "ip": inFrame = reader.NextDouble(); break; case "op": outFrame = reader.NextDouble(); break; case "tm": timeRemapping = AnimatableValueParser.ParseFloat(reader, composition, false); break; case "cl": cl = reader.NextString(); break; default: reader.SkipValue(); break; } } reader.EndObject(); // Bodymovin pre-scales the in frame and out frame by the time stretch. However, that will // cause the stretch to be double counted since the in out animation gets treated the same // as all other animations and will have stretch applied to it again. inFrame /= timeStretch; outFrame /= timeStretch; List <Keyframe <float?> > inOutKeyframes = new List <Keyframe <float?> >(); // Before the in frame if (inFrame > 0) { Keyframe <float?> preKeyframe = new Keyframe <float?>(composition, 0f, 0f, null, 0f, inFrame); inOutKeyframes.Add(preKeyframe); } // The + 1 is because the animation should be visible on the out frame itself. outFrame = (outFrame > 0 ? outFrame : composition.EndFrame) + 1; Keyframe <float?> visibleKeyframe = new Keyframe <float?>(composition, 1f, 1f, null, inFrame, outFrame); inOutKeyframes.Add(visibleKeyframe); Keyframe <float?> outKeyframe = new Keyframe <float?>(composition, 0f, 0f, null, outFrame, float.MaxValue); inOutKeyframes.Add(outKeyframe); if (layerName.EndsWith(".ai") || "ai".Equals(cl)) { composition.AddWarning("Convert your Illustrator layers to shape layers."); } return(new Layer(shapes, composition, layerName, layerId, layerType, parentId, refId, masks, transform, solidWidth, solidHeight, solidColor, timeStretch, startFrame, preCompWidth, preCompHeight, text, textProperties, inOutKeyframes, matteType, timeRemapping)); }
/// <summary> /// Will return null if the animation can't be played such as if it has expressions. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="reader"></param> /// <param name="scale"></param> /// <param name="composition"></param> /// <param name="valueParser"></param> /// <returns></returns> private static List <Keyframe <T> > Parse <T>(JsonReader reader, float scale, LottieComposition composition, IValueParser <T> valueParser) { return(KeyframesParser.Parse(reader, composition, scale, valueParser)); }
public static AnimatableFloatValue ParseFloat(JsonReader reader, LottieComposition composition, bool isDp) { return(new(Parse(reader, isDp ? Utils.Utils.DpScale() : 1f, composition, FloatParser.Instance))); }
public static Layer Parse(LottieComposition composition) { var bounds = composition.Bounds; return(new Layer(new List <IContentModel>(), composition, "__container", -1, Layer.LayerType.PreComp, -1, null, new List <Mask>(), new AnimatableTransform(), 0, 0, default, 0, 0, (int)bounds.Width,
internal static AnimatablePointValue ParsePoint(JsonReader reader, LottieComposition composition) { return(new(Parse(reader, Utils.Utils.DpScale(), composition, PointFParser.Instance))); }
internal static ShapeStroke Parse(JsonReader reader, LottieComposition composition) { string name = null; AnimatableColorValue color = null; AnimatableFloatValue width = null; AnimatableIntegerValue opacity = null; var capType = ShapeStroke.LineCapType.Unknown; var joinType = ShapeStroke.LineJoinType.Round; AnimatableFloatValue offset = null; var miterLimit = 0d; var lineDashPattern = new List <AnimatableFloatValue>(); while (reader.HasNext()) { switch (reader.NextName()) { case "nm": name = reader.NextString(); break; case "c": color = AnimatableValueParser.ParseColor(reader, composition); break; case "w": width = AnimatableValueParser.ParseFloat(reader, composition); break; case "o": opacity = AnimatableValueParser.ParseInteger(reader, composition); break; case "lc": capType = (ShapeStroke.LineCapType)(reader.NextInt() - 1); break; case "lj": joinType = (ShapeStroke.LineJoinType)(reader.NextInt() - 1); break; case "ml": miterLimit = reader.NextDouble(); break; case "d": reader.BeginArray(); while (reader.HasNext()) { string n = null; AnimatableFloatValue val = null; reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "n": n = reader.NextString(); break; case "v": val = AnimatableValueParser.ParseFloat(reader, composition); break; default: reader.SkipValue(); break; } } reader.EndObject(); switch (n) { case "o": offset = val; break; case "d": case "g": lineDashPattern.Add(val); break; } } reader.EndArray(); if (lineDashPattern.Count == 1) { // If there is only 1 value then it is assumed to be equal parts on and off. lineDashPattern.Add(lineDashPattern[0]); } break; default: reader.SkipValue(); break; } } return(new ShapeStroke(name, offset, lineDashPattern, color, opacity, width, capType, joinType, miterLimit)); }
internal static AnimatableScaleValue ParseScale(JsonReader reader, LottieComposition composition) { return(new(Parse(reader, composition, ScaleXyParser.Instance))); }
internal static GradientStroke Parse(JsonReader reader, LottieComposition composition) { string name = null; AnimatableGradientColorValue color = null; AnimatableIntegerValue opacity = null; GradientType gradientType = GradientType.Linear; AnimatablePointValue startPoint = null; AnimatablePointValue endPoint = null; AnimatableFloatValue width = null; ShapeStroke.LineCapType capType = ShapeStroke.LineCapType.Unknown; ShapeStroke.LineJoinType joinType = ShapeStroke.LineJoinType.Round; AnimatableFloatValue offset = null; float miterLimit = 0f; List <AnimatableFloatValue> lineDashPattern = new List <AnimatableFloatValue>(); bool hidden = false; while (reader.HasNext()) { switch (reader.NextName()) { case "nm": name = reader.NextString(); break; case "g": int points = -1; reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "p": points = reader.NextInt(); break; case "k": color = AnimatableValueParser.ParseGradientColor(reader, composition, points); break; default: reader.SkipValue(); break; } } reader.EndObject(); break; case "o": opacity = AnimatableValueParser.ParseInteger(reader, composition); break; case "t": gradientType = reader.NextInt() == 1 ? GradientType.Linear : GradientType.Radial; break; case "s": startPoint = AnimatableValueParser.ParsePoint(reader, composition); break; case "e": endPoint = AnimatableValueParser.ParsePoint(reader, composition); break; case "w": width = AnimatableValueParser.ParseFloat(reader, composition); break; case "lc": capType = (ShapeStroke.LineCapType)(reader.NextInt() - 1); break; case "lj": joinType = (ShapeStroke.LineJoinType)(reader.NextInt() - 1); break; case "ml": miterLimit = reader.NextDouble(); break; case "d": reader.BeginArray(); while (reader.HasNext()) { String n = null; AnimatableFloatValue val = null; reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "n": n = reader.NextString(); break; case "v": val = AnimatableValueParser.ParseFloat(reader, composition); break; default: reader.SkipValue(); break; } } reader.EndObject(); if (n.Equals("o")) { offset = val; } else if (n.Equals("d") || n.Equals("g")) { lineDashPattern.Add(val); } } reader.EndArray(); if (lineDashPattern.Count == 1) { // If there is only 1 value then it is assumed to be equal parts on and off. lineDashPattern.Add(lineDashPattern[0]); } break; case "hd": hidden = reader.NextBoolean(); break; default: reader.SkipValue(); break; } } return(new GradientStroke( name, gradientType, color, opacity, startPoint, endPoint, width, capType, joinType, miterLimit, lineDashPattern, offset, hidden)); }
internal static AnimatableShapeValue ParseShapeData(JsonReader reader, LottieComposition composition) { return(new(Parse(reader, Utils.Utils.DpScale(), composition, ShapeDataParser.Instance))); }
/// <summary> /// Attempts to translate the given <see cref="LottieData.LottieComposition"/> for a range of UAP versions, /// producing one or more translations. /// </summary> /// <param name="lottieComposition">The <see cref="LottieComposition"/> to translate.</param> /// <param name="configuration">Controls optional features of the translator.</param> /// <param name="minimumUapVersion">The lowest version of UAP on which the result must run. /// Must be >= 7 and <= the target UAP version.</param> /// <returns>The results of the translation and the issues.</returns> public static MultiVersionTranslationResult TryTranslateLottieComposition( LottieComposition lottieComposition, in TranslatorConfiguration configuration,
internal static AnimatableTextFrame ParseDocumentData(JsonReader reader, LottieComposition composition) { return(new(Parse(reader, composition, DocumentDataParser.Instance))); }
internal static FontCharacter Parse(JsonReader reader, LottieComposition composition) { char character = '\0'; double size = 0; double width = 0; String style = null; String fontFamily = null; List <ShapeGroup> shapes = new List <ShapeGroup>(); reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "ch": character = reader.NextString()[0]; break; case "size": size = reader.NextDouble(); break; case "w": width = reader.NextDouble(); break; case "style": style = reader.NextString(); break; case "fFamily": fontFamily = reader.NextString(); break; case "data": reader.BeginObject(); while (reader.HasNext()) { if ("shapes".Equals(reader.NextName())) { reader.BeginArray(); while (reader.HasNext()) { shapes.Add((ShapeGroup)ContentModelParser.Parse(reader, composition)); } reader.EndArray(); } else { reader.SkipValue(); } } reader.EndObject(); break; default: reader.SkipValue(); break; } } reader.EndObject(); return(new FontCharacter(shapes, character, size, width, style, fontFamily)); }
internal static AnimatableColorValue ParseColor(JsonReader reader, LottieComposition composition) { return(new(Parse(reader, composition, ColorParser.Instance))); }
public static Layer Parse(LottieComposition composition) { var bounds = composition.Bounds; return(new Layer(new List <IContentModel>(), composition, "__container", -1, Layer.LayerType.PreComp, -1, null, new List <Mask>(), new AnimatableTransform(), 0, 0, default(Color), 0, 0, (int)bounds.Width, (int)bounds.Height, null, null, new List <Keyframe <float?> >(), Layer.MatteType.None, null, false)); }
private static void ParseAssets(JsonReader reader, LottieComposition composition, Dictionary <string, List <Layer> > precomps, Dictionary <string, LottieImageAsset> images) { reader.BeginArray(); while (reader.HasNext()) { string id = null; // For precomps var layers = new List <Layer>(); var layerMap = new Dictionary <long, Layer>(); // For images var width = 0; var height = 0; string imageFileName = null; string relativeFolder = null; reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "id": id = reader.NextString(); break; case "layers": reader.BeginArray(); while (reader.HasNext()) { var layer = LayerParser.Parse(reader, composition); layerMap.Add(layer.Id, layer); layers.Add(layer); } reader.EndArray(); break; case "w": width = reader.NextInt(); break; case "h": height = reader.NextInt(); break; case "p": imageFileName = reader.NextString(); break; case "u": relativeFolder = reader.NextString(); break; default: reader.SkipValue(); break; } } reader.EndObject(); if (imageFileName != null) { var image = new LottieImageAsset(width, height, id, imageFileName, relativeFolder); images[image.Id] = image; } else { precomps.Add(id, layers); } } reader.EndArray(); }