Update
This commit is contained in:
Родитель
fd4c6ff283
Коммит
3b2b6e22ef
|
@ -108,6 +108,70 @@ public class Lottie : Control
|
|||
_baseUri = serviceProvider.GetContextBaseUri();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnLoaded()
|
||||
{
|
||||
base.OnLoaded();
|
||||
|
||||
var elemVisual = ElementComposition.GetElementVisual(this);
|
||||
var compositor = elemVisual?.Compositor;
|
||||
if (compositor is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_customVisual = compositor.CreateCustomVisual(new LottieCompositionCustomVisualHandler());
|
||||
ElementComposition.SetElementChildVisual(this, _customVisual);
|
||||
|
||||
LayoutUpdated += OnLayoutUpdated;
|
||||
|
||||
if (_preloadPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisposeImpl();
|
||||
Load(_preloadPath);
|
||||
|
||||
_customVisual.Size = new Vector2((float)Bounds.Size.Width, (float)Bounds.Size.Height);
|
||||
_customVisual.SendHandlerMessage(
|
||||
new LottiePayload(
|
||||
LottieCommand.Update,
|
||||
_animation,
|
||||
Stretch,
|
||||
StretchDirection));
|
||||
|
||||
Start();
|
||||
_preloadPath = null;
|
||||
}
|
||||
|
||||
protected override void OnUnloaded()
|
||||
{
|
||||
base.OnUnloaded();
|
||||
|
||||
LayoutUpdated -= OnLayoutUpdated;
|
||||
|
||||
Stop();
|
||||
DisposeImpl();
|
||||
}
|
||||
|
||||
private void OnLayoutUpdated(object? sender, EventArgs e)
|
||||
{
|
||||
if (_customVisual == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_customVisual.Size = new Vector2((float)Bounds.Size.Width, (float)Bounds.Size.Height);
|
||||
_customVisual.SendHandlerMessage(
|
||||
new LottiePayload(
|
||||
LottieCommand.Update,
|
||||
_animation,
|
||||
Stretch,
|
||||
StretchDirection));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (_animation == null)
|
||||
|
@ -122,52 +186,6 @@ public class Lottie : Control
|
|||
return Stretch.CalculateSize(availableSize, sourceSize, StretchDirection);
|
||||
}
|
||||
|
||||
protected override void OnLoaded()
|
||||
{
|
||||
var elemVisual = ElementComposition.GetElementVisual(this);
|
||||
var compositor = elemVisual?.Compositor;
|
||||
if (compositor is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_customVisual = compositor.CreateCustomVisual(new LottieCustomVisualHandler());
|
||||
ElementComposition.SetElementChildVisual(this, _customVisual);
|
||||
LayoutUpdated += OnLayoutUpdated;
|
||||
|
||||
base.OnLoaded();
|
||||
|
||||
if (_preloadPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DisposeImpl();
|
||||
Load(_preloadPath);
|
||||
|
||||
_customVisual.Size = new Vector2((float)Bounds.Size.Width, (float)Bounds.Size.Height);
|
||||
_customVisual.SendHandlerMessage(new LottieCustomVisualHandler.Payload(
|
||||
LottieCustomVisualHandler.Command.Update,
|
||||
_animation,
|
||||
Stretch,
|
||||
StretchDirection));
|
||||
|
||||
Start();
|
||||
_preloadPath = null;
|
||||
}
|
||||
|
||||
private void OnLayoutUpdated(object sender, EventArgs e)
|
||||
{
|
||||
if (_customVisual == null) return;
|
||||
_customVisual.Size = new Vector2((float)Bounds.Size.Width, (float)Bounds.Size.Height);
|
||||
_customVisual.SendHandlerMessage(
|
||||
new LottieCustomVisualHandler.Payload(
|
||||
LottieCustomVisualHandler.Command.Update,
|
||||
_animation,
|
||||
Stretch,
|
||||
StretchDirection));
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (_animation == null)
|
||||
|
@ -212,12 +230,6 @@ public class Lottie : Control
|
|||
}
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
_customVisual?.SendHandlerMessage(
|
||||
new LottieCustomVisualHandler.Payload(LottieCustomVisualHandler.Command.Stop));
|
||||
}
|
||||
|
||||
private SkiaSharp.Skottie.Animation? Load(Stream stream)
|
||||
{
|
||||
using var managedStream = new SKManagedStream(stream);
|
||||
|
@ -227,12 +239,13 @@ public class Lottie : Control
|
|||
|
||||
Logger
|
||||
.TryGet(LogEventLevel.Information, LogArea.Control)?
|
||||
.Log(this,
|
||||
$"Version: {animation.Version} Duration: {animation.Duration} Fps:{animation.Fps} InPoint: {animation.InPoint} OutPoint: {animation.OutPoint}");
|
||||
.Log(this, $"Version: {animation.Version} Duration: {animation.Duration} Fps:{animation.Fps} InPoint: {animation.InPoint} OutPoint: {animation.OutPoint}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.TryGet(LogEventLevel.Warning, LogArea.Control)?.Log(this, "Failed to load animation.");
|
||||
Logger
|
||||
.TryGet(LogEventLevel.Warning, LogArea.Control)?
|
||||
.Log(this, "Failed to load animation.");
|
||||
}
|
||||
|
||||
return animation;
|
||||
|
@ -240,7 +253,9 @@ public class Lottie : Control
|
|||
|
||||
private SkiaSharp.Skottie.Animation? Load(string path, Uri? baseUri)
|
||||
{
|
||||
var uri = path.StartsWith("/") ? new Uri(path, UriKind.Relative) : new Uri(path, UriKind.RelativeOrAbsolute);
|
||||
var uri = path.StartsWith("/")
|
||||
? new Uri(path, UriKind.Relative)
|
||||
: new Uri(path, UriKind.RelativeOrAbsolute);
|
||||
if (uri.IsAbsoluteUri && uri.IsFile)
|
||||
{
|
||||
using var fileStream = File.OpenRead(uri.LocalPath);
|
||||
|
@ -264,7 +279,6 @@ public class Lottie : Control
|
|||
if (path is null)
|
||||
{
|
||||
DisposeImpl();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -274,6 +288,7 @@ public class Lottie : Control
|
|||
{
|
||||
_repeatCount = RepeatCount;
|
||||
_animation = Load(path, _baseUri);
|
||||
|
||||
if (_animation is null)
|
||||
{
|
||||
return;
|
||||
|
@ -286,21 +301,31 @@ public class Lottie : Control
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.TryGet(LogEventLevel.Warning, LogArea.Control)?.Log(this, "Failed to load animation: " + e);
|
||||
Logger
|
||||
.TryGet(LogEventLevel.Warning, LogArea.Control)?
|
||||
.Log(this, "Failed to load animation: " + e);
|
||||
_animation = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeImpl()
|
||||
{
|
||||
_customVisual?.SendHandlerMessage(
|
||||
new LottieCustomVisualHandler.Payload(LottieCustomVisualHandler.Command.Dispose));
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_customVisual?.SendHandlerMessage(new LottieCustomVisualHandler.Payload(LottieCustomVisualHandler.Command.Start,
|
||||
_animation,
|
||||
Stretch, StretchDirection, _repeatCount));
|
||||
_customVisual?.SendHandlerMessage(
|
||||
new LottiePayload(
|
||||
LottieCommand.Start,
|
||||
_animation,
|
||||
Stretch,
|
||||
StretchDirection,
|
||||
_repeatCount));
|
||||
}
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
_customVisual?.SendHandlerMessage(new LottiePayload(LottieCommand.Stop));
|
||||
}
|
||||
|
||||
private void DisposeImpl()
|
||||
{
|
||||
_customVisual?.SendHandlerMessage(new LottiePayload(LottieCommand.Dispose));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
namespace Avalonia.Skia.Lottie;
|
||||
|
||||
internal enum LottieCommand
|
||||
{
|
||||
Start,
|
||||
Stop,
|
||||
Update,
|
||||
Dispose
|
||||
}
|
|
@ -6,7 +6,7 @@ using SkiaSharp;
|
|||
|
||||
namespace Avalonia.Skia.Lottie;
|
||||
|
||||
internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
||||
internal class LottieCompositionCustomVisualHandler : CompositionCustomVisualHandler
|
||||
{
|
||||
private TimeSpan _primaryTimeElapsed, _animationElapsed;
|
||||
private TimeSpan? _lastServerTime;
|
||||
|
@ -19,35 +19,24 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
private int _repeatCount;
|
||||
private int _count;
|
||||
|
||||
public enum Command
|
||||
{
|
||||
Start,
|
||||
Stop,
|
||||
Update,
|
||||
Dispose
|
||||
}
|
||||
|
||||
public record struct Payload(
|
||||
Command Command,
|
||||
SkiaSharp.Skottie.Animation? Animation = null,
|
||||
Stretch? Stretch = null,
|
||||
StretchDirection? StretchDirection = null,
|
||||
int? RepeatCount = null);
|
||||
|
||||
public override void OnMessage(object message)
|
||||
{
|
||||
if (message is not Payload msg) return;
|
||||
if (message is not LottiePayload msg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case
|
||||
{
|
||||
Command: Command.Start,
|
||||
LottieCommand: LottieCommand.Start,
|
||||
Animation: { } an,
|
||||
Stretch: { } st,
|
||||
StretchDirection: { } sd,
|
||||
RepeatCount: { } rp
|
||||
}:
|
||||
{
|
||||
_running = true;
|
||||
_lastServerTime = null;
|
||||
_stretch = st;
|
||||
|
@ -58,24 +47,37 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
_animationElapsed = TimeSpan.Zero;
|
||||
RegisterForNextAnimationFrameUpdate();
|
||||
break;
|
||||
}
|
||||
case
|
||||
{
|
||||
Command: Command.Update,
|
||||
LottieCommand: LottieCommand.Update,
|
||||
Stretch: { } st,
|
||||
StretchDirection: { } sd
|
||||
}:
|
||||
{
|
||||
_stretch = st;
|
||||
_stretchDirection = sd;
|
||||
RegisterForNextAnimationFrameUpdate();
|
||||
break;
|
||||
case {Command: Command.Stop}:
|
||||
}
|
||||
case
|
||||
{
|
||||
LottieCommand: LottieCommand.Stop
|
||||
}:
|
||||
{
|
||||
_running = false;
|
||||
_animationElapsed = TimeSpan.Zero;
|
||||
_count = 0;
|
||||
break;
|
||||
case {Command: Command.Dispose}:
|
||||
}
|
||||
case
|
||||
{
|
||||
LottieCommand: LottieCommand.Dispose
|
||||
}:
|
||||
{
|
||||
DisposeImpl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,6 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
RegisterForNextAnimationFrameUpdate();
|
||||
}
|
||||
|
||||
|
||||
private void DisposeImpl()
|
||||
{
|
||||
lock (_sync)
|
||||
|
@ -128,7 +129,7 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
return frameTime;
|
||||
}
|
||||
|
||||
private void SkottieDraw(SKCanvas canvas)
|
||||
private void Draw(SKCanvas canvas)
|
||||
{
|
||||
var animation = _animation;
|
||||
if (animation is null)
|
||||
|
@ -158,14 +159,8 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
var dst = new SKRect(0, 0, animation.Size.Width, animation.Size.Height);
|
||||
|
||||
animation.SeekFrameTime(t, ic);
|
||||
|
||||
// Debug.WriteLine($"dst: {dst}, ic.Bounds: {ic.Bounds}");
|
||||
|
||||
canvas.Save();
|
||||
|
||||
animation.Render(canvas, dst);
|
||||
// canvas.DrawRect(ic.Bounds, new SKPaint { Color = SKColors.Magenta, Style = SKPaintStyle.Stroke, StrokeWidth = 1 });
|
||||
|
||||
canvas.Restore();
|
||||
|
||||
ic.Reset();
|
||||
|
@ -187,8 +182,12 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
_lastServerTime = CompositionNow;
|
||||
}
|
||||
|
||||
|
||||
if (_animation is not { } an || _stretch is not { } st || _stretchDirection is not { } sd) return;
|
||||
if (_animation is not { } an
|
||||
|| _stretch is not { } st
|
||||
|| _stretchDirection is not { } sd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var leaseFeature = context.TryGetFeature<ISkiaSharpApiLeaseFeature>();
|
||||
|
@ -231,7 +230,7 @@ internal class LottieCustomVisualHandler : CompositionCustomVisualHandler
|
|||
{
|
||||
return;
|
||||
}
|
||||
SkottieDraw(canvas);
|
||||
Draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Avalonia.Media;
|
||||
|
||||
namespace Avalonia.Skia.Lottie;
|
||||
|
||||
internal record struct LottiePayload(
|
||||
LottieCommand LottieCommand,
|
||||
SkiaSharp.Skottie.Animation? Animation = null,
|
||||
Stretch? Stretch = null,
|
||||
StretchDirection? StretchDirection = null,
|
||||
int? RepeatCount = null);
|
Загрузка…
Ссылка в новой задаче