WPF画导航箭头,始终指向鼠标位置
界面:
<Canvas x:Name="container"> <Viewbox x:Name="player" Width="50" Height="50" RenderTransformOrigin="0.5,0.5"> <Viewbox.RenderTransform> <TransformGroup> <RotateTransform Angle="0"/> </TransformGroup> </Viewbox.RenderTransform> <Path Fill="DodgerBlue" Data="M0,10 5,0 10,10 5,8" VerticalAlignment="Center" HorizontalAlignment="Center"></Path> </Viewbox> </Canvas>
初始位置在窗口中央:
Point center; private void MainWindow_Loaded(object sender, RoutedEventArgs e) { Point p = new Point((this.ActualWidth - player.ActualWidth) / 2, (this.ActualHeight - player.ActualHeight) / 2); center = new Point(p.X + player.ActualWidth / 2, p.Y + player.ActualHeight / 2); Canvas.SetLeft(player, p.X); Canvas.SetTop(player, p.Y); }
获取鼠标坐标,并计算旋转角度:
protected override void OnPreviewMouseMove(MouseEventArgs e) { base.OnPreviewMouseMove(e); Point p = e.GetPosition(container); Point p1 = new Point(p.X - center.X, p.Y - center.Y); SetAngle(p1); } void SetAngle(Point o) { var tran = player.RenderTransform.GetTransform<RotateTransform>(); var atan = System.Math.Atan(o.X / o.Y); if (o.X == 0d) { if (o.Y > 0) atan = System.Math.PI; } else if (o.Y == 0) { atan = o.X >= 0 ? System.Math.PI / 2 : -System.Math.PI / 2; } else if (o.X > 0) { if (o.Y < 0) atan = System.Math.Atan(o.X / -o.Y); else atan = System.Math.PI - System.Math.Atan(o.X / o.Y); } else { if (o.Y < 0) atan = System.Math.Atan(o.X / -o.Y); else atan = System.Math.PI + System.Math.Atan(-o.X / o.Y); } tran!.Angle = Math.RadianToAngle(atan); }
帮助类:
public static class Math { /// <summary> /// 弧度转角度 /// </summary> /// <param name="radian"></param> /// <returns></returns> public static double RadianToAngle(double radian) { return 180 / System.Math.PI * radian; } public static double Length(Point p1, Point p2) { double x = p1.X - p2.X; double y = p1.Y - p2.Y; return System.Math.Sqrt(x * x + y * y); } } public static class WPFExtension { public static T? GetTransform<T>(this Transform transform) where T : Transform { if (transform == null) return null; if(transform is TransformGroup group) { foreach (var item in group.Children) { if(item is T) return (T)item; } } return (T)transform; } }