2009-06-23 13 views
11

Muszę mieć możliwość powiększania i pomniejszania obszaru roboczego za pomocą kółka myszy. Udało mi się skonfigurować obsługę myszy na kółkach i obecnie używam ScaleTransform, aby zastosować zoom; jednak skalowanie nie odbywa się w sposób "intuicyjny".Silverlight 3 - ScaleTransform lub inna metoda powiększania płótna?

Próbuję osiągnąć ten sam styl "powiększania", jak można zobaczyć w MultiScaleImage, Mapach Google/Earth lub Adobe Acrobat Reader - ale NIE w przypadku obrazu, z kontrolą. Przejście nie musi być "płynne" ani animowane (chyba, że ​​jest to łatwiejsze podejście), ale funkcjonalność musi być taka sama.

Wszelkie przemyślenia lub pomysły będą bardzo cenne i z góry dziękujemy!

Edit: Udało mi się "gładkim" zoom z wykorzystaniem animacji:

<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> 

z następującego kodu:

_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 

Jednak problem pojawia się nadal, że jest powiększanie z w lewym górnym rogu, w przeciwieństwie do witryn takich jak Mapy Google, w których zoom jest "w pobliżu" myszy.

Odpowiedz

10

Musisz użyć średniej ważonej jako centrum powiększenia na podstawie pozycji myszy. Innymi słowy, zachowaj najnowszy środek powiększenia (lub jeśli go nie masz, a po prostu ustaw go na aktualną pozycję myszy) i zachowaj liczbę razy, w których zostało obliczone centrum powiększenia (po pierwszym powiększeniu, które wynosi 1) . Za każdym razem, gdy ponownie obliczysz środek powiększenia, zwiększ ten var.

Przykładowy kod Follows - deltaZoom to ile jesteś powiększanie, centerx i Centery są obecne centrum zoom ZoomSteps jest kilka razy mamy powiększony i mouseX i mouseY są aktualne położenie myszy:

_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(); 

Edytowane tak, że można opuścić poniżej poziomu powiększenia 1.0, ale nadal występują pewne problemy (ZoomStep = -1, 0 lub 1 czasami powodują dziwne drgania).

+0

Dzięki za źródło :) +1 –

+0

Co to jest CenterAnimation? – Erix

Powiązane problemy