コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        //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);
            }
        }
コード例 #4
0
 public PathKeyframe(LottieComposition composition, Keyframe <Vector2?> keyframe)
     : base(composition, keyframe.StartValue, keyframe.EndValue, keyframe.Interpolator, keyframe.StartFrame, keyframe.EndFrame)
 {
     _pointKeyFrame = keyframe;
     CreatePath();
 }
コード例 #5
0
 public void Put(int rawRes, LottieComposition composition)
 {
     Put(rawRes.ToString(), composition);
 }
コード例 #6
0
 public static AnimatableFloatValue ParseFloat(JsonReader reader, LottieComposition composition)
 {
     return(ParseFloat(reader, composition, true));
 }
コード例 #7
0
            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));
            }
コード例 #8
0
        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;
                }
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        // 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;
            }
        }
コード例 #11
0
 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)));
 }
コード例 #12
0
        /// <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));
        }
コード例 #13
0
 internal static AnimatableIntegerValue ParseInteger(JsonReader reader, LottieComposition composition)
 {
     return(new AnimatableIntegerValue(Parse(reader, composition, IntegerParser.Instance)));
 }
コード例 #14
0
        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));
        }
コード例 #15
0
 internal static AnimatableGradientColorValue ParseGradientColor(JsonReader reader, LottieComposition composition, int points)
 {
     return(new(Parse(reader, composition, new GradientColorParser(points))));
 }
コード例 #16
0
ファイル: LayerParser.cs プロジェクト: aleua/LottieUWP
        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));
        }
コード例 #17
0
 /// <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));
 }
コード例 #18
0
 public static AnimatableFloatValue ParseFloat(JsonReader reader, LottieComposition composition, bool isDp)
 {
     return(new(Parse(reader, isDp ? Utils.Utils.DpScale() : 1f, composition, FloatParser.Instance)));
 }
コード例 #19
0
        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,
コード例 #20
0
 internal static AnimatablePointValue ParsePoint(JsonReader reader, LottieComposition composition)
 {
     return(new(Parse(reader, Utils.Utils.DpScale(), composition, PointFParser.Instance)));
 }
コード例 #21
0
        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));
        }
コード例 #22
0
 internal static AnimatableScaleValue ParseScale(JsonReader reader, LottieComposition composition)
 {
     return(new(Parse(reader, composition, ScaleXyParser.Instance)));
 }
コード例 #23
0
        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));
        }
コード例 #24
0
 internal static AnimatableShapeValue ParseShapeData(JsonReader reader, LottieComposition composition)
 {
     return(new(Parse(reader, Utils.Utils.DpScale(), composition, ShapeDataParser.Instance)));
 }
コード例 #25
0
 /// <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 &gt;= 7 and &lt;= the target UAP version.</param>
 /// <returns>The results of the translation and the issues.</returns>
 public static MultiVersionTranslationResult TryTranslateLottieComposition(
     LottieComposition lottieComposition,
     in TranslatorConfiguration configuration,
コード例 #26
0
 internal static AnimatableTextFrame ParseDocumentData(JsonReader reader, LottieComposition composition)
 {
     return(new(Parse(reader, composition, DocumentDataParser.Instance)));
 }
コード例 #27
0
        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));
        }
コード例 #28
0
 internal static AnimatableColorValue ParseColor(JsonReader reader, LottieComposition composition)
 {
     return(new(Parse(reader, composition, ColorParser.Instance)));
 }
コード例 #29
0
        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));
        }
コード例 #30
0
        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();
        }