Skip to content

Commit

Permalink
feat: Added DoubleAnimation, DoubleAnimationUsingKeyFrames on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Apr 10, 2020
1 parent 9a05b80 commit 3eea4b2
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/Uno.UI/Media/NativeRenderTransformAdapter.iOSmacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ partial void Apply(bool isSizeChanged, bool isOriginChanged)
if (Transform.IsAnimating)
{
// While animating the transform, we let the Animator apply the transform by itself, so do not update the Transform
#if __IOS__
#if __IOS__ || __MACOS__
if (!_wasAnimating)
{
// At the beginning of the animation make sure we disable all properties of the transform
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ internal class FloatValueAnimator : IValueAnimator
private const int FrameRate = 50;

private long _numberOfFrames;
#if __IOS__
private CADisplayLink _displayLink;
#else
private NSTimer _timer;
#endif

private double _startTime = 0;

private bool _isDisposed;
Expand Down Expand Up @@ -52,23 +57,49 @@ public void Start()
PrebuildFrames();//Preload as much of the animation as possible
}

IsRunning = true;
IsRunning = true;

_startTime = 0;// Start time will be set if it is equal to zero

if (!_isAttachedToLooper)
{
#if __IOS__
//http://www.bigspaceship.com/ios-animation-intervals/
_displayLink = CADisplayLink.Create(OnFrame);//OnFrame is called when an animation frame is ready

//Need to attach the _displayLink to the MainLoop (uiThread) so that the call back will be called on the UI thread
//Default == normal UI updates
_displayLink.AddToRunLoop(NSRunLoop.Main, NSRunLoopMode.Default);
//UITracking == updates during scrolling
_displayLink.AddToRunLoop(NSRunLoop.Main, NSRunLoopMode.UITracking);
_displayLink.AddToRunLoop(NSRunLoop.Main, NSRunLoopMode.UITracking);
#else
ScheduleTimer();
#endif
_isAttachedToLooper = true;
}
}

#if __MACOS__
private void ScheduleTimer()
{
if (_timer?.IsValid == true) return;
UnscheduleTimer();
_timer = NSTimer.CreateRepeatingScheduledTimer(0.001, OnTimerTick);
}

private void UnscheduleTimer()
{
_timer?.Invalidate();
_timer?.Dispose();
_timer = null;
}

private void OnTimerTick(NSTimer obj)
{
OnFrame();
}
#endif

/// <summary>
/// Precalculates the frame values.
/// </summary>
Expand Down Expand Up @@ -109,8 +140,11 @@ private void OnFrame()
{
return;
}

#if __IOS__
var currentTime = _displayLink.Timestamp; // current time in seconds
#else
var currentTime = NSProcessInfo.ProcessInfo.SystemUptime;
#endif

if (_startTime == 0)
{ // if start time is not set, set it
Expand All @@ -135,7 +169,7 @@ private void OnFrame()

if (delta < 0)
{ // Start Delay can cause this - wait till the start delay is spent before continuing
return;
return;
}

CurrentPlayTime = (long)delta; //Update play time
Expand Down Expand Up @@ -186,10 +220,12 @@ private void ReleaseDisplayLink()
{
if (_isAttachedToLooper)
{
#if __IOS__
//Detach the _displayLink to the MainLoop (uiThread).
_displayLink?.RemoveFromRunLoop(NSRunLoop.Main, NSRunLoop.NSDefaultRunLoopMode);//detaches from the UI thread
_displayLink?.RemoveFromRunLoop(NSRunLoop.Main, NSRunLoop.UITrackingRunLoopMode);
_displayLink = null;
#endif
_isAttachedToLooper = false;
}
}
Expand All @@ -214,6 +250,7 @@ public void SetEasingFunction(IEasingFunction easingFunction)

public long StartDelay { get; set; }

#if __IOS__
public bool IsRunning
{
get { return !(_displayLink?.Paused ?? false); }
Expand All @@ -225,6 +262,26 @@ private set
}
}
}
#else
public bool IsRunning
{
get => _timer?.IsValid ?? false;
private set
{
if (_timer != null)
{
if (value && !_timer.IsValid)
{
ScheduleTimer();
}
else
{
UnscheduleTimer();
}
}
}
}
#endif

public long CurrentPlayTime { get; set; }

Expand All @@ -240,7 +297,11 @@ public void Dispose()
AnimationCancel = null;

Stop();
#if __IOS__
_displayLink?.Dispose();
#else
_timer?.Dispose();
#endif
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
using System.Text;
using Windows.Foundation;
using Uno.UI.DataBinding;
#if __IOS__
using UIKit;
using _View = UIKit.UIView;
#else
using AppKit;
using _View = AppKit.NSView;
#endif
using CoreGraphics;
using Foundation;
using CoreAnimation;
Expand Down Expand Up @@ -33,7 +39,7 @@ internal class GPUFloatValueAnimator : IValueAnimator
private IEasingFunction _easingFunction;
private bool _isDisposed;

#region PropertyNameConstants
#region PropertyNameConstants
private const string TranslateTransformX = "TranslateTransform.X";
private const string TranslateTransformXWithNamespace = "Windows.UI.Xaml.Media:TranslateTransform.X";
private const string TranslateTransformY = "TranslateTransform.Y";
Expand Down Expand Up @@ -66,7 +72,7 @@ internal class GPUFloatValueAnimator : IValueAnimator
private const string CompositeTransformSkewXWithNamespace = "Windows.UI.Xaml.Media:CompositeTransform.SkewX";
private const string CompositeTransformSkewY = "CompositeTransform.SkewY";
private const string CompositeTransformSkewYWithNamespace = "Windows.UI.Xaml.Media:CompositeTransform.SkewY";
#endregion
#endregion

internal static Point GetAnchorForAnimation(Transform transform, Point relativeOrigin, Size viewSize)
{
Expand Down Expand Up @@ -135,7 +141,7 @@ private void InitializeCoreAnimation()
var animatedItem = _bindingPath.LastOrDefault();
switch (animatedItem.DataContext)
{
case UIView view when animatedItem.PropertyName.EndsWith("Opacity"):
case _View view when animatedItem.PropertyName.EndsWith("Opacity"):
_coreAnimation = InitializeOpacityCoreAnimation(view);
return;

Expand Down Expand Up @@ -235,8 +241,8 @@ public void SetEasingFunction(IEasingFunction easingFunction)
_valueAnimator.SetEasingFunction(easingFunction);
}

#region coreAnimationInitializers
private UnoCoreAnimation InitializeOpacityCoreAnimation(UIView view)
#region coreAnimationInitializers
private UnoCoreAnimation InitializeOpacityCoreAnimation(_View view)
{
return CreateCoreAnimation(view, "opacity", value => new NSNumber(value));
}
Expand Down Expand Up @@ -297,7 +303,7 @@ private UnoCoreAnimation InitializeScaleCoreAnimation(ScaleTransform transform,
private UnoCoreAnimation InitializeSkewCoreAnimation(SkewTransform transform, IBindingItem animatedItem)
{
// We need to review this. This won't play along if other transforms are happening at the same time since we are animating the whole transform
UIView view = transform.View;
_View view = transform.View;

if (animatedItem.PropertyName.Equals("AngleX")
|| animatedItem.PropertyName.Equals(SkewTransformAngleX)
Expand Down Expand Up @@ -363,7 +369,7 @@ private UnoCoreAnimation InitializeCompositeCoreAnimation(CompositeTransform tra
throw new NotSupportedException(__notSupportedProperty);
}
}
#endregion
#endregion

private UnoCoreAnimation CreateCoreAnimation(
Transform transform,
Expand All @@ -372,7 +378,7 @@ private UnoCoreAnimation CreateCoreAnimation(
=> CreateCoreAnimation(transform.View, property, nsValueConversion, transform.StartAnimation, transform.EndAnimation);

private UnoCoreAnimation CreateCoreAnimation(
UIView view,
_View view,
string property,
Func<float, NSValue> nsValueConversion,
Action prepareAnimation = null,
Expand Down
6 changes: 3 additions & 3 deletions src/Uno.UI/UI/Xaml/Media/Animation/DoubleAnimation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ private void OnEnd()

if (FillBehavior == FillBehavior.HoldEnd)//Two types of fill behaviors : HoldEnd - Keep displaying the last frame
{
#if __IOS__
// iOS: Here we make sure that the final frame is applied properly (it may have been skipped by animator)
#if __IOS__ || __MACOS__
// iOS && macOS: Here we make sure that the final frame is applied properly (it may have been skipped by animator)
// Note: The value is applied using the "Animations" precedence, which means that the user won't be able to alter
// it from application code. Instead we should set the value using a lower precedence
// (possibly "Local" with PropertyInfo.SetLocalValue(ComputeToValue())) but we must keep the
Expand Down Expand Up @@ -383,7 +383,7 @@ private void OnAnimatorCancelled(object sender, EventArgs e)
// value in order to support deactivation scenarios.
State = TimelineState.Stopped;

#if XAMARIN_IOS
#if XAMARIN_IOS || __MACOS__
_startingValue = null;

// On Android, AnimationEnd is always called after AnimationCancel. We don't unset _startingValue yet to be able to calculate
Expand Down
16 changes: 0 additions & 16 deletions src/Uno.UI/UI/Xaml/Media/Animation/DoubleAnimation.macOS.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ protected override void Dispose(bool disposing)
partial void UseHardware();
partial void HoldValue();

#if NET461 || __MACOS__
#if NET461
private bool ReportEachFrame() => true;
#endif
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if __IOS__
using CoreAnimation;
using CoreAnimation;
using Foundation;
using Uno.Extensions;
using Uno.Logging;
Expand All @@ -8,7 +7,11 @@
using System.Diagnostics;
using System.Text;
using System.Threading;
#if __IOS__
using UIKit;
#else
using AppKit;
#endif

namespace Windows.UI.Composition
{
Expand Down Expand Up @@ -303,4 +306,3 @@ public void Dispose()
}
}
}
#endif

0 comments on commit 3eea4b2

Please sign in to comment.