平移 canvas 使得点 (x,y) 位于中心
Pan canvas such that Point (x,y) is at the center
我有一个 Canvas
是 WPF,其中包含很多形状和线条。我在 canvas 中加入了缩放和平移功能。我有一个类似搜索的功能,它以 X 和 Y 作为输入,当我请求搜索时,canvas 应该放大到那个点并以 (X,Y) 位置这样的方式翻译 canvas在中心。缩放效果很好,但我无法实现平移。
在 this post 的帮助下,我将以下代码用于 PanBorder.cs。在这里,我想使用 PanToPosition(double x , double y) 进行平移,使中心位于 (X,Y)。
class PanBorder : Border
{
private UIElement child = null;
private Point origin;
private Point start;private TranslateTransform GetTranslateTransform(UIElement element)
{
return (TranslateTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
}
private ScaleTransform GetScaleTransform(UIElement element)
{
return (ScaleTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is ScaleTransform);
}
public override UIElement Child
{
get { return base.Child; }
set
{
if (value != null && value != this.Child)
this.Initialize(value);
base.Child = value;
}
}
public void Initialize(UIElement element)
{
this.child = element;
if (child != null)
{
TransformGroup group = new TransformGroup();
ScaleTransform st = new ScaleTransform();
group.Children.Add(st);
TranslateTransform tt = new TranslateTransform();
group.Children.Add(tt);
child.RenderTransform = group;
child.RenderTransformOrigin = new Point(0.0, 0.0);
this.MouseLeftButtonDown += child_MouseLeftButtonDown;
this.MouseLeftButtonUp += child_MouseLeftButtonUp;
this.MouseMove += child_MouseMove;
}
}
public void Reset()
{
if (child != null)
{
// reset pan
var tt = GetTranslateTransform(child);
tt.X = 0.0;
tt.Y = 0.0;
}
}
public void PanToPosition(double x, double y) {
if (child != null)
{
var tt = GetTranslateTransform(child);
//Pan such that center is at (X,Y)
}
}
#region Child Events
private void child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (child != null)
{
var tt = GetTranslateTransform(child);
start = e.GetPosition(this);
origin = new Point(tt.X, tt.Y);
this.Cursor = Cursors.Hand;
child.CaptureMouse();
}
}
private void child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (child != null)
{
child.ReleaseMouseCapture();
this.Cursor = Cursors.Arrow;
}
}
private void child_MouseMove(object sender, MouseEventArgs e)
{
if (child != null)
{
if (child.IsMouseCaptured)
{
var tt = GetTranslateTransform(child);
Vector v = start - e.GetPosition(this);
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}
}
#endregion
}`
我有以下代码来放大 canvas:
//for zooming control on the window
void window_MouseWheel(object sender, MouseWheelEventArgs e)
{
Point p = e.MouseDevice.GetPosition(canvasWaSNA);
Matrix m = canvasWaSNA.RenderTransform.Value;
if (e.Delta > 0)
m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
当我输入点 (X,Y) 时,我调用了以下函数:
public void moveToPosition(double x, double y) {
resize();
border.PanToPosition(x, y);
Point p = new Point(x, y);
Matrix m = canvasWaSNA.RenderTransform.Value;
m.ScaleAtPrepend(6, 6, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
要调整 canvas 的大小,我有以下代码:
private void resize()
{
Matrix m = canvasWaSNA.RenderTransform.Value;
m.SetIdentity();
canvasWaSNA.RenderTransform = new MatrixTransform(m);
border.Reset();
}
我需要帮助。提前谢谢。
嗯,我终于做到了。我应用了平移点的简单概念,因为我的问题是将 Point(X,Y) 平移到屏幕中心并应用缩放。这是更新后的 PanToPosition 函数:
public void PanToPosition(double x, double y, Point center) {
if (child != null)
{
var tt = GetTranslateTransform(child);
start = new Point(x,y);
Point p = new Point(center.X, center.Y);
origin = new Point(tt.X, tt.Y);
Vector v = start - p;
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}
我称这个函数为:
public void moveToPosition(double x, double y) {
resize();
Point center = new Point(this.Width / 2, this.Height / 2);
border.PanToPosition(x, y, center);
Point p = new Point(x, y);
Matrix m = canvasWaSNA.RenderTransform.Value;
m.ScaleAtPrepend(6, 6, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
这里我把屏幕的中心点和要平移的点都传到了中心。起点是要翻译的点,p 是目的地。因此,我计算了平移比例因子。
我有一个 Canvas
是 WPF,其中包含很多形状和线条。我在 canvas 中加入了缩放和平移功能。我有一个类似搜索的功能,它以 X 和 Y 作为输入,当我请求搜索时,canvas 应该放大到那个点并以 (X,Y) 位置这样的方式翻译 canvas在中心。缩放效果很好,但我无法实现平移。
在 this post 的帮助下,我将以下代码用于 PanBorder.cs。在这里,我想使用 PanToPosition(double x , double y) 进行平移,使中心位于 (X,Y)。
class PanBorder : Border
{
private UIElement child = null;
private Point origin;
private Point start;private TranslateTransform GetTranslateTransform(UIElement element)
{
return (TranslateTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
}
private ScaleTransform GetScaleTransform(UIElement element)
{
return (ScaleTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is ScaleTransform);
}
public override UIElement Child
{
get { return base.Child; }
set
{
if (value != null && value != this.Child)
this.Initialize(value);
base.Child = value;
}
}
public void Initialize(UIElement element)
{
this.child = element;
if (child != null)
{
TransformGroup group = new TransformGroup();
ScaleTransform st = new ScaleTransform();
group.Children.Add(st);
TranslateTransform tt = new TranslateTransform();
group.Children.Add(tt);
child.RenderTransform = group;
child.RenderTransformOrigin = new Point(0.0, 0.0);
this.MouseLeftButtonDown += child_MouseLeftButtonDown;
this.MouseLeftButtonUp += child_MouseLeftButtonUp;
this.MouseMove += child_MouseMove;
}
}
public void Reset()
{
if (child != null)
{
// reset pan
var tt = GetTranslateTransform(child);
tt.X = 0.0;
tt.Y = 0.0;
}
}
public void PanToPosition(double x, double y) {
if (child != null)
{
var tt = GetTranslateTransform(child);
//Pan such that center is at (X,Y)
}
}
#region Child Events
private void child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (child != null)
{
var tt = GetTranslateTransform(child);
start = e.GetPosition(this);
origin = new Point(tt.X, tt.Y);
this.Cursor = Cursors.Hand;
child.CaptureMouse();
}
}
private void child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (child != null)
{
child.ReleaseMouseCapture();
this.Cursor = Cursors.Arrow;
}
}
private void child_MouseMove(object sender, MouseEventArgs e)
{
if (child != null)
{
if (child.IsMouseCaptured)
{
var tt = GetTranslateTransform(child);
Vector v = start - e.GetPosition(this);
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}
}
#endregion
}`
我有以下代码来放大 canvas:
//for zooming control on the window
void window_MouseWheel(object sender, MouseWheelEventArgs e)
{
Point p = e.MouseDevice.GetPosition(canvasWaSNA);
Matrix m = canvasWaSNA.RenderTransform.Value;
if (e.Delta > 0)
m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
当我输入点 (X,Y) 时,我调用了以下函数:
public void moveToPosition(double x, double y) {
resize();
border.PanToPosition(x, y);
Point p = new Point(x, y);
Matrix m = canvasWaSNA.RenderTransform.Value;
m.ScaleAtPrepend(6, 6, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
要调整 canvas 的大小,我有以下代码:
private void resize()
{
Matrix m = canvasWaSNA.RenderTransform.Value;
m.SetIdentity();
canvasWaSNA.RenderTransform = new MatrixTransform(m);
border.Reset();
}
我需要帮助。提前谢谢。
嗯,我终于做到了。我应用了平移点的简单概念,因为我的问题是将 Point(X,Y) 平移到屏幕中心并应用缩放。这是更新后的 PanToPosition 函数:
public void PanToPosition(double x, double y, Point center) {
if (child != null)
{
var tt = GetTranslateTransform(child);
start = new Point(x,y);
Point p = new Point(center.X, center.Y);
origin = new Point(tt.X, tt.Y);
Vector v = start - p;
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}
我称这个函数为:
public void moveToPosition(double x, double y) {
resize();
Point center = new Point(this.Width / 2, this.Height / 2);
border.PanToPosition(x, y, center);
Point p = new Point(x, y);
Matrix m = canvasWaSNA.RenderTransform.Value;
m.ScaleAtPrepend(6, 6, p.X, p.Y);
canvasWaSNA.RenderTransform = new MatrixTransform(m);
}
这里我把屏幕的中心点和要平移的点都传到了中心。起点是要翻译的点,p 是目的地。因此,我计算了平移比例因子。