Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a SKLottieView to play Lottie animations #118

Merged
merged 19 commits into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions SkiaSharp.Extended.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Maui", "Maui", "{3BAE904F-F
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpDemo", "samples\Maui\SkiaSharpDemo\SkiaSharpDemo.csproj", "{2C67033A-2C49-4146-B942-9CDD2E0BA412}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Extended.UI.Maui.Tests", "tests\SkiaSharp.Extended.UI.Maui.Tests\SkiaSharp.Extended.UI.Maui.Tests.csproj", "{4B4EC78C-33B5-456D-BD7D-4358D16272F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -433,6 +435,30 @@ Global
{2C67033A-2C49-4146-B942-9CDD2E0BA412}.Release|x86.ActiveCfg = Release|Any CPU
{2C67033A-2C49-4146-B942-9CDD2E0BA412}.Release|x86.Build.0 = Release|Any CPU
{2C67033A-2C49-4146-B942-9CDD2E0BA412}.Release|x86.Deploy.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|ARM.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|iPhone.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|x64.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Debug|x86.Build.0 = Debug|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|Any CPU.Build.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|ARM.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|ARM.Build.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|iPhone.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|iPhone.Build.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|x64.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|x64.Build.0 = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|x86.ActiveCfg = Release|Any CPU
{4B4EC78C-33B5-456D-BD7D-4358D16272F4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -454,6 +480,7 @@ Global
{2C0DAB3F-1246-4AE7-BFA5-E7F5DDD7E1C4} = {5DEC7961-7CE3-44D7-A7FC-6185BA2D37FE}
{3BAE904F-F162-4444-AFB6-EA9D288BCDF7} = {51B0C2C7-732B-4A5C-A4F2-55655D147866}
{2C67033A-2C49-4146-B942-9CDD2E0BA412} = {3BAE904F-F162-4444-AFB6-EA9D288BCDF7}
{4B4EC78C-33B5-456D-BD7D-4358D16272F4} = {5555F827-12DF-4D15-BF07-3A720FC2EF3F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {08D78153-5DD7-4C52-A348-46AA448B2CFC}
Expand Down
3 changes: 3 additions & 0 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Task("build")
.Does(() =>
{
var settings = new MSBuildSettings()
{ AllowPreviewVersion = true }
.EnableBinaryLogger("./output/binlogs/build.binlog")
.SetConfiguration("Release")
.SetMaxCpuCount(0)
Expand All @@ -20,6 +21,7 @@ Task("pack")
.Does(() =>
{
MSBuild("./SkiaSharp.Extended-Pack.slnf", new MSBuildSettings()
{ AllowPreviewVersion = true }
.EnableBinaryLogger("./output/binlogs/pack.binlog")
.SetConfiguration("Release")
.SetMaxCpuCount(0)
Expand All @@ -33,6 +35,7 @@ Task("pack")
}

MSBuild("./SkiaSharp.Extended-Pack.slnf", new MSBuildSettings()
{ AllowPreviewVersion = true }
.EnableBinaryLogger("./output/binlogs/pack-preview.binlog")
.SetConfiguration("Release")
.SetMaxCpuCount(0)
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<AndroidResource Include="Resources\drawable-xxhdpi\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="Assets\Lottie\trophy.json" />
<None Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo.UWP/Lottie/trophy.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo.UWP/SkiaSharpDemo.UWP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
<Content Include="Lottie\trophy.json" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
Expand Down
1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo.WPF/Lottie/trophy.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo.WPF/SkiaSharpDemo.WPF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

<ItemGroup>
<Content Include="logo.png" CopyToOutputDirectory="PreserveNewest" />
<Content Include="Lottie\trophy.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

</Project>

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo.iOS/SkiaSharpDemo.iOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<ITunesArtwork Include="iTunesArtwork" />
<ITunesArtwork Include="iTunesArtwork@2x" />
<BundleResource Include="Resources\Lottie\trophy.json" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\Default-568h%402x.png" />
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<BundleResource Include="Resources\Lottie\trophy.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
Expand Down
1 change: 1 addition & 0 deletions samples/Forms/SkiaSharpDemo/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<converters:RoundToIntConverter x:Key="RoundToInt" />
<converters:RoundToConverter x:Key="RoundTo" />
<converters:TimeSpanToDoubleConverter x:Key="TimeSpanToDouble" />

<Style TargetType="StackLayout">
<Setter Property="Spacing" Value="0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Globalization;
using Xamarin.Forms;

namespace SkiaSharpDemo.Converters
{
public class TimeSpanToDoubleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value switch
{
TimeSpan ts => ts.TotalMilliseconds == 0 && parameter is not null
? double.Parse(parameter.ToString())
: ts.TotalMilliseconds,
_ => throw new ArgumentException("Value was not a TimeSpan.", nameof(value)),
};

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value switch
{
double d => TimeSpan.FromMilliseconds(d),
_ => throw new ArgumentException("Value was not a double.", nameof(value)),
};
}
}
45 changes: 45 additions & 0 deletions samples/Forms/SkiaSharpDemo/Demos/Lottie/LottiePage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SkiaSharp.Extended.UI.Controls;assembly=SkiaSharp.Extended.UI"
xmlns:views="clr-namespace:SkiaSharpDemo.Views"
x:Class="SkiaSharpDemo.Demos.LottiePage"
Title="Lottie">

<Grid RowDefinitions="*,Auto">

<controls:SKLottieView x:Name="lottieView"
Source="Lottie/trophy.json"
Duration="{Binding Duration}"
Progress="{Binding Progress}"
IsRunning="{Binding IsBusy}"/>

<BoxView Color="Green" Opacity="0.5" CornerRadius="12"
WidthRequest="25" HeightRequest="24" Margin="24"
HorizontalOptions="End" VerticalOptions="Start"
IsVisible="{Binding IsComplete, Source={Reference lottieView}}" />

<StackLayout Spacing="12" Padding="12" Grid.Row="1">

<Slider Minimum="0"
Maximum="{Binding Duration, Converter={StaticResource TimeSpanToDouble}, ConverterParameter=1}"
Value="{Binding Progress, Converter={StaticResource TimeSpanToDouble}}" />

<Grid ColumnDefinitions="*,*" Margin="0,-12,0,0">
<Label Grid.Column="0"
Text="{Binding Progress, StringFormat='{}{0:mm\\:ss\\.fff}'}" />
<Label Grid.Column="1" HorizontalOptions="End"
Text="{Binding Duration, StringFormat='{}{0:mm\\:ss\\.fff}'}" />
</Grid>

<StackLayout Orientation="Horizontal" HorizontalOptions="Center" Spacing="6">
<Button Text="Reset" Command="{Binding ResetCommand}" />
<Button Text="-100ms" Command="{Binding StepCommand}" CommandParameter="-100" />
<Button Text="Play/Pause" Command="{Binding PlayPauseCommand}" />
<Button Text="+100ms" Command="{Binding StepCommand}" CommandParameter="100" />
<Button Text="End" Command="{Binding EndCommand}" />
</StackLayout>

</StackLayout>
</Grid>

</ContentPage>
68 changes: 68 additions & 0 deletions samples/Forms/SkiaSharpDemo/Demos/Lottie/LottiePage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Windows.Input;
using System.Collections.Generic;
using SkiaSharp.Extended.UI.Controls;
using Xamarin.Forms;

namespace SkiaSharpDemo.Demos
{
public partial class LottiePage : ContentPage
{
private TimeSpan duration;
private TimeSpan progress;

public LottiePage()
{
InitializeComponent();

ResetCommand = new Command(OnReset);
StepCommand = new Command<string>(OnStep);
EndCommand = new Command(OnEnd);
PlayPauseCommand = new Command(OnPlayPause);

IsBusy = true;

BindingContext = this;
}

public TimeSpan Duration
{
get => duration;
set
{
duration = value;
OnPropertyChanged();
}
}

public TimeSpan Progress
{
get => progress;
set
{
progress = value;
OnPropertyChanged();
}
}

public ICommand ResetCommand { get; }

public ICommand StepCommand { get; }

public ICommand PlayPauseCommand { get; }

public ICommand EndCommand { get; }

private void OnReset() =>
Progress = TimeSpan.Zero;

private void OnStep(string step) =>
Progress += TimeSpan.FromMilliseconds(int.Parse(step));

private void OnEnd() =>
Progress = Duration;

private void OnPlayPause() =>
IsBusy = !IsBusy;
}
}
7 changes: 7 additions & 0 deletions samples/Forms/SkiaSharpDemo/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ public MainPage()
Color = Color.SteelBlue,
},
new Demo
{
Title = "Lottie",
Description = "Ooooh! Lottie animations are really cool and now super easy to do!",
PageType = typeof(LottiePage),
Color = Color.SteelBlue,
},
new Demo
{
Title = "ToImage",
Description = "You have that ImageSource and you really want an actual image... What do you do? Well, you ToSKImageAsync that puppy!",
Expand Down
1 change: 1 addition & 0 deletions samples/Maui/SkiaSharpDemo/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<converters:RoundToIntConverter x:Key="RoundToInt" />
<converters:RoundToConverter x:Key="RoundTo" />
<converters:TimeSpanToDoubleConverter x:Key="TimeSpanToDouble" />

</ResourceDictionary>
</Application.Resources>
Expand Down
22 changes: 22 additions & 0 deletions samples/Maui/SkiaSharpDemo/Converters/TimeSpanToDoubleConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Globalization;

namespace SkiaSharpDemo.Converters;

public class TimeSpanToDoubleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value switch
{
TimeSpan ts => ts.TotalMilliseconds == 0 && parameter is not null
? double.Parse(parameter.ToString())
: ts.TotalMilliseconds,
_ => throw new ArgumentException("Value was not a TimeSpan.", nameof(value)),
};

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value switch
{
double d => TimeSpan.FromMilliseconds(d),
_ => throw new ArgumentException("Value was not a double.", nameof(value)),
};
}
45 changes: 45 additions & 0 deletions samples/Maui/SkiaSharpDemo/Demos/Lottie/LottiePage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SkiaSharp.Extended.UI.Controls;assembly=SkiaSharp.Extended.UI"
xmlns:views="clr-namespace:SkiaSharpDemo.Views"
x:Class="SkiaSharpDemo.Demos.LottiePage"
Title="Lottie">

<Grid RowDefinitions="*,Auto">

<controls:SKLottieView x:Name="lottieView"
Source="Lottie/trophy.json"
Duration="{Binding Duration}"
Progress="{Binding Progress}"
IsRunning="{Binding IsBusy}"/>

<BoxView Color="Green" Opacity="0.5" CornerRadius="12"
WidthRequest="25" HeightRequest="24" Margin="24"
HorizontalOptions="End" VerticalOptions="Start"
IsVisible="{Binding IsComplete, Source={Reference lottieView}}" />

<VerticalStackLayout Spacing="12" Padding="12" Grid.Row="1">

<Slider Minimum="0"
Maximum="{Binding Duration, Converter={StaticResource TimeSpanToDouble}, ConverterParameter=1}"
Value="{Binding Progress, Converter={StaticResource TimeSpanToDouble}}" />

<Grid ColumnDefinitions="*,*" Margin="0,-12,0,0">
<Label Grid.Column="0"
Text="{Binding Progress, StringFormat='{}{0:mm\\:ss\\.fff}'}" />
<Label Grid.Column="1" HorizontalOptions="End"
Text="{Binding Duration, StringFormat='{}{0:mm\\:ss\\.fff}'}" />
</Grid>

<HorizontalStackLayout HorizontalOptions="Center" Spacing="6">
<Button Text="Reset" Command="{Binding ResetCommand}" />
<Button Text="-100ms" Command="{Binding StepCommand}" CommandParameter="-100" />
<Button Text="Play/Pause" Command="{Binding PlayPauseCommand}" />
<Button Text="+100ms" Command="{Binding StepCommand}" CommandParameter="100" />
<Button Text="End" Command="{Binding EndCommand}" />
</HorizontalStackLayout>

</VerticalStackLayout>
</Grid>

</ContentPage>
Loading