我有一个Windows通用应用程序,我正在使用DirectX渲染场景。我想使用Scrollviewer,因此我在Scrollviewer后面渲染我的场景,并希望根据Scrollviewer计算场景变换。它到目前为止工作正常,特别是翻译和滚动。但是当我放大时,场景会在两种特殊情况下跳跃:
或多或少我使用以下代码:
float zoom = scrollViewer.ZoomFactor;
float inverseZoom = 1f / scrollViewer.ZoomFactor;
float scaledContentW = Document.Size.X * scrollViewer.ZoomFactor;
float scaledContentH = Document.Size.Y * scrollViewer.ZoomFactor;
float translateX;
float translateY;
if (scaledContentW < scrollViewer.ViewportWidth)
{
translateX = ((float)scrollViewer.ViewportWidth * inverseZoom - Document.Size.X) * 0.5f;
}
else
{
translateX = -inverseZoom * (float)scrollViewer.HorizontalOffset;
}
if (scaledContentH < scrollViewer.ViewportHeight)
{
translateY = ((float)scrollViewer.ViewportHeight * inverseZoom - Document.Size.Y) * 0.5f;
}
else
{
translateY = -inverseZoom * (float)scrollViewer.VerticalOffset;
}
float visibleX = inverseZoom * (float)scrollViewer.HorizontalOffset;
float visibleY = inverseZoom * (float)scrollViewer.VerticalOffset; ;
float visibleW = Math.Min(Document.Size.X, inverseZoom * (float)scrollViewer.ViewportWidth);
float visibleH = Math.Min(Document.Size.Y, inverseZoom * (float)scrollViewer.ViewportHeight);
Rect2 visibleRect = new Rect2(visibleX, visibleY, visibleW, visibleH);
transform =
Matrix3x2.CreateTranslation(
translateX,
translateY) *
Matrix3x2.CreateScale(zoom);
您可以在此处获取示例:https://github.com/SebastianStehle/Win2DZoomTest
为了确保我的眼睛没有被打破,我正在放大并将翻译和缩放值写入文件。你可以在这里看到它:
https://www.dropbox.com/s/9ak6ohg4zb1mnxa/Test.png?dl=0
列的含义如下:
第1列:转换矩阵的计算缩放值(M11)= ScrollViewer.ZoomFactor 第2列:矩阵的计算x偏移量(见上文) 第3列:矩阵*向量(500,500)结果的x值,此处:Colum1 * 500 + Column2
你看,矩阵值看起来不错,但是在应用转换时,你可以向右跳几毫秒。一种理论认为,视口可能会发生变化,因为滚动条变得可见。但这种情况并非如此。我还尝试了固定值,使滚动条可见,甚至为滚动查看器创建了一个自定义模板,根本没有滚动条。
顺便说一句:这是一篇交叉帖子,我在这里也问过这个问题:https://github.com/Microsoft/Win2D/issues/125
答案 0 :(得分:6)
您会看到此行为,因为当您缩放大于product
的大小时,会移动缩放中心点。要解决此问题,您只需订阅public class FrameArray {
private String frameInventory;
private int[] units;
private double[] price;
private double product;
public FrameArray( String frame, int[] unitsArray, double[] priceArray, double product )
{
frameInventory = frame;
units = unitsArray;
price = priceArray;
product = weightedProduct(unitsArray, priceArray);
}
public void setFrameInventory( String frame )
{
frameInventory = frame;
}
public String getFrameInventory()
{
return frameInventory;
}
public double weightedProduct(int[] unitsArray, double[] priceArray){
double value = 0;
double product = 0;
for(int i = 0; i < unitsArray.length; i++){
value = (double) (unitsArray[i] * priceArray[i]);
product = product + value;}
return product;
}
public void displayMessage()
{
System.out.printf( "Current frame inventory\n\n");
}
public void processInventory()
{
outputInventory();
}
public void outputInventory()
{
System.out.println( "Inventory levels:\n");
System.out.printf( "Style Qty Price Value\n\n");
for (int frame = 0; frame < price.length; frame++)
System.out.printf( "Frame %2d: %3d %5.2f %5.2f\n",
frame + 1, units[ frame ], price[ frame], product );
}
}
的{{1}}事件,并在处理程序内部手动将其内容保留在中心。
ScrollViewer
这应修复来自 Win2D 的两个绘制ScrollViewer
的跳跃运动。
为了证明我的观点,当内容大小超过大小时,跳跃行为很可能是由于不正常的翻译x 和/或 y 值的变化。 LayoutUpdated
。所以我写了一些代码来在屏幕上记录这些值,如下所示 -
private void ScrollViewer_LayoutUpdated(object sender, object e)
{
this.ScrollViewer.ChangeView(this.ScrollViewer.ScrollableWidth / 2, this.ScrollViewer.ScrollableHeight / 2, this.ScrollViewer.ZoomFactor, true);
}
现在查看上图中的数字。我做的是我尝试放大直到发生跳跃的场景。查看突出显示的翻译y 值?它略大于之前的价值,这与下降趋势相反。
因此,要解决此问题,您需要能够跳过由Rectangle
引起的这些异常值。