Pixiview/Gallery.Android/Renderers/AppShellSection/AppColorChangeRevealDrawable.cs
2021-08-04 10:27:41 +08:00

99 lines
2.5 KiB
C#

using Android.Animation;
using Android.Graphics;
using Android.Graphics.Drawables;
using System;
using AColor = Android.Graphics.Color;
namespace Gallery.Droid.Renderers.AppShellSection
{
public class AppColorChangeRevealDrawable : AnimationDrawable
{
readonly Point _center;
float _progress;
bool _disposed;
ValueAnimator _animator;
internal AColor StartColor { get; }
internal AColor EndColor { get; }
public AppColorChangeRevealDrawable(AColor startColor, AColor endColor, Point center) : base()
{
StartColor = startColor;
EndColor = endColor;
if (StartColor != EndColor)
{
_animator = ValueAnimator.OfFloat(0, 1);
_animator.SetInterpolator(new Android.Views.Animations.DecelerateInterpolator());
_animator.SetDuration(500);
_animator.Update += OnUpdate;
_animator.Start();
_center = center;
}
else
{
_progress = 1;
}
}
public override void Draw(Canvas canvas)
{
if (_disposed)
return;
if (_progress == 1)
{
canvas.DrawColor(EndColor);
return;
}
canvas.DrawColor(StartColor);
var bounds = Bounds;
float centerX = _center.X;
float centerY = _center.Y;
float width = bounds.Width();
float distanceFromCenter = Math.Abs(width / 2 - _center.X);
float radius = (width / 2 + distanceFromCenter) * 1.1f;
var paint = new Paint
{
Color = EndColor
};
canvas.DrawCircle(centerX, centerY, radius * _progress, paint);
}
void OnUpdate(object sender, ValueAnimator.AnimatorUpdateEventArgs e)
{
_progress = (float)e.Animation.AnimatedValue;
InvalidateSelf();
}
protected override void Dispose(bool disposing)
{
if (_disposed)
return;
_disposed = true;
if (disposing)
{
if (_animator != null)
{
_animator.Update -= OnUpdate;
_animator.Cancel();
_animator.Dispose();
_animator = null;
}
}
base.Dispose(disposing);
}
}
}