2014-07-24 7 views
6

C'è qualcosa che mi manca in questo modo, spero che tu possa condividere un po 'di luce su di me.Il trascinamento del testo ruotato all'interno della tela Android non funziona come previsto

Sto disegnando del testo all'interno della tela. Per questo ho una classe Word

public class Word { 
    private int x; 
    private int y; 
    private String text; 
} 

L'applicazione permette all'utente di ruotare il testo, e mi occupo della rotazione withing onDraw

protected void onDraw(Canvas canvas) { 
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.rotate(angle, centerX, centerY) 
    ... 
    canvas.drawText(word.getText(), word.getX(), word.getY()) 
    .... 
    canvas.restore(); 
} 

Il problema che ottengo è quando l'utente trascina la tela e c'è un set di rotazione. Quando angolo = 0 il movimento sta andando come previsto.

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     case MotionEvent.ACTION_DOWN: 
      initialX = (int) event.getX(); 
      initialY = (int) event.getY(); 
     break; 
     case MotionEvent.ACTION_MOVE: 
      int currentX = (int) event.getX(); 
      int currentY = (int) event.getY(); 
      int xMovement = currentX - initialX; 
      int yMovement = currentY - initialY; 

      dragWords(xMovement, yMovement); 
    ..... 

e dragWords per ogni parola che faccio:

private void dragText(int xMovement, int yMovement){ 
for (Word word : words) { 
    word.setX(word.getX() + xMovement); 
    word.setY(word.getY() + yMovement); 
} 
invalidate(); 

}

Quando l'angolo di rotazione è 0, muovendosi su/giù/sinistra/destra rende le parole muovono alla stessa distanza . Quando l'angolo diventa più grande, le parole iniziano a muoversi in diverse dirrazioni, ad esempio a 60, inizia a salire in diagonale, quando 180 si sposta solo su/giù e non a sinistra/a destra.

Penso di aver bisogno di calcolare una sorta di differenza in base all'angolo e di aggiungerlo a xMovement/yMovement ... ma come dovrei farlo?

LE: Ecco un'immagine su come si comporta: enter image description here Le linee blu è come il testo si muove sulla resistenza, mentre l'arancia è il dito trascinare sullo schermo. Quando l'angolo è 0, funziona piuttosto bene, quando l'angolo aumenta, inizia a spostarsi diagonalmente a sinistra/destra, mentre quando l'angolo è ancora più grande, si sposta solo su e giù e non risponde a sinistra/destra

risposta

0

Nella parte ellipses nel codice seguente:

dragWords(xMovement, yMovement); 
..... <<<--------------------- I hope you are updating initialX and initialY 

initialX = currentX; 
initialY = currentY; 

caso contrario, i valori xey saranno non corrisponde correttamente con la quantità di distanza spostata durante il gesto di tocco.

Come utente matiash indicato, è necessario utilizzare Matrix#mapPoints(float[]) per trasformare i valori xey. Dichiarare e inizializzare una matrice:

Matrix correctionMatrix; 

// Your view's constructor 
public MyView() { 
    .... 
    correctionMatrix = new Matrix(); 
} 

Ecco come il vostro onDraw(Canvas) dovrebbe essere simile:

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    canvas.rotate(angle, centerX, centerY); 
    ... 

    // Neutralize the rotation 
    correctionMatrix.setRotate(-angle, centerX, centerY); 

    // Initialize a float array that holds the original coordinates 
    float[] src = {word.getX(), word.getY()}; 

    // Load transformed values into `src` array 
    correctionMatrix.mapPoints(src); 

    // `src[0]` and `src[1]` hold the transformed `X` and `Y` coordinates 
    canvas.drawText(word.text, src[0], src[1], somePaint); 
    .... 
    canvas.restore(); 
} 

Questo dovrebbe dare i risultati desiderati - movimento nel assi X e Y, indipendentemente dalla rotazione di tela.

È ovviamente possibile spostare la chiamata a setRotate(float, float, float) in un posto migliore. Devi solo chiamarlo una volta dopo aver cambiato il valore angle.

+0

Realmente non vedo la differenza tra questa soluzione e la sostanza che ho postato (?) – matiash

+0

È davvero lo stesso approccio era solo un po 'più semplice, solo su matrice con -angle – Alin

+0

@matiash Ho appena dato la sostanza che hai postato un esempio di esecuzione - funziona bene, salva un problema non correlato (non importante). Il fatto è che ho esaminato la tua risposta e ho visto che "Alin" non ha avuto successo. Così, ho codificato da solo con l'idea che la rotazione debba essere neutralizzata (usando la negazione dell'angolo di rotazione). – Vikram

3

Se io capisco correttamente, il problema è che Canvas.rotate() non ruota solo la direzione del testo, ma piuttosto la tela intera . Pertanto, le coordinate x-y delle parole vengono anche ruotate dal punto di articolazione specificato.

Per abbinare il movimento di trascinamento, è possibile utilizzare uno Matrix per questo, in particolare lo inverse matrix di quello che si sta utilizzando per ruotare il quadro. Verrà utilizzato per convertire le coordinate x-y delle parole nelle loro posizioni originali, pre-rotazione.

Ad esempio, calcolare questo valore una volta e aggiornarlo ogni volta che si modifica angle, centerX o centerY.

// rotMatrix is the same operation applied on the canvas. 
Matrix rotMatrix = new Matrix(); 
rotMatrix.postRotate(mAngle, centerX, centerY); 

// Invert it to convert x, y to their transformed positions. 
Matrix matrix = new Matrix(); 
rotMatrix.invert(matrix); 

Poi, quando il disegno ogni parola:

int wordX = ... 
int wordY = ... 
String text = ... 

float[] coords = new float[] { wordX, wordY }; 
matrix.mapPoints(coords); 
canvas.drawText(text, coords[0], coords[1], paint); 
+0

Ho intenzione di testare questo oggi, grazie per la risposta. Ho provato prima di usare una matrice come 'matrix.setRotate (-mAngle, centerX, centerY)' e poi mapPoints ma non ha funzionato correttamente. – Alin

+0

Ho bisogno di usare canvas.rotate a causa di altre operazioni che sto facendo nella vista. La rotazione della tela funziona piuttosto bene, ad esempio quando ruoto un'immagine, anche trascinando i lavori per le immagini, ma non so perché per le parole non lo è. Non sono sicuro di capire davvero la tua risposta. – Alin

+0

@Alin mi dispiace non essere stato chiaro. Quello che intendevo era tenere tutto come fai tu, incluso canvas.rotate, ma aggiungi questo codice extra. – matiash

Problemi correlati