gpt4 book ai didi

c# - WPF 形状裁剪

转载 作者:行者123 更新时间:2023-12-02 11:02:41 24 4
gpt4 key购买 nike

我正在尝试以用户控件的形式创建 3..2..1 倒计时。类似于 this 。我的想法是创建两个彼此重叠的矩形,一浅一深,并有一个径向圆作为深色矩形的剪裁器。径向圆将具有动画角度属性,因此它会转动。

我找到了径向圆的实现,并将矩形的 Clip 属性绑定(bind)到圆的 RenderedGeometry 属性上。这是结果:

Problem Screenshot

红色笔画是我的剪刀的形状。这似乎是一种奇怪的剪辑行为,但我有点理解它,但我想知道是否有一种方法可以解决这个问题事实上,我的剪切对象似乎以一种奇怪的方式使用 RenderedGeometry。

编辑1:我正在寻找的效果http://www.youtube.com/watch?v=9FPHTo5V2BQ

最佳答案

下面显示的简单派生 Shape 控件绘制倒计时矩形。您必须设置其Fill(也许还有Stroke)、WidthHeightAngle code> 属性,并且您可以在 0 到 360 之间设置 Angle 动画。

public class CountdownRect : Shape
{
static CountdownRect()
{
WidthProperty.OverrideMetadata(typeof(CountdownRect),
new FrameworkPropertyMetadata((o, e) => ((CountdownRect)o).UpdateGeometry()));

HeightProperty.OverrideMetadata(typeof(CountdownRect),
new FrameworkPropertyMetadata((o, e) => ((CountdownRect)o).UpdateGeometry()));

StrokeLineJoinProperty.OverrideMetadata(typeof(CountdownRect),
new FrameworkPropertyMetadata(PenLineJoin.Round));
}

public static readonly DependencyProperty AngleProperty =
DependencyProperty.Register("Angle", typeof(double), typeof(CountdownRect),
new FrameworkPropertyMetadata((o, e) => ((CountdownRect)o).UpdateGeometry()));

public double Angle
{
get { return (double)GetValue(AngleProperty); }
set { SetValue(AngleProperty, value); }
}

private readonly StreamGeometry geometry = new StreamGeometry();

protected override Geometry DefiningGeometry
{
get { return geometry; }
}

private void UpdateGeometry()
{
if (!double.IsNaN(Width) && !double.IsNaN(Height))
{
var angle = ((Angle % 360d) + 360d) % 360d;
var margin = StrokeThickness / 2d;
var p0 = new Point(margin, margin);
var p1 = new Point(Width - margin, margin);
var p2 = new Point(Width - margin, Height - margin);
var p3 = new Point(margin, Height - margin);

using (var context = geometry.Open())
{
if (angle == 0d)
{
context.BeginFigure(p0, true, true);
context.LineTo(p1, true, false);
context.LineTo(p2, true, false);
context.LineTo(p3, true, false);
}
else
{
var x = p2.X / 2d;
var y = p2.Y / 2d;
var a = Math.Atan2(x, y) / Math.PI * 180d;
var t = Math.Tan(angle * Math.PI / 180d);

context.BeginFigure(new Point(x, y), true, true);

if (angle < a)
{
context.LineTo(new Point(x + y * t, p0.Y), true, false);
context.LineTo(p1, true, false);
context.LineTo(p2, true, false);
context.LineTo(p3, true, false);
context.LineTo(p0, true, false);
}
else if (angle < 180d - a)
{
context.LineTo(new Point(p2.X, y - x / t), true, false);
context.LineTo(p2, true, false);
context.LineTo(p3, true, false);
context.LineTo(p0, true, false);
}
else if (angle < 180d + a)
{
context.LineTo(new Point(x - y * t, p2.Y), true, false);
context.LineTo(p3, true, false);
context.LineTo(p0, true, false);
}
else if (angle < 360d - a)
{
context.LineTo(new Point(p0.X, y + x / t), true, false);
context.LineTo(p0, true, false);
}
else
{
context.LineTo(new Point(x + y * t, p0.Y), true, false);
}

context.LineTo(new Point(x, p0.Y), true, false);
}
}
}
}
}

关于c# - WPF 形状裁剪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15838426/

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