2013-02-01 12 views
14

Sono riuscito a implementare pinch zoom e panning agganciando fino agli eventi ManipulationDelta e ManipulationStarted (su un controllo immagine):Smooth pinch-zoom e panoramica su Windows Phone 8

private void image_OnManipulationDelta(object sender, ManipulationDeltaEventArgs e) 
    { 
     var transform = (CompositeTransform)image.RenderTransform; 

     // pan 
     transform.TranslateX = _translationX + e.CumulativeManipulation.Translation.X; 
     transform.TranslateY = _translationY + e.CumulativeManipulation.Translation.Y; 

     // zoom 
     if (e.PinchManipulation != null) 
     { 
      transform.CenterX = e.PinchManipulation.Original.Center.X; 
      transform.CenterY = e.PinchManipulation.Original.Center.Y; 

      transform.ScaleX = _scaleX * e.PinchManipulation.CumulativeScale; 
      transform.ScaleY = _scaleY * e.PinchManipulation.CumulativeScale; 
     } 
    } 

    private void image_OnManipulationStarted(object sender, ManipulationStartedEventArgs e) 
    { 
     // the user has started manipulating the screen, set starting points 
     var transform = (CompositeTransform)image.RenderTransform; 
     _scaleX = transform.ScaleX; 
     _scaleY = transform.ScaleY; 
     _translationX = transform.TranslateX; 
     _translationY = transform.TranslateY; 
    } 

Ma la paragonato a la fluidità del resto dell'interfaccia utente del telefono Windows si sente molto placida e rigida. Non c'è inerzia nel movimento.

C'è un modo per rendere più fluidi i movimenti? Usare le animazioni e gli storyboard è un modo per farlo? Ho provato a utilizzare ScrollView per ottenere un panning minimo, ma gli eventi ManipulationDelta non vengono attivati ​​correttamente.

+0

Solo un aggiornamento come la questione sembrano essere popolari: Ho finito per utilizzare il codice sopra combinato con le animazioni create a livello di codice per ottenere quella sensazione di "inerzia". Dovevo anche ottimizzare usando semplici controlli (tele e immagini bitmap nella cache), per farlo funzionare senza intoppi. – Pking

+0

Possibile duplicato - Bene spiegato qui. [http://stackoverflow.com/questions/13969400/pinch-to-zoom-functionality-in-windows-phone-8](http://stackoverflow.com/questions/13969400/pinch-to-zoom-functionality- in-finestre-phone-8) –

risposta

5

Volevo ottenere questo da un punto di vista matematico. Il risultato è qualcosa di simile nella correttezza a PanAndZoomImage di Telerik. Se non sei interessato, vai direttamente a questo gist (Funziona con WP7.1 +). Avrai bisogno di fare riferimento a System.Windows.Interactivity e al toolkit di Windows Phone.

utilizzati:

<Image Source="http://i.imgur.com/ZbKlRzK.jpg"> 
    <i:Interaction.Behaviors> 
     <phoneApp1:PanAndZoomBehavior MaxZoom="10" /> 
    </i:Interaction.Behaviors> 
</Image> 

Math

panning e zoom utilizza 2 di 4 trasformazioni CompositeTransform, cioè Definizione e Scaling. Il punto chiave è capire come comporre due di quelle scale + tradurre le trasformazioni. Userò la notazione haskellish, perché è meno oneroso scrivere e leggere. Nostri 'primitivi sono

  1. scale s = scala muoversi (sx, sy) con fattore sx in direzione xe sy in direzione y
  2. translate t = compensare tutti i punti da tx in direzione X e ty in direzione Y

CompositeTransform scale intorno a un punto centrale, che si esprime come

scaleAround c s = translate c . scale s . translate -c 

le seguenti regole tengono (fare i calcoli, se si Non mi credi, tutti gli operatori sono componente per componente):

  1. translate a . translate b = translate (a+b)
  2. scale a . scale b = scale (a*b)
  3. translate t . scale s = scale s . translate (t/s)

Un CompositeTransform è come

transform s c t = translate t . scaleAround c s 
       = translate (t+c) . scale s . translate -c 

Durante la composizione di due di queste trasformazioni , dobbiamo muoverci intorno alle primitive finché non arriviamo a s uch un modulo sopra.Lasciate che a e b siano quei due CompositeTransforms. Così otteniamo:

transform' = b . a 
      = translate bt . scaleAround bc bs . translate at . scaleAround ac as 
      = translate bt . translate bc . scale bs . translate -bc . translate at . translate ac . scale as . translate -ac 
      = translate (bt+bc) . scale bs . translate (ac+at-bc) . scale as . translate -ac 
      = translate (bt+bc) . translate (ac+at-bc)*bs . scale bs . scale as . translate -ac 
      = translate (bt+bc+(ac+at-bc)*bs) . scale (as*bs) . translate -ac 
      = translate (bt+bc-ac+(ac+at-bc)*bs) . scaleAround ac (as*bs) 
      = translate (bt+at*bs+(bs-1)*(ac-bs)) . scaleAround ac (as*bs) 

Questo è solo perché ero frustrato con la quantità di documentazione di profonda sul perché certe persone fanno certe cose.

Per il codice effettiva composizione, looko here

Problemi correlati