Beispiel #1
0
        internal static async Task <AnimatedVisualFactory?> LoadAsync(
            ImageAssetHandler?imageLoader,
            Uri uri,
            LottieVisualOptions options)
        {
            if (uri is null)
            {
                return(null);
            }

            var absoluteUri = Uris.GetAbsoluteUri(uri);

            if (absoluteUri.Scheme.StartsWith("ms-"))
            {
                // The URI is an application URI. Defer to the StorageFileLoader.
                return(await StorageFileLoader.LoadAsync(imageLoader, absoluteUri, options));
            }
            else
            {
                var loader = new UriLoader(imageLoader);

                return(await Loader.LoadAsync(
                           () => GetJsonStreamAsync(uri),
                           loader,
                           options));
            }
        }
        internal static async Task <AnimatedVisualFactory?> LoadAsync(
            StorageFile file,
            LottieVisualOptions options)
        {
            var stream = (await file.OpenReadAsync()).AsStreamForRead();

            return(await LoadAsync(file.Name, stream, options));
        }
        internal static async Task <AnimatedVisualFactory?> LoadAsync(
            ImageAssetHandler?imageLoader,
            Uri applicationUri,
            LottieVisualOptions options)
        {
            Debug.Assert(applicationUri.AbsoluteUri.StartsWith("ms-"), "Precondition");
            var file = await StorageFile.GetFileFromApplicationUriAsync(applicationUri);

            return(await LoadAsync(imageLoader, file, options));
        }
Beispiel #4
0
        internal static async Task <AnimatedVisualFactory?> LoadAsync(
            ImageAssetHandler?imageLoader,
            IInputStream inputStream,
            LottieVisualOptions options)
        {
            if (inputStream is null)
            {
                return(null);
            }

            var loader = new InputStreamLoader(imageLoader, inputStream);

            return(await Loader.LoadAsync(
                       loader.GetJsonStreamAsync,
                       loader,
                       options));
        }
        internal static async Task <AnimatedVisualFactory?> LoadAsync(
            ImageAssetHandler?imageLoader,
            StorageFile file,
            LottieVisualOptions options)
        {
            if (file is null)
            {
                return(null);
            }

            if (file.Name.EndsWith(".lottie", StringComparison.OrdinalIgnoreCase))
            {
                // It's a .lottie file. Defer to the DotLottieLoader.
                return(await DotLottieLoader.LoadAsync(file, options));
            }

            var loader = new StorageFileLoader(imageLoader, file);

            return(await Loader.LoadAsync(
                       loader.GetJsonStreamAsync,
                       loader,
                       options));
        }
        static async Task <AnimatedVisualFactory?> LoadAsync(
            string fileName,
            Stream stream,
            LottieVisualOptions options)
        {
            ZipArchive zipArchive;

            try
            {
                zipArchive = new ZipArchive(stream, ZipArchiveMode.Read);
            }
            catch (InvalidDataException)
            {
                // Not a valid zip file.
                return(null);
            }

            var loader = new DotLottieLoader();

            return(await Loader.LoadAsync(
                       () => loader.GetJsonStreamAsync(zipArchive, fileName),
                       loader,
                       options));
        }
Beispiel #7
0
        internal async Task <ContentFactory> LoadAsync(LottieVisualOptions options)
        {
            LottieVisualDiagnostics diagnostics = null;
            var timeMeasurer = TimeMeasurer.Create();

            if (options.HasFlag(LottieVisualOptions.IncludeDiagnostics))
            {
                diagnostics = new LottieVisualDiagnostics {
                    Options = options
                };
            }

            var result = new ContentFactory(diagnostics);

            // Get the file name and JSON contents.
            (var fileName, var jsonStream) = await GetJsonStreamAsync();

            if (diagnostics != null)
            {
                diagnostics.FileName = fileName;
                diagnostics.ReadTime = timeMeasurer.GetElapsedAndRestart();
            }

            if (jsonStream is null)
            {
                // Failed to load ...
                return(result);
            }

            // Parsing large Lottie files can take significant time. Do it on
            // another thread.
            LottieComposition lottieComposition = null;

            await CheckedAwaitAsync(Task.Run(() =>
            {
                lottieComposition =
                    LottieCompositionReader.ReadLottieCompositionFromJsonStream(
                        jsonStream,
                        LottieCompositionReader.Options.IgnoreMatchNames,
                        out var readerIssues);

                if (diagnostics != null)
                {
                    diagnostics.JsonParsingIssues = ToIssues(readerIssues);
                }
            }));

            if (diagnostics != null)
            {
                diagnostics.ParseTime = timeMeasurer.GetElapsedAndRestart();
            }

            if (lottieComposition is null)
            {
                // Failed to load...
                return(result);
            }

            if (diagnostics != null)
            {
                // Save the LottieComposition in the diagnostics so that the xml and codegen
                // code can be derived from it.
                diagnostics.LottieComposition = lottieComposition;

                // Validate the composition and report if issues are found.
                diagnostics.LottieValidationIssues = ToIssues(LottieCompositionValidator.Validate(lottieComposition));
                diagnostics.ValidationTime         = timeMeasurer.GetElapsedAndRestart();
            }

            result.SetDimensions(
                width: lottieComposition.Width,
                height: lottieComposition.Height,
                duration: lottieComposition.Duration);

            // Translating large Lotties can take significant time. Do it on another thread.
            WinCompData.Visual wincompDataRootVisual = null;
            uint requiredUapVersion  = 0;
            var  optimizationEnabled = options.HasFlag(LottieVisualOptions.Optimize);

            TranslationResult translationResult;

            await CheckedAwaitAsync(Task.Run(() =>
            {
                // Generate property bindings only if the diagnostics object was requested.
                // This is because the binding information is output in the diagnostics object
                // so there's no point translating bindings if the diagnostics object
                // isn't available.
                var makeColorsBindable = diagnostics != null && options.HasFlag(LottieVisualOptions.BindableColors);
                translationResult      = LottieToWinCompTranslator.TryTranslateLottieComposition(
                    lottieComposition: lottieComposition,
                    configuration: new TranslatorConfiguration
                {
                    TranslatePropertyBindings = makeColorsBindable,
                    GenerateColorBindings     = makeColorsBindable,
                    TargetUapVersion          = GetCurrentUapVersion(),
                });

                wincompDataRootVisual = translationResult.RootVisual;
                requiredUapVersion    = translationResult.MinimumRequiredUapVersion;

                if (diagnostics != null)
                {
                    diagnostics.TranslationIssues = ToIssues(translationResult.TranslationIssues);
                    diagnostics.TranslationTime   = timeMeasurer.GetElapsedAndRestart();

                    // If there were any property bindings, save them in the Diagnostics object.
                    if (translationResult.SourceMetadata.TryGetValue(s_propertyBindingNamesKey, out var propertyBindingNames))
                    {
                        diagnostics.ThemePropertyBindings = (IReadOnlyList <PropertyBinding>)propertyBindingNames;
                    }
                }

                // Optimize the resulting translation. This will usually significantly reduce the size of
                // the Composition code, however it might slow down loading too much on complex Lotties.
                if (wincompDataRootVisual != null && optimizationEnabled)
                {
                    // Optimize.
                    wincompDataRootVisual = UIData.Tools.Optimizer.Optimize(wincompDataRootVisual, ignoreCommentProperties: true);

                    if (diagnostics != null)
                    {
                        diagnostics.OptimizationTime = timeMeasurer.GetElapsedAndRestart();
                    }
                }
            }));

            if (wincompDataRootVisual is null)
            {
                // Failed.
                return(result);
            }
            else
            {
                if (diagnostics != null)
                {
                    // Save the root visual so diagnostics can generate XML and codegen.
                    diagnostics.RootVisual         = wincompDataRootVisual;
                    diagnostics.RequiredUapVersion = requiredUapVersion;
                }

                result.SetRootVisual(wincompDataRootVisual);
                return(result);
            }
        }