WPF你还在用GIF?使用LottieSharp展现json文件动画

前言

  • 今天介绍一篇使用json格式在wpf中播放动画效果;

正文

  • 话说在上古(1987)时代,Gif因其体积小成像相对清晰和非常强的兼容性,而大受欢迎;.

  • Gif也因为当时的技术限制导致很多缺陷 这包括对电脑的内存和性能占用非常大;

  • 同时Gif还是一个有损文件格式 对半透明和颜色都有一定程度的限制;

  • 随着技术的进步衍生出了 apngwebp格式相对技术色彩范围更广效果也更清晰也占用更低的内存;

  • apngwebp这两种格式需要复杂的开发环境来支持,还是不太友好;

  • 这时就需要另外一种格式了 序列帧

  • 序列帧它是一个无损低内存的格式,不过只能在客户端使用;

  • 因为帧数多想要在web环境中使用 ,就需要转换为雪碧图

  • Lottie动画是由airbnb公司推出的;

  • Lottie的原理是把各种矢量素材以及效果 打包成一个体积很小的json文件然后交给开发人员就好了;

  • 经常在APP所见到的动态图标都是由Lottie来实现的;

  • 下面我们如何开源项目LottieSharp进行展现json文件动画;

1)Nuget 搜索 LottieSharp 点击安装;

WPF你还在用GIF?使用LottieSharp展现json文件动画

2)使用方式很简单如下

 <ws:Window x:Class="LottieSharp.Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LottieSharp.Sample"
        xmlns:lottieSharp="clr-namespace:LottieSharp;assembly=LottieSharp"
        xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"
        mc:Ignorable="d"
        Title="{Binding Path=ImageDrawable.Fps, StringFormat={}LottieSharp:{0}, ElementName=LottieAnimationView}" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Expander  ExpandDirection="Left" Grid.Column="0" 
                   Style="{DynamicResource ExpanderStyle1}" IsExpanded="True">
            <Border  
                     BorderBrush="{StaticResource PrimaryPressedSolidColorBrush}"
                     BorderThickness="0,0,1,0">
                <ListBox x:Name="myListBox"
                         SelectionChanged="myListBox_SelectionChanged"/>

            </Border>
        </Expander>
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
            </Grid.RowDefinitions>
            <lottieSharp:LottieAnimationView x:Name="LottieAnimationView" DefaultCacheStrategy="None" FileName="Assets/moody-dog.json" AutoPlay="True" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            <Slider Grid.Row="1" Maximum="10" Value="1" Minimum="0.1" SmallChange="0.1" LargeChange="0.1" ValueChanged="Slider_ValueChanged_1" />
            <Slider Grid.Row="2" Minimum="0" Maximum="1000" SmallChange="1" ValueChanged="Slider_ValueChanged" />

            <DockPanel Grid.Row="3" Margin="5">
                <Button DockPanel.Dock="Left" Content="Pause Animation" Click="PauseAnimation_Click" HorizontalAlignment="Left" />
                <Button DockPanel.Dock="Left" Margin="10,0,0,0" Content="Start Animation" Click="StartAnimation_Click" HorizontalAlignment="Left"/>
                <!--<Button DockPanel.Dock="Left" Content="Load Animation" Margin="10,0,0,0" Click="LoadAnimation_Click" HorizontalAlignment="Left"/>-->

                <StackPanel DockPanel.Dock="Right" Orientation="Horizontal"  HorizontalAlignment="Right" Margin="10,0" Width="158">
                    <TextBlock Text="Fps: " FontSize="16" VerticalAlignment="Center"></TextBlock>
                    <TextBox Text="{Binding FrameRate, ElementName=LottieAnimationView, Mode=TwoWay}" Width="60"/>
                </StackPanel>
            </DockPanel>

            <Grid Grid.Row="4" Margin="5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="ImageAssetsFolder (optional):" VerticalAlignment="Center"/>
                <TextBox Grid.Column="1" Name="ImageAssetsFolderTextBox" Margin="10,0,0,0" TextChanged="ImageAssetsFolderTextBox_TextChanged"/>
                <Button Grid.Column="2" Margin="10,0,0,0" Content="..." Click="LoadImageAssetsFolder_Click" />
                <Button Grid.Column="3" Margin="10,0,0,0" Content="X" ToolTip="Delete path" Click="DeleteImageAssetsFolder_Click" />
            </Grid>
        </Grid>
       

    </Grid>
</ws:Window>

3)后台逻辑代码;

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;

namespace LottieSharp.Sample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
            LottieAnimationView.UseHardwareAcceleration(true);
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets");
            var root = new DirectoryInfo(path);
            var array = new List<string>(); 
            foreach (var item in root.GetFiles())
            {
                array.Add(item.Name);
            }
            myListBox.ItemsSource = array;
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            LottieAnimationView.Dispose();
            DataContext = null;
        }

        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            LottieAnimationView.PauseAnimation();
            LottieAnimationView.Progress = (float)(e.NewValue / 1000);
        }

        private void LoadAnimation_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.DefaultExt = ".json";
            openFileDialog.Filter = "Json files|*.json|All files|*.*";
            if (openFileDialog.ShowDialog() == true)
            {
                LottieAnimationView.PauseAnimation();
                LottieAnimationView.FileName = openFileDialog.FileName;
                LottieAnimationView.PlayAnimation();
            }
        }

        private void StartAnimation_Click(object sender, RoutedEventArgs e)
        {
            LottieAnimationView.PlayAnimation();
        }

        private void PauseAnimation_Click(object sender, RoutedEventArgs e)
        {
            LottieAnimationView.PauseAnimation();
        }

        private void LoadImageAssetsFolder_Click(object sender, RoutedEventArgs e)
        {
            using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
            {
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    ImageAssetsFolderTextBox.Text = dialog.SelectedPath;
            }
        }

        private void DeleteImageAssetsFolder_Click(object sender, RoutedEventArgs e)
        {
            ImageAssetsFolderTextBox.Text = "";
        }

        private void ImageAssetsFolderTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            LottieAnimationView.PauseAnimation();
            LottieAnimationView.ImageAssetsFolder = ImageAssetsFolderTextBox.Text;
        }

        private void Slider_ValueChanged_1(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (!double.IsNaN(e.NewValue))
                LottieAnimationView.Scale = (float)e.NewValue;
        }

        private void myListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets", myListBox.SelectedItem.ToString());
            LottieAnimationView.PauseAnimation();
            LottieAnimationView.FileName = path;
            LottieAnimationView.PlayAnimation();
        }
    }
}

案例中只是少数的json文件,可以去官网下载更多json文件源码