Esempio n. 1
0
        internal static BaseLayer ForModel(Layer layerModel, LottieDrawable 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);
            }
        }
        private static void ParseLayers(JsonReader reader, LottieComposition composition, List <Layer> layers,
                                        Dictionary <long, Layer> layerMap)
        {
            var imageCount = 0;

            reader.BeginArray();
            while (reader.HasNext())
            {
                var layer = LayerParser.Parse(reader, composition);
                if (layer.GetLayerType() == Layer.LayerType.Image)
                {
                    imageCount++;
                }
                layers.Add(layer);
                layerMap[layer.Id] = layer;

                if (imageCount > 4)
                {
                    LottieLog.Warn(
                        $"You have {imageCount} images. Lottie should primarily be used with shapes. If you are using Adobe Illustrator, convert the Illustrator layers to shape layers.");
                }
            }

            reader.EndArray();
        }
Esempio n. 3
0
        internal void InterpolateBetween(ShapeData shapeData1, ShapeData shapeData2, float percentage)
        {
            if (_initialPoint == null)
            {
                _initialPoint = new Vector2();
            }
            _closed = shapeData1.Closed || shapeData2.Closed;

            if (shapeData1.Curves.Count != shapeData2.Curves.Count)
            {
                LottieLog.Warn($"Curves must have the same number of control points. Shape 1: {shapeData1.Curves.Count}\tShape 2: {shapeData2.Curves.Count}");
            }

            if (_curves.Count == 0)
            {
                int points = Math.Min(shapeData1.Curves.Count, shapeData2.Curves.Count);
                for (int i = 0; i < points; i++)
                {
                    _curves.Add(new CubicCurveData());
                }
            }

            var initialPoint1 = shapeData1.InitialPoint;
            var initialPoint2 = shapeData2.InitialPoint;

            SetInitialPoint(MiscUtils.Lerp(initialPoint1.X, initialPoint2.X, percentage), MiscUtils.Lerp(initialPoint1.Y, initialPoint2.Y, percentage));

            for (var i = _curves.Count - 1; i >= 0; i--)
            {
                var curve1 = shapeData1.Curves[i];
                var curve2 = shapeData2.Curves[i];

                var cp11    = curve1.ControlPoint1;
                var cp21    = curve1.ControlPoint2;
                var vertex1 = curve1.Vertex;

                var cp12    = curve2.ControlPoint1;
                var cp22    = curve2.ControlPoint2;
                var vertex2 = curve2.Vertex;

                _curves[i].SetControlPoint1(MiscUtils.Lerp(cp11.X, cp12.X, percentage), MiscUtils.Lerp(cp11.Y, cp12.Y, percentage));
                _curves[i].SetControlPoint2(MiscUtils.Lerp(cp21.X, cp22.X, percentage), MiscUtils.Lerp(cp21.Y, cp22.Y, percentage));
                _curves[i].SetVertex(MiscUtils.Lerp(vertex1.X, vertex2.X, percentage), MiscUtils.Lerp(vertex1.Y, vertex2.Y, percentage));
            }
        }
Esempio n. 4
0
        /**
         * If the animation doesn't exist in the cache, null will be returned.
         *
         * Once the animation is successfully parsed, {@link #renameTempFile(FileExtension)} must be
         * called to move the file from a temporary location to its permanent cache location so it can
         * be used in the future.
         */
        //internal async Task<KeyValuePair<FileExtension, Stream>?> FetchAsync(CancellationToken cancellationToken = default(CancellationToken))
        //{
        //    StorageFile cachedFile = null;
        //    try
        //    {
        //        cachedFile = await GetCachedFileAsync(_url, cancellationToken);
        //    }
        //    catch (FileNotFoundException)
        //    {
        //        return null;
        //    }
        //    if (cachedFile == null)
        //    {
        //        return null;
        //    }

        //    Stream inputStream;
        //    try
        //    {
        //        inputStream = await cachedFile.OpenStreamForReadAsync().AsAsyncOperation().AsTask(cancellationToken);
        //    }
        //    catch (FileNotFoundException)
        //    {
        //        return null;
        //    }

        //    FileExtension extension;
        //    if (cachedFile.Path.EndsWith(".zip"))
        //    {
        //        extension = FileExtension.Zip;
        //    }
        //    else
        //    {
        //        extension = FileExtension.Json;
        //    }

        //    Debug.WriteLine("Cache hit for " + _url + " at " + cachedFile.Path, LottieLog.Tag);
        //    return new KeyValuePair<FileExtension, Stream>(extension, inputStream);
        //}

        ///// <summary>
        ///// Writes an InputStream from a network response to a temporary file. If the file successfully parses
        ///// to an composition, {@link #renameTempFile(FileExtension)} should be called to move the file
        ///// to its final location for future cache hits.
        ///// </summary>
        ///// <param name="stream"></param>
        ///// <param name="extension"></param>
        ///// <returns></returns>
        //internal async Task<StorageFile> WriteTempCacheFileAsync(Stream stream, FileExtension extension, CancellationToken cancellationToken = default(CancellationToken))
        //{
        //    var fileName = FilenameForUrl(_url, extension, true);
        //    var file = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting).AsTask(cancellationToken);
        //    try
        //    {
        //        using (var output = await file.OpenStreamForWriteAsync().AsAsyncOperation().AsTask(cancellationToken))
        //        {
        //            await stream.CopyToAsync(output).AsAsyncAction().AsTask(cancellationToken);
        //        }
        //    }
        //    finally
        //    {
        //        stream.Dispose();
        //    }
        //    return file;
        //}

        /// <summary>
        ///     If the file created by {@link #writeTempCacheFile(InputStream, FileExtension)} was successfully parsed,
        ///     this should be called to remove the temporary part of its name which will allow it to be a cache hit in the future.
        /// </summary>
        /// <param name="extension"></param>
        internal Task RenameTempFileAsync(FileExtension extension, CancellationToken cancellationToken = default)
        {
            return(Task.Run(() =>
            {
                var fileName = FilenameForUrl(_url, extension, true);
                var file = new FileInfo(fileName);
                var newFileName = file.Name.Replace(".temp", "");
                var oldFilename = file.Name;
                try
                {
                    file.MoveTo(newFileName);
                    Debug.WriteLine($"Copying temp file to real file ({file.Name})", LottieLog.Tag);
                }
                catch
                {
                    LottieLog.Warn($"Unable to rename cache file {oldFilename} to {newFileName}.");
                }
            }));
        }
Esempio n. 5
0
        /// <summary>
        /// If the file created by {@link #writeTempCacheFile(InputStream, FileExtension)} was successfully parsed,
        /// this should be called to remove the temporary part of its name which will allow it to be a cache hit in the future.
        /// </summary>
        /// <param name="extension"></param>
        internal async Task RenameTempFileAsync(FileExtension extension, CancellationToken cancellationToken = default(CancellationToken))
        {
            string fileName = FilenameForUrl(_url, extension, true);
            var    file     = await ApplicationData.Current.LocalCacheFolder.GetFileAsync(fileName).AsTask(cancellationToken);

            string newFileName = file.Name.Replace(".temp", "");
            string oldFilename = file.Name;

            try
            {
                await file.RenameAsync(newFileName).AsTask(cancellationToken);

                Debug.WriteLine($"Copying temp file to real file ({file.Name})", LottieLog.Tag);
            }
            catch
            {
                LottieLog.Warn($"Unable to rename cache file {oldFilename} to {newFileName}.");
            }
        }