Silverlight 3 - ScaleTransform или другой метод для увеличения холста?
-
06-07-2019 - |
Вопрос
Мне нужно иметь возможность увеличивать и уменьшать масштаб холста с помощью колесика мыши. Я успешно настроил обработчики колесика мыши и в настоящее время использую ScaleTransform для применения масштабирования; однако масштабирование не выполняется «интуитивно» путь. Р>
Я пытаюсь использовать тот же стиль " масштабирования " как вы можете видеть в MultiScaleImage, Google Maps / Earth или Adobe Acrobat Reader - но НЕ с изображением, с элементом управления. Переход не должен быть «гладким» или анимированные (если это не более простой подход), но функциональность должна быть такой же. Р>
Любые мысли или идеи будут высоко оценены и заранее благодарны!
Изменить. Мне удалось "сгладить" увеличение с использованием анимации:
<Canvas.Resources>
<Storyboard x:Name="ZoomStoryboard">
<DoubleAnimation x:Name="ZoomAnimationX"
Storyboard.TargetName="Workspace"
Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleX"
Duration="0:0:0.2"/>
<DoubleAnimation x:Name="ZoomAnimationY"
Storyboard.TargetName="Workspace"
Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleY"
Duration="0:0:0.2"/>
</Storyboard>
</Canvas.Resources>
со следующим кодом:
_Zoom += (args.Delta / 7);
if (_Zoom < 0.15)
_Zoom = 0.15;
ZoomAnimationX.To = _Zoom;
ZoomAnimationY.To = _Zoom;
ZoomStoryboard.Begin();
ZoomScale.Text = _Zoom.ToString("0.00") + "x";
_PreviousMousePosition = _CurrentMousePosition
Однако по-прежнему возникает проблема, связанная с уменьшением масштаба в верхнем левом углу, в отличие от таких сайтов, как Google Maps, где масштабирование "вокруг". мышь. Р>
Решение
Вам необходимо использовать средневзвешенное значение в качестве центра масштабирования в зависимости от положения мыши. Другими словами, сохраняйте последний центр масштабирования (или, если у вас его еще нет, просто установите его в текущую позицию мыши) и сохраняйте количество вычислений центра масштабирования (после первого масштабирования это будет 1). , Чем каждый раз, когда вы пересчитываете центр увеличения, увеличивайте это значение.
Пример кода следует - deltaZoom - это степень масштабирования, centerX и centerY - текущий масштаб, ZoomSteps - количество масштабов, а mouseX и mouseY - текущая позиция мыши:
_Zoom += deltaZoom;
if (_Zoom <= 0)
_Zoom = 0.1;
if (deltaZoom >= 0)
{
if (_ZoomSteps == -1)
{
_CenterX = 0;
_CenterY = 0;
_ZoomSteps = 0;
}
else
{
_CenterX = (_CenterX * Math.Abs(_ZoomSteps) + mouseX) / (Math.Abs(_ZoomSteps + 1));
_CenterY = (_CenterY * Math.Abs(_ZoomSteps) + mouseY) / (Math.Abs(_ZoomSteps + 1));
_ZoomSteps++;
}
}
else
{
if (_ZoomSteps == 1)
{
_CenterX = 0;
_CenterY = 0;
_ZoomSteps = 0;
}
else
{
_CenterX = (_CenterX * Math.Abs(_ZoomSteps) - mouseX) / (Math.Abs(_ZoomSteps - 1));
_CenterY = (_CenterY * Math.Abs(_ZoomSteps) - mouseY) / (Math.Abs(_ZoomSteps - 1));
_ZoomSteps--;
}
}
ZoomAnimationX.To = _Zoom;
ZoomAnimationY.To = _Zoom;
CenterAnimationX.To = Math.Abs(_CenterX);
CenterAnimationY.To = Math.Abs(_CenterY);
ZoomStoryboard.Begin();
Отредактировано так, что вы можете опуститься ниже уровня масштабирования 1,0, но все еще есть некоторые проблемы (ZoomStep = -1, 0 или 1 иногда вызывают странные колебания).