2011-09-23 177 views
18

我正在開發一個應用程序,在該應用程序中粘貼圖像,在畫布上進行繪畫和繪畫。此應用程序還可以放大/縮小畫布或將其拖到不同的位置。 我的問題是:縮放或拖動畫布後無法獲得正確的畫布座標。我想畫手指畫在畫布上進行縮放或拖動,但無法檢索在那裏我已經碰到合適的位置後.. :( 此外,我是新蜂。這裏是代碼。放大/縮小或在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

*我無法獲得正確的畫布座標*。你必須更具體。規模本身是否有效?定義你期望的*正確的畫布座標*?他們現在有什麼問題? – Knickedi

+0

嘗試放大圖像,然後在畫布上畫一些東西。然後你會知道。 –

+0

也取消註釋 canvas.translate(mPosX,mPosY); –

回答

19

完成它最終被自己

應用該公式繪製的一切(PX,PY)座標:

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

嘿,awais我也被困在同樣的事情上。我沒有正確理解你的解決方案,你可以請分享你的代碼或幫助我一樣嗎? – user1169079

+0

你的問題在哪裏? 在我的情況下,我必須在屏幕上繪製一些東西,我用float x = ev.getX()/ mScaleFactor + rect.left;爲X而不是event.getX();類似於Y軸。 Rect是繪製畫布的clipbounds。我們必須將它保存在一些矩形變量中。他們不斷更新onDraw函數。 –

+0

http://stackoverflow.com/questions/9989170/clickable-area-after-scaling-with-respect-to-positions-of-touch-event ..檢查這個,如果你可以幫助它將是偉大的... – 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(); 
} 

希望這將有助於

+0

那些高於兩個值的x和y是我的命中區域/點擊所在的偏移量?或者我需要使用上面的x和y值更新繪圖對象? – user1169079

+0

你需要根據上面提到的相對x和y來更新繪製對象。 –

+0

謝謝隊友!我已經得到了我的對象正在移動..但我不知道如何將可點擊區域移動到我正在工作的相同位置..如果您有任何想法建議!我試過getHitRect並將其添加到它的偏移量?辛苦工作! – user1169079