在我的 .net Maui 应用程序中,我想在画布上绘制一个脉动的圆圈。我尝试过每秒使图形视图无效 15 次(以达到 15 FPS)。然而,由于画布比这个脉动圆圈大得多,因此这种方法非常滞后,我理解。
有什么方法可以只重新绘制圆圈所在的区域,或者将其放在单独的图层上并且只重新绘制它?
或者还有其他方法可以在画布上制作这样的动画吗?
可绘制:
public void Draw(ICanvas canvas, RectF dirtyRect)
{
// Draw the image background.
if (_image != null)
{
canvas.DrawImage(_image, Padding + _translationX, Padding + _translationY, _width, _height);
}
// Draw other stuff
// Draw pulsating circle
canvas.DrawCircle(_x, _y, _radius);
canvas.FillColor = Colors.Red;
canvas.FillCircle(_x, _y, _radius);
var radiusStep = dirtyRect.Width / 15;
_step++;
if (_step > 15)
{
_step = 1;
}
canvas.DrawCircle(_x, _y, radiusStep * _step);
}
每个圆圈画一次。较大的放在前面。无需重新绘制圆圈,只需切换较大的圆圈是否透明即可。
每次无效时,画布都会被擦除干净,因此可以根据您的逻辑按照您想要的顺序重新绘制所有内容。
制作脉冲对象的一种方法是从 GraphicView 开始。您可以放置动画来控制脉冲。
internal async Task AnimateRippleEffect()
{
float start = 0;
float end = 1;
_animationManager?.Add(new Microsoft.Maui.Animations.Animation(callback: (progress) =>
{
_drawable.AnimationPercent = start.Lerp(end, progress);
Invalidate();
}, duration: 0.4, easing: Easing.SinInOut,
finished: () =>
{
_drawable.AnimationPercent = 0;
}));
await Task.CompletedTask;
}
在你的Drawable中你放了这样的东西
private double _animationPercent;
public double AnimationPercent
{
get => _animationPercent;
set => _animationPercent = value;
}
public void Draw(ICanvas canvas, RectF dirtyRect)
{
var center = new PointF((float)dirtyRect.Width / 2, (float)dirtyRect.Height / 2);
canvas.SaveState();
canvas.FillColor = Colors.Red.WithAlpha(0.75f * (1 - (float)_animationPercent));
canvas.Alpha = 0.55f;
float minimumRippleEffectSize = 0.0f;
var rippleEffectSize = minimumRippleEffectSize.Lerp(dirtyRect.Width * 0.65f, _animationPercent);
canvas.FillCircle((float)center.X, (float)center.Y, rippleEffectSize);
canvas.RestoreState();
}
我的repo中有脉动/波纹效果,您可以查看更完整的代码示例。您还可以找到将 MAUI Graphics 用于 2D 和 3D 的其他方法。