У меня есть универсальное приложение для 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: Значение x результата матрицы * vector (500, 500), здесь: Colum1 * 500 + Column2
Вы видите, что значения матрицы выглядят хорошо, но при применении преобразования вы получаете этот небольшой прыжок вправо в течение нескольких миллисекунд. Одна из теорий заключалась в том, что область просмотра может измениться, поскольку полоса прокрутки становится видимой. Но это не так. Я также пробовал фиксированные значения здесь, сделал полосы прокрутки видимыми и даже создал собственный шаблон для scrollviewer без полос прокрутки.
Btw: Это перекрестный пост, я также задал здесь вопрос: https://github.com/Microsoft/Win2D/issues/125