2011-09-23 16 views
18

Zajmuję się tworzeniem aplikacji, w której wklejam obrazy, wykonuję rysunek i maluję na płótnie. Ta aplikacja może również skalować w górę/w dół obszaru roboczego lub przeciągnąć go do innej lokalizacji. Mój problem: nie mogę uzyskać prawidłowych współrzędnych obszaru roboczego po skalowaniu lub przeciągnięciu obszaru roboczego. Chcę narysować farby palcem po płótno jest skalowany lub przeciągnięty ale nie może pobrać odpowiednie miejsce gdzie Dotknąłem .. :( Również jestem nowym pszczoła. Oto kod.Współrzędne Canvas po skalowaniu w górę/w dół lub przeciągnięciu w systemie Android

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    canvas.save(); 
    //canvas.translate(mPosX, mPosY); 
    canvas.scale(mScaleFactor, mScaleFactor, super.getWidth() * 0.5f, 
      super.getHeight() * 0.5f); 
    mIcon.draw(canvas); 
    for (Path path : listPath) { 
     canvas.drawPath(path, paint); 
    } 
    canvas.restore(); 
} 

public TouchExampleView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    // Let the ScaleGestureDetector inspect all events. 
    mScaleDetector.onTouchEvent(ev); 

    final int action = ev.getAction(); 
    switch (action & MotionEvent.ACTION_MASK) { 
    case MotionEvent.ACTION_DOWN: { 
     final float x = ev.getX(); 
     final float y = ev.getY(); 

     mLastTouchX = x; 
     mLastTouchY = y; 
     mActivePointerId = ev.getPointerId(0); 
     break; 
    } 

    case MotionEvent.ACTION_MOVE: { 
     final int pointerIndex = ev.findPointerIndex(mActivePointerId); 
     final float x = ev.getX(pointerIndex); 
     final float y = ev.getY(pointerIndex); 

     // Only move if the ScaleGestureDetector isn't processing a gesture. 
     if (!mScaleDetector.isInProgress()) { 
      final float dx = x - mLastTouchX; 
      final float dy = y - mLastTouchY; 

      mPosX += dx; 
      mPosY += dy; 

      invalidate(); 
     } 

     mLastTouchX = x; 
     mLastTouchY = y; 

     break; 
    } 

    case MotionEvent.ACTION_UP: { 
     mActivePointerId = INVALID_POINTER_ID; 
     break; 
    } 

    case MotionEvent.ACTION_CANCEL: { 
     mActivePointerId = INVALID_POINTER_ID; 
     break; 
    } 

    case MotionEvent.ACTION_POINTER_UP: { 
     final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
     final int pointerId = ev.getPointerId(pointerIndex); 
     if (pointerId == mActivePointerId) { 
      // This was our active pointer going up. Choose a new 
      // active pointer and adjust accordingly. 
      final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
      mLastTouchX = ev.getX(newPointerIndex); 
      mLastTouchY = ev.getY(newPointerIndex); 
      mActivePointerId = ev.getPointerId(newPointerIndex); 
     } 
     break; 
    } 
    } 

    float objectNewX,objectNewY; 
    if (mScaleFactor >= 1) { 
     objectNewX = ev.getX() + (ev.getX() - super.getWidth() * 0.5f) * (mScaleFactor - 1); 
     objectNewY = ev.getY() + (ev.getY() - super.getHeight() * 0.5f) * (mScaleFactor - 1); 
    } else { 
     objectNewX = ev.getX() - (ev.getX() - super.getWidth() * 0.5f) * (1 - mScaleFactor); 
     objectNewY = ev.getY() - (ev.getY() - super.getHeight() * 0.5f) * (1 - mScaleFactor); 
    } 

    if (ev.getAction() == MotionEvent.ACTION_DOWN) { 
     path = new Path(); 
     path.moveTo(objectNewX,objectNewY); 
     path.lineTo(objectNewX,objectNewY); 
    } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { 
     path.lineTo(objectNewX,objectNewY); 
     listPath.add(path); 
    } else if (ev.getAction() == MotionEvent.ACTION_UP) { 
     path.lineTo(objectNewX,objectNewY); 
     listPath.add(path); 
    } 

    return true; 
} 

private class ScaleListener extends 
     ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     mScaleFactor *= detector.getScaleFactor(); 

     // Don't let the object get too small or too large. 
     mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); 

     invalidate(); 
     return true; 
    } 
} 
+0

* Nie mogę uzyskać poprawnych współrzędnych canvas *. Musisz być bardziej konkretny. Czy sama skala działa? Określ, czego oczekujesz jako * poprawne współrzędne płótna *? Co jest z nimi nie tak teraz? – Knickedi

+0

spróbuj powiększyć obraz, a następnie pomaluj coś na płótnie ... a potem się dowiesz. –

+0

także odkomentowanie canvas.translate (mPosX, mPosY); –

Odpowiedz

19

Gotowe . to w końcu sam

Draw wszystko przez zastosowanie tej formuły (px, py) współrzędne:

float px = ev.getX()/mScaleFactor + rect.left; 
float py = ev.getY()/mScaleFactor + rect.top; 
rect = canvas.getClipBounds(); 
//Get them in on Draw function and apply above formula before drawing 
+0

Hej awais Jestem też utknąłem w tym samym. Nie zrozumiałam twojego rozwiązania poprawnie, czy możesz podzielić się z nami swoim kodem lub pomóc mi z tym samym? – user1169079

+0

gdzie jest twój problem ??? W moim przypadku, gdzie muszę narysować coś na ekranie użyłem float x = ev.getX()/mScaleFactor + rect.left; dla X zamiast event.getX(); podobnie dla osi Y. Rect to clipbounds na narysowanym płótnie. Musimy zapisać go w jakiejś prostokątnej zmiennej. Są stale aktualizowane w funkcji onDraw. –

+0

http://stackoverflow.com/questions/9989170/clickable-area-after-scaling-w-respect-to-positions-of-touch-event .. sprawdź to, czy możesz pomóc, że będzie świetnie ... – user1169079

7
@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    clipBounds_canvas = canvas.getClipBounds(); 
    /////Do whatever you want to do..!!!    
}; 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    int x = ev.getX()/zoomFactor + clipBounds_canvas.left; 
    int y = ev.getY()/zoomFactor + clipBounds_canvas.top; 
    //Use the above two values insted of ev.getX() and ev.getY(); 
} 

nadzieję, że pomoże

.
+0

Te powyżej dwóch wartości x i y są przesunięciem w miejscu, w którym znajdzie się moje miejsce/kliknięcie? Czy muszę zaktualizować moje obiekty rysowania przy użyciu powyższych wartości x i y? – user1169079

+0

Musisz zaktualizować obiekty do rysowania, jak sądzę, zgodnie z wyżej wymienionymi względnymi X i Y. –

+0

Dzięki kolego !!! Mam miejsce, w którym mój obiekt się porusza ... ale nie wiem jak przenieść klikalny obszar do tej samej pozycji, nad którą pracuję ... jeśli masz jakiś pomysł, zasugeruj !!! Próbowałem getHitRect i dodać do niego offset? Zrób pracę !!! – user1169079