2014-05-09 38 views
0

我有一個畫布,上面有一個位圖圖像。我可以通過縮放縮放手勢縮放整個畫布。現在我想要在縮放的畫布上畫線或徒手繪製,即放大。這樣做時,我可以在畫布未縮放時獲得準確的結果,但當畫布放大時,我會在某個隨機位置處繪製線條。如何在縮放畫布上用位圖繪製線條,圓圈

線描時畫布不進行縮放

Line drawing when canvas is not scaled

線描當帆布在onTouchMove被放大:當用戶縮小或

Line Drawing when canvas is zoomed in onTouchMove

結果onTouchEnd同時畫線。 線條應如第二張圖所示位於U上。

Result when user zooms out or onTouchEnd while drawing line. LINE SHOULD BE AT U AS SHOWN IN THE SECOND FIGURE

這是我的代碼

@Override 
public boolean onTouchEvent(MotionEvent event) 
{ 
    float x = event.getX(); 
    float y = event.getY(); 

    if(WriteApp.getAction().equalsIgnoreCase("draw")) 
    { 
     isDrawing=true; 
     int touchCount = event.getPointerCount(); 
     //Log.i("", "from on draw x"+x+" y "+y); 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      Log.i("", "touch start x"+x+" y "+y); 
      touch_start(x, y); 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_MOVE: 

      touch_move(x, y); 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      Log.i("", "touch end x"+x+" y "+y); 
      touch_up(); 
      this.invalidate(); 
      break; 
     } 
     return true; 
    } 
    isDrawing=false; 
    switch (event.getAction() & MotionEvent.ACTION_MASK) 
    { 
    case MotionEvent.ACTION_DOWN: 

     mode = DRAG; 

     //We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated 
     //amount for each coordinates This works even when we are translating the first time because the initial 
     //values for these two variables is zero. 
     startX = event.getX()-previousTranslateX; 
     startY = event.getY()-previousTranslateY; 
     break; 

    case MotionEvent.ACTION_MOVE: 
     translateX = event.getX()-startX; 
     translateY = event.getY()-startY; 

     //We cannot use startX and startY directly because we have adjusted their values using the previous translation values. 
     //This is why we need to add those values to startX and startY so that we can get the actual coordinates of the finger. 
     double distance = Math.sqrt(Math.pow(event.getX()-(startX + previousTranslateX), 2) + 
       Math.pow(event.getY()-(startY + previousTranslateY), 2) 
       ); 

     if(distance > 0) 
     { 
      dragged = true; 
     } 

     break; 

    case MotionEvent.ACTION_POINTER_DOWN: 
     mode = ZOOM; 
     break; 

    case MotionEvent.ACTION_UP: 
     mode = NONE; 
     dragged = false; 

     //All fingers went up, so let’s save the value of translateX and translateY into previousTranslateX and 
     //previousTranslate 
     previousTranslateX = translateX; 
     previousTranslateY = translateY; 
     break; 

    case MotionEvent.ACTION_POINTER_UP: 
     mode = DRAG; 

     //This is not strictly necessary; we save the value of translateX and translateY into previousTranslateX 
     //and previousTranslateY when the second finger goes up 
     previousTranslateX = translateX; 
     previousTranslateY = translateY; 
     break; 
    } 

    detector.onTouchEvent(event); 

    //We redraw the canvas only in the following cases: 
    // 
    // o The mode is ZOOM 
    // OR 
    // o The mode is DRAG and the scale factor is not equal to 1 (meaning we have zoomed) and dragged is 
    // set to true (meaning the finger has actually moved) 
    if ((mode == DRAG && scaleFactor != 1f && dragged) || mode == ZOOM) 
    { 
     invalidate(); 
    } 

    return true; 
} 

@Override 
public void onDraw(Canvas canvas) { 

    canvas.save(); 

    //If translateX times -1 is lesser than zero, let’s set it to zero. This takes care of the left bound 
    //if(((translateX*-1)(scaleFactor-1)*displayWidth)<0) 
    //If translateX times -1 is lesser than zero, let's set it to zero. This takes care of the left bound 
    if((translateX * -1) < 0) { 
     translateX = 0; 
    } 

    //This is where we take care of the right bound. We compare translateX times -1 to (scaleFactor - 1) * displayWidth. 
    //If translateX is greater than that value, then we know that we've gone over the bound. So we set the value of 
    //translateX to (1 - scaleFactor) times the display width. Notice that the terms are interchanged; it's the same 
    //as doing -1 * (scaleFactor - 1) * displayWidth 
    else if((translateX * -1) > (scaleFactor - 1) * displayWidth) { 
     translateX = (1 - scaleFactor) * displayWidth; 
    } 

    if(translateY * -1 < 0) { 
     translateY = 0; 
    } 

    //We do the exact same thing for the bottom bound, except in this case we use the height of the display 
    else if((translateY * -1) > (scaleFactor - 1) * displayHeight) { 
     translateY = (1 - scaleFactor) * displayHeight; 
    } 


    //We need to divide by the scale factor here, otherwise we end up with excessive panning based on our zoom level 
    //because the translation amount also gets scaled according to how much we’ve zoomed into the canvas. 
    canvas.translate(translateX, translateY); 

    //We’re going to scale the X and Y coordinates by the same amount 
    canvas.scale(scaleFactor, scaleFactor); 

    super.onDraw(canvas); 

    //The rest of your canvas-drawing code 


    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    if(scaleFactor!=1.f) 
     canvas.restore(); 

    if(isDrawing) 
     canvas.drawPath(mPath, dPaint); 

    if(scaleFactor==1.f) 
     canvas.restore(); 

} 
+0

你正在做錯事 – pskink

+0

是的,這就是我正在尋找的。已經發布我的code.please檢查,讓我知道我哪裏會出錯。 :) –

+0

1)獲取Canvas的矩陣,2)顛倒()它3)使用倒置矩陣mapPoints()映射onTouchEvent中的每個觸摸點 – pskink

回答