我有一個畫布,上面有一個位圖圖像。我可以通過縮放縮放手勢縮放整個畫布。現在我想要在縮放的畫布上畫線或徒手繪製,即放大。這樣做時,我可以在畫布未縮放時獲得準確的結果,但當畫布放大時,我會在某個隨機位置處繪製線條。如何在縮放畫布上用位圖繪製線條,圓圈
線描時畫布不進行縮放:
線描當帆布在onTouchMove被放大:當用戶縮小或
結果onTouchEnd同時畫線。 線條應如第二張圖所示位於U上。
這是我的代碼
@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();
}
你正在做錯事 – pskink
是的,這就是我正在尋找的。已經發布我的code.please檢查,讓我知道我哪裏會出錯。 :) –
1)獲取Canvas的矩陣,2)顛倒()它3)使用倒置矩陣mapPoints()映射onTouchEvent中的每個觸摸點 – pskink