Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Canvas coordinates after scaling up/down or dragging in android

Tags:

I'm developing an application in which I'm pasting images, doing drawing and painting on canvas. This app can also Scale up/down the canvas or drag it to different location. My problem is: I can't get the correct canvas coordinates after scaling or dragging the canvas. I want to draw finger paint after the canvas is scaled or dragged but unable to retrieve the right place where i've touched..:( Also I'm new bee. Here is the code.

@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;     } } 
like image 791
Awais Tariq Avatar asked Sep 23 '11 05:09

Awais Tariq


1 Answers

Done it finally by myself.

Draw everything by applying this formula to (px,py) coordinates:

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 
like image 135
Awais Tariq Avatar answered Oct 14 '22 04:10

Awais Tariq