2009-06-23 11 views
11

Devo essere in grado di ingrandire e rimpicciolire una tela usando la rotellina del mouse. Ho configurato con successo i gestori di mouse wheel e sto attualmente utilizzando un ScaleTransform per applicare lo zoom; tuttavia, il ridimensionamento non viene eseguito in modo "intuitivo".Silverlight 3 - ScaleTransform o altro metodo per ingrandire una tela?

Sto provando a realizzare lo stesso stile di "zoom" come si può vedere in MultiScaleImage, Google Maps/Earth o Adobe Acrobat Reader - ma NON con un'immagine, con un controllo. La transizione non ha bisogno di essere "liscia" o animata (a meno che non sia un approccio più semplice), ma la funzionalità deve essere la stessa.

Tutti i pensieri o idee sarebbe molto apprezzato e grazie in anticipo!

Edit: sono riuscito a "liscio" lo zoom usando animazione:

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

con il seguente codice:

_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 

Tuttavia, il problema si pone ancora che è lo zoom fuori l'angolo in alto a sinistra, a differenza di siti come Google Maps in cui lo zoom è "intorno" al mouse.

risposta

10

È necessario utilizzare una media ponderata come centro dello zoom in base alla posizione del mouse. In altre parole, mantieni l'ultimo centro dello zoom (o se non ne hai ancora uno appena impostato sulla posizione corrente del mouse) e mantieni il numero di volte in cui è stato calcolato il centro dello zoom (dopo il primo zoom, sarebbe 1) . Di ogni volta che ricalcoli il centro dello zoom, incrementalo.

Esempio di codice Follows - deltaZoom è quanto si sta zoom, centerX e centerY sono il centro di zoom corrente, ZoomSteps è il numero di volte che abbiamo lo zoom, e mouseX e mouseY sono la posizione del mouse corrente:

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

Redatta in modo da poter scendere sotto il livello di zoom 1.0, ma ci sono ancora alcuni problemi (ZoomStep = -1, 0 o 1 talvolta causare scuote strano).

+0

Grazie per la fonte :) +1 –

+0

Che cos'è CenterAnimation? – Erix

Problemi correlati