gpt4 book ai didi

c# - 用波浪动画填充椭圆

转载 作者:IT王子 更新时间:2023-10-29 04:22:28 30 4
gpt4 key购买 nike

我在 Windows Phone 8.1 Silverlight App 和 UWP 中都创建了一个椭圆我想用动画波浪填充它,为此,我关注这个 solution

但它是针对 WPF 的,所以我无法使用像“Visual Brush”这样的控件。

我想用类似于此的波浪填充椭圆(忽略图像中的 50%)-

enter image description here

这是我的省略号

<Ellipse Name="WaveEllipse" Grid.Column="1" Grid.Row="0" VerticalAlignment="Top"
Stroke="{StaticResource PhoneAccentBrush}"
StrokeThickness="4"
Width="225"
Height="225">
</Ellipse>

视觉画笔上有任何替代品吗?主要是想在Windows Phone 8.1 Silverlight中实现,如果WP平台上没有,我会转用UWP

最佳答案

在给你代码之前,先看看下面这个动画 gif,试着理解这个动画是如何创建的。

enter image description here

有道理吧?我们需要做的就是创建一个这样的形状,为其偏移 X(无限)和 Y(水位)设置动画,最后用椭圆剪裁它。

因此,首先您需要使用 Adobe Illustrator 或类似工具来创建此形状。在 AI 中,有一个 Zig Zag 效果(见下面的屏幕截图)非常适合这个。您只需要确保起点与结束点在同一位置,这样当您重复播放动画时,就会感觉它永远不会结束。

enter image description here

UWP 当前缺少的是剪辑非矩形形状的 UIElement 的功能,因此我们必须将其导出为 png(否则我们会将其导出为 svg 并使用 Path 显示它)。

也是同样的原因,裁剪部分需要做大量的工作。就像 Jet Chopper 的回答一样,为了得到一个 surfaceBrush 需要大量的代码!更不用说您还需要手动处理设备丢失和应用程序生命周期。

值得庆幸的是,在创意者更新(即 15063)中,有一个名为 LoadedImageSurface 的新 API,它通过带有几行代码。在我下面的代码示例中,您会看到我使用了这个,这意味着,如果您想支持旧版本的 Windows 10,您需要将其替换为 Jet 的答案中的内容。

代码

想法是创建一个名为 WaveProgressControl 的 UserControl,它封装所有动画逻辑并公开一个名为 Percent 的依赖属性,该属性控制 < em>水位。

WaveProgressControl 控件 - XAML

<UserControl x:Class="WaveProgressControlRepo.WaveProgressControl"
Height="160"
Width="160">

<Grid x:Name="Root">
<Ellipse x:Name="ClippedImageContainer"
Fill="White"
Margin="6" />
<Ellipse x:Name="CircleBorder"
Stroke="#FF0289CD"
StrokeThickness="3" />
<TextBlock Foreground="#FF0289CD"
FontSize="36"
FontWeight="SemiBold"
TextAlignment="Right"
VerticalAlignment="Center"
Width="83"
Margin="0,0,12,0">
<Run Text="{x:Bind Percent, Mode=OneWay}" />
<Run Text="%"
FontSize="22" />
</TextBlock>
</Grid>
</UserControl>

WaveProgressControl 控件 - 代码隐藏

private readonly Compositor _compositor;
private readonly CompositionPropertySet _percentPropertySet;

public WaveProgressControl()
{
InitializeComponent();

_compositor = Window.Current.Compositor;

_percentPropertySet = _compositor.CreatePropertySet();
_percentPropertySet.InsertScalar("Value", 0.0f);

Loaded += OnLoaded;
}

public double Percent
{
get => (double)GetValue(PercentProperty);
set => SetValue(PercentProperty, value);
}
public static readonly DependencyProperty PercentProperty =
DependencyProperty.Register("Percent", typeof(double), typeof(WaveProgressControl),
new PropertyMetadata(0.0d, (s, e) =>
{
var self = (WaveProgressControl)s;
var propertySet = self._percentPropertySet;
propertySet.InsertScalar("Value", Convert.ToSingle(e.NewValue) / 100);
}));

private void OnLoaded(object sender, RoutedEventArgs e)
{
CompositionSurfaceBrush imageSurfaceBrush;

SetupClippedWaveImage();
SetupEndlessWaveAnimationOnXAxis();
SetupExpressionAnimationOnYAxisBasedOnPercentValue();

void SetupClippedWaveImage()
{
// Note LoadedImageSurface is only available in 15063 onward.
var imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri(BaseUri, "/Assets/wave.png"));
imageSurfaceBrush = _compositor.CreateSurfaceBrush(imageSurface);
imageSurfaceBrush.Stretch = CompositionStretch.None;
imageSurfaceBrush.Offset = new Vector2(120, 248);

var maskBrush = _compositor.CreateMaskBrush();
var maskSurfaceBrush = ClippedImageContainer.GetAlphaMask(); // CompositionSurfaceBrush
maskBrush.Mask = maskSurfaceBrush;
maskBrush.Source = imageSurfaceBrush;

var imageVisual = _compositor.CreateSpriteVisual();
imageVisual.RelativeSizeAdjustment = Vector2.One;
ElementCompositionPreview.SetElementChildVisual(ClippedImageContainer, imageVisual);

imageVisual.Brush = maskBrush;
}

void SetupEndlessWaveAnimationOnXAxis()
{
var waveOffsetXAnimation = _compositor.CreateScalarKeyFrameAnimation();
waveOffsetXAnimation.InsertKeyFrame(1.0f, -80.0f, _compositor.CreateLinearEasingFunction());
waveOffsetXAnimation.Duration = TimeSpan.FromSeconds(1);
waveOffsetXAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
imageSurfaceBrush.StartAnimation("Offset.X", waveOffsetXAnimation);
}

void SetupExpressionAnimationOnYAxisBasedOnPercentValue()
{
var waveOffsetYExpressionAnimation = _compositor.CreateExpressionAnimation("Lerp(248.0f, 120.0f, Percent.Value)");
waveOffsetYExpressionAnimation.SetReferenceParameter("Percent", _percentPropertySet);
imageSurfaceBrush.StartAnimation("Offset.Y", waveOffsetYExpressionAnimation);
}
}

主页

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<local:WaveProgressControl x:Name="WaveProgressControl" />

<Slider Grid.Row="1"
Margin="24"
Value="{x:Bind WaveProgressControl.Percent, Mode=TwoWay}" />
</Grid>

我已将所有内容放入此 sample project下面是一个现场演示。享受! :)

enter image description here

关于c# - 用波浪动画填充椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46021277/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com