【发布时间】:2012-10-17 07:00:37
【问题描述】:
我正在使用画布元素在 WPF 中绘制程序。我想要实现的是一个带有可拖动端点的滚动条。 Adobe 的 After Effects 视频编辑软件中就是这类滚动条的示例。
这种滚动条的基本功能是它能够滚动比它的容器更大的内容,但左右端点都可以拖动以动态改变内容的比例。
我在绘图程序中实现了一个类似的滚动条;用户应该能够拖动入点和出点(画布中的矩形),并且绘图画布应该通过缩放到所需范围来对此做出响应。 为此我需要的信息:
- 总图的宽度(图点的数量)
- 容器的宽度(静态,600px)
- 入点和出点相对于滚动条画布总宽度的百分比
根据这些信息,我创建了一个 MatrixTransform,使用 ScaleAt() 方法缩放容器内的绘图画布,使其与下方滚动条中的入点和出点匹配。为此,我使用了以下代码。 resetTransform 每秒调用 FPS 次以跟上传入的数据,并且 XMAX 和 YMAX 在其他地方更新以反映这一点。
public void resetTransform(Boolean useSlider = false)
{
//Add transformgroup to plot
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 center = (((outP + inP) / 2) / maxVal) * plot.ActualWidth;
double delta = (outP-inP);
double factor = (maxVal/delta) * xscale;
double mappedinP = (inP / maxVal) * view.XMAX;
double anchorOut = (outP / maxVal) * view.XMAX;
double anchorIn = (inP / maxVal) * view.XMAX;
m.ScaleAt(factor, -yscale,center,0); //scale around the center point,
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
}
期望:当绘图点的数量随着时间的推移而增长时,一切都应该正常工作,并且绘制的图形会很好地缩放。现实:移动点时图形会缩放,但不具有代表性;此外,添加的情节点越多,整个画布向右移动的越多,我似乎对转换的控制就越少。现在的算法可能是错误的方法来获得我需要的结果,但我花了很多时间思考如何正确地做到这一点。
更新
我上传了一段视频,以便更清楚地了解互动。在视频中,您可以清楚地看到画布向右移动。 Screencapture video
我应该如何缩放画布(绘图)以适应两个边界?
【问题讨论】:
-
可以使用第三方控件吗? telerik RadTimeBar 和 RadTimeLine 有这种行为。
-
啊,我明白了,这些控件完全符合我的需要,但它们是商业工具。我想自己编写解决方案以从我的错误中学习并将项目放在 github 上,所以从这个意义上说,上述工具并不能真正帮助我。除非他们在他们网站的某个地方向我展示底层代码?