2011-09-23 44 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