前言

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

正文

  • 话说在上古​​(1987)​​时代,​​Gif​​因其​​体积小​​成像相对​​清晰​​和非常强的​​兼容性​​,而大受欢迎;
  • ​Gif​​也因为当时的技术限制导致很多缺陷 这包括对电脑的内存和性能占用非常大;
  • 同时​​Gif​​还是一个有损文件格式 对半透明和颜色都有一定程度的限制;
  • 随着技术的进步衍生出了​​apng​​和​​webp​​格式相对技术色彩范围​​更广​​效果也​​更清晰​​也占用​​更低的内存​​;
  • ​apng​​​和​​webp​​这两种格式需要复杂的开发环境来支持,还是不太友好;
  • 这时就需要另外一种格式了​​序列帧​​;
  • ​序列帧​​​它是一个​​无损​​且​​低内存​​的格式,不过只能在​​客户端​​使用;
  • 因为帧数多想要在​​web​​环境中使用 ,就需要转换为​​雪碧图​​;
  • ​Lottie​​​动画是由​​airbnb​​公司推出的;
  • ​Lottie​​​的原理是把各种矢量素材以及效果 打包成一个体积很小的​​json​​文件然后交给开发人员就好了;
  • 经常在​​APP​​所见到的动态图标都是由​​Lottie​​来实现的;
  • 下面我们如何开源项目LottieSharp[1]进行展现​​json​​文件动画;

1)​​Nuget​​​ 搜索 ​​LottieSharp​​ 点击安装;

你还在用GIF?那就out了_xml

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​​​文件,可以去官网[2]下载更多​​json​​文件;源码[3]

WPF开发者

,赞27

参考资料

[1]

LottieSharp: ​https://github.com/ascora/LottieSharp​

[2]

官网: ​https://lottiefiles.com/featured​

[3]

源码: ​https://gitee.com/yanjinhua/LottieSharp​