椭圆绘制WPF动画

发布于 2024-08-25 00:10:16 字数 187 浏览 3 评论 0 原文

我正在开发一个矩形区域的控件,当触发发生时,将在矩形区域中绘制一个椭圆形。该控件将能够承载其他控件,例如文本框、按钮等,因此在触发时将在它们周围绘制圆圈。我希望将圆圈绘制为动画,就像您用笔圈出内部控件一样。

实现这一目标的最佳方法是什么?

我一直在做一些研究,我可以使用 WPF 动画或者我可以使用 GDI+ 来完成任务。想法?

I am developing a control that is a rectangle area and will draw an ellipse in the rectangle area when a trigger occurs. This control will be able to host other controls like, textbox's, buttons, etc. so the circle will be drawn around them when triggered. I want the circle being drawn as an animation like you were circling the inner controls with a pen.

What is the best way to accomplish this?

I've been doing some research and I could use WPF animation or I could use GDI+ to accomplish the tasks. Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝礼 2024-09-01 00:10:16

WPF 动画使这变得极其简单。以下是基本技术:

  1. 使用您喜欢的任何 WPF 功能(形状、路径、几何图形、画笔、绘图、图像等)创建椭圆的视觉外观。这可以是一个简单的椭圆,也可以是图形设计师创建的精美绘图,或者介于两者之间的任何内容。

  2. 应用由一条宽椭圆虚线和一条零长度虚线组成的 OpacityMask。由于短划线的长度为零,因此整个自定义样式的椭圆将不可见。

  3. 以动画方式显示破折号的长度。随着它变长,椭圆的部分将变得不透明(因此它是可见的),直到全部可见。默认情况下,您的椭圆会从 0 平滑地动画到 1,但您可以通过动画参数控制和改变椭圆出现的速率,例如,您可以先慢速开始,然后加速。

解决方案的总体结构

这是基本的 ControlTemplate 结构:

<ControlTemplate TargetType="MyCustomControl">
  <Grid>

    <Rectangle Fill="{StaticResource EllipseVisualAppearance}">
      <Rectangle.OpacityMask>
        <VisualBrush>
          <VisualBrush.Visual>
            <Ellipse
              x:Name="opacityEllipse"
              StrokeDashArray="0 10"
              Stroke="Black" StrokeThickness="0.5"
              Width="1" Height"1" />
          </VisualBrush.Visual>
        </VisualBrush>
      </Rectangle.OpacityMask>
    </Rectangle>

    <ContentPresenter />   <!-- This presents the actual content -->

  </Grid>
</ControlTemplate>

创建椭圆视觉效果

WPF 在表达视觉效果方面非常丰富,因此对于椭圆形来说,天空是无限的。可以看起来像。

使用任何 WPF 绘图技术按照您希望的显示方式准确绘制椭圆。根据您想要从椭圆中获得多少“艺术风格”,您可以做一个简单(且无聊)的描边椭圆或任何任意花哨的东西,例如:

  • 描画一条大致椭圆但不闭合且可能向外展开的路径。
  • 填充由图形设计师创建的路径,该路径开始时就像画笔正在做的一样,并且可能会随着您的绕行而变宽,并以斑点结束。
  • 在 Expression Design(或 Adob​​e Illustrator)中创建矢量绘图,将其转换为 XAML 绘图。
  • 创建位图图像(请注意,与矢量图形相比,位图通常在保真度和性能方面存在劣势)
  • 使用 Expression Blend 在画布上绘制多个形状

这是一个最终简单的椭圆:

<VisualBrush x:Key="EllipseVisualAppearance">
  <VisualBrush.Visual>
    <Ellipse StrokeThickness="0.1" Stroke="Blue" />
  </VisualBrush.Visual>
</VisualBrush>

对椭圆进行动画处理

再次,有一个您可以通过多种方式来实现此目的,具体取决于您希望动画的外观。对于简单的 0 到 360 度动画,您的 DoubleAnimation 可以简单如下:

 <DoubleAnimation
   StoryBoard.TargetName="opacityEllipse"
   StoryBoard.TargetProperty="StrokeDashArray[0]"
   From="0" To="3.1416" Duration="0:0:0.5" />

常数 3.1416 略高于 pi,即直径为 1 的圆的周长。这意味着椭圆在动画结束时将完全可见期间。

替代解决方案

StackOverflow 用户Simon Fox 发布了一个答案,其中包含指向Charles Petzold 的这篇文章,但他的答案消失了几分钟后。估计他删了Petzold 代码显示了使用 PathGeometry 和 ArcSegment 执行此操作的更简单方法。如果您想要的只是一个没有任何装饰的简单椭圆,那么根据他的示例对您的代码进行建模可能是正确的选择。

WPF animation makes this extremely easy. Here is the basic technique:

  1. Create your ellipse's visual appearance using whatever WPF functionality you like (Shapes, Paths, Geometries, Brushes, Drawings, Images, etc). This can be a simple ellipse or a fancy drawing created by your graphics designer, or anything in between.

  2. Apply an OpacityMask consisting of a wide elliptical dashed line with a single zero-length dash. Since the dash is zero-length the entire custom-styled ellipse will be invisible.

  3. Animate the length of the dash. As it gets longer parts of the ellipse will become opaque (so it will be visible) until it is all visible. By default your ellipse will animate smoothly from 0 to 1 but you can control and vary the rate the ellipse appears via the animation parameters, for example you could start slow at first then speed up.

Overall structure of solution

Here is the basic ControlTemplate structure:

<ControlTemplate TargetType="MyCustomControl">
  <Grid>

    <Rectangle Fill="{StaticResource EllipseVisualAppearance}">
      <Rectangle.OpacityMask>
        <VisualBrush>
          <VisualBrush.Visual>
            <Ellipse
              x:Name="opacityEllipse"
              StrokeDashArray="0 10"
              Stroke="Black" StrokeThickness="0.5"
              Width="1" Height"1" />
          </VisualBrush.Visual>
        </VisualBrush>
      </Rectangle.OpacityMask>
    </Rectangle>

    <ContentPresenter />   <!-- This presents the actual content -->

  </Grid>
</ControlTemplate>

Creating your ellipse visual

WPF is incredibly rich at expressing visuals, so the sky is the limit when it comes to what your ellipse can look like.

Draw your ellipse exactly the way you want it to appear using any WPF drawing technique. Depending on how much "artistic style" you want from the ellipse you can do a simple (and boring) stroked ellipse or anything arbitrarily fancy, such as:

  • Stroke a path that roughly an ellipse but not closed and perhaps flared out.
  • Fill a path created by a graphic designer that starts as if a paintbrush were doing it and perhaps gets wider as you go around and ends in a blob.
  • Create a vector drawing in Expression Design (or Adobe Illustrator), convert it to a XAML Drawing.
  • Create a bitmap image (note that in general bitmaps have fidelity and performance disadvantages compared to vector drawings)
  • Draw multiple Shapes on a Canvas using Expression Blend

Here is an ultimately simple ellipse:

<VisualBrush x:Key="EllipseVisualAppearance">
  <VisualBrush.Visual>
    <Ellipse StrokeThickness="0.1" Stroke="Blue" />
  </VisualBrush.Visual>
</VisualBrush>

Animating your ellipse

Again there are a huge variety of ways you can do this, depending on how you want your animation to look. For a simple 0 to 360 animation your DoubleAnimation can be as simple as:

 <DoubleAnimation
   StoryBoard.TargetName="opacityEllipse"
   StoryBoard.TargetProperty="StrokeDashArray[0]"
   From="0" To="3.1416" Duration="0:0:0.5" />

The constant 3.1416 is slightly over pi, which is the circumference of a circle of diameter 1. This means that the ellipse will be fully visible just at the end of the animation duration.

An alternative solution

StackOverflow user Simon Fox had posted an answer containing a link to this article by Charles Petzold, but his answer disappeared a few minutes later. I guess he deleted it. The Petzold code shows a simpler way to do this using PathGeometry and ArcSegment. If all you want is a simple ellipse with no frills, modeling your code on his example is probably the way to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文