C# 通过设置输入点和输出点在WPF中动态缩放画布
我正在使用canvas元素在WPF中绘制程序。我想要实现的是一个带有可拖动端点的滚动条。Adobe的After Effects视频编辑软件中提供了此类滚动条的示例 这种滚动条的基本功能是,它能够滚动比其容器大的内容,但可以拖动左右端点来动态更改内容的比例 我在绘图程序中实现了类似的滚动条;用户应该能够在输入和输出点(画布中的矩形)周围拖动,绘图画布应该通过缩放到所需的范围来响应这一点。 我需要这方面的信息:C# 通过设置输入点和输出点在WPF中动态缩放画布,c#,wpf,C#,Wpf,我正在使用canvas元素在WPF中绘制程序。我想要实现的是一个带有可拖动端点的滚动条。Adobe的After Effects视频编辑软件中提供了此类滚动条的示例 这种滚动条的基本功能是,它能够滚动比其容器大的内容,但可以拖动左右端点来动态更改内容的比例 我在绘图程序中实现了类似的滚动条;用户应该能够在输入和输出点(画布中的矩形)周围拖动,绘图画布应该通过缩放到所需的范围来响应这一点。 我需要这方面的信息: 总绘图的宽度(绘图点的数量) 容器宽度(静态,600px) 输入和输出点相对于滚动条画
- 总绘图的宽度(绘图点的数量)
- 容器宽度(静态,600px)
- 输入和输出点相对于滚动条画布总宽度的百分比
我应该如何缩放画布(绘图)以适应两个边界 所以,经过一番努力,我找到了解决这个问题的正确算法。我将在下面发布resetTransform函数的调整版本:
//Reset graph transform
public void resetTransform(Boolean useSlider = false)
{
double yscale = plot.Height / view.YMAX; //YMAX is maximum plot value received
double xscale = plot.Width / view.XMAX; //XMAX is total ammount of plotted points
Matrix m = new Matrix(1, 0, 0, 1, 0, 0);
if (useSlider)
{
double maxVal = zoomBar.ActualWidth - outPoint.Width;
double outP = Canvas.GetLeft(outPoint); //points position relative to the scrollbar
double inP = Canvas.GetLeft(inPoint);
double delta = (outP-inP);
double factor = (maxVal/delta) * xscale;
anchorOut = (outP / maxVal) * view.XMAX; //Define anchorpoint coordinates
anchorIn = (inP / maxVal) * view.XMAX;
double center = (anchorOut +anchorIn)/2; //Define centerpoint
m.Translate(-anchorIn, 0); //Move graph to inpoint
m.ScaleAt(factor, -yscale,0,0); //scale around the inpoint, with a factor so that outpoint is plot.Height(=600px) further away
m.Translate(0, plot.Height); //to compensate the flipped graph, move it back down
}
scale = new ScaleTransform(m.M11, m.M22, 0, 0); //save scale factors in a scaletransform for reference
signals.scaleSignalStrokes(scale); //Scale the plotlines to compensate for canvas scaling
MatrixTransform matrixTrans = new MatrixTransform(m); //Create matrixtransform
plot.RenderTransform = matrixTrans; //Apply to canvas
}
因此,与其围绕中心点进行缩放,我应该首先平移图像,然后使用因子围绕画布的原点进行缩放。这意味着画布的另一面正好是plot.Height像素(添加了一些缩放)
现在一切似乎都很好,但因为我使用自定义控件(画布中的可拖动矩形),我注意到这些矩形并不总是触发mouse事件
因为它超出了这个问题的范围,我在中进一步描述了这个问题,所以经过一些努力,我找到了解决这个问题的正确算法。我将在下面发布resetTransform函数的调整版本:
//Reset graph transform
public void resetTransform(Boolean useSlider = false)
{
double yscale = plot.Height / view.YMAX; //YMAX is maximum plot value received
double xscale = plot.Width / view.XMAX; //XMAX is total ammount of plotted points
Matrix m = new Matrix(1, 0, 0, 1, 0, 0);
if (useSlider)
{
double maxVal = zoomBar.ActualWidth - outPoint.Width;
double outP = Canvas.GetLeft(outPoint); //points position relative to the scrollbar
double inP = Canvas.GetLeft(inPoint);
double delta = (outP-inP);
double factor = (maxVal/delta) * xscale;
anchorOut = (outP / maxVal) * view.XMAX; //Define anchorpoint coordinates
anchorIn = (inP / maxVal) * view.XMAX;
double center = (anchorOut +anchorIn)/2; //Define centerpoint
m.Translate(-anchorIn, 0); //Move graph to inpoint
m.ScaleAt(factor, -yscale,0,0); //scale around the inpoint, with a factor so that outpoint is plot.Height(=600px) further away
m.Translate(0, plot.Height); //to compensate the flipped graph, move it back down
}
scale = new ScaleTransform(m.M11, m.M22, 0, 0); //save scale factors in a scaletransform for reference
signals.scaleSignalStrokes(scale); //Scale the plotlines to compensate for canvas scaling
MatrixTransform matrixTrans = new MatrixTransform(m); //Create matrixtransform
plot.RenderTransform = matrixTrans; //Apply to canvas
}
因此,与其围绕中心点进行缩放,我应该首先平移图像,然后使用因子围绕画布的原点进行缩放。这意味着画布的另一面正好是plot.Height像素(添加了一些缩放)
现在一切似乎都很好,但因为我使用自定义控件(画布中的可拖动矩形),我注意到这些矩形并不总是触发mouse事件
因为它不在这个问题的范围之内,我已经在中进一步描述了这个问题,可以使用第三方控制吗?telerik RadTimeBar和RadTimeLine有这种行为。啊,我明白了,这些控件正是我需要的,但它们是商业工具。我希望自己编写解决方案,从错误中吸取教训,并将项目放在github上,因此上述工具在这方面并没有真正帮助我。除非他们在网站上的某个地方向我展示底层代码,否则可以使用第三方控制吗?telerik RadTimeBar和RadTimeLine有这种行为。啊,我明白了,这些控件正是我需要的,但它们是商业工具。我希望自己编写解决方案,从错误中吸取教训,并将项目放在github上,因此上述工具在这方面并没有真正帮助我。除非他们在网站上的某个地方向我展示底层代码?