2013-07-12 1 views
2

이제 캔버스에 점을 그려서 확대하거나 축소 할 수 있습니다.Canvas가 확대 또는 축소 된 경우에도 화면의 고정 된 점에 항상 도트를 그립니 까? - Android

필자가 아는 한, 그림 기능 canvas.drawCircle()은 캔버스 좌표계에서 좌표를 취합니다. 또한, 캔버스가 확대 될 때 좌표는 변경되지 않습니다.

예. 이전에 캔버스 좌표계에서 (50, 50)에 점을 그려 캔버스를 확대하면 캔버스의 점 좌표는 여전히 (50, 50)으로 유지됩니다. 그러나 분명히 그 점은 w.r.t로 옮겨졌습니다. 화면.

캔버스가 확대/축소되면 점이 화면의 동일한 위치에 유지되어야합니다. * 점이 w.r.t. 화면에서 원래 위치로 다시 이동하려고합니다. 화면. 다음과 같이 *

onDraw() 기능은 다음과 같습니다

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    canvasWidth = canvas.getWidth(); 
    canvasHeight = canvas.getHeight(); 

    canvas.save(); 
    canvas.translate(mPosX, mPosY); 
    canvas.scale(mScaleFactor, mScaleFactor); 
    mImage.draw(canvas); // draw the map as the background 

      Paint PointStyle = new Paint(); 
    PointStyle.setColor(Color.BLUE); 
    PointStyle.setStyle(Paint.Style.FILL_AND_STROKE); 
    PointStyle.setStrokeWidth(2); 

    canvas.drawCircle(Constant.INITIAL_X, Constant.INITIAL_Y, 3, PointStyle); 

    canvas.restore(); 
} 

내가 스케일링 후 화면에 다시 점을 이동하려면 다음 방법을 시도했다.

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 

     mScaleFactor *= detector.getScaleFactor(); // accumulate the scale factors 
     // Don't let the object get too small or too large. 
     mScaleFactor = Math.max(1f, Math.min(mScaleFactor, 10.0f)); // 1 ~ 10 

     float pinToCornerOnScreenXDistance = 0; 
     float pinToCornerOnScreenYDistance = 0; 
     float canvasToScreenDiffRatioX = 0; 
     float canvasToScreenDiffRatioY = 0; 
     float pinOnCanvasX = 0; 
     float pinOnCanvasY = 0; 

     // pin's location on the screen --> S:(336, 578) 
     pinToCornerOnScreenXDistance = 336 - canvasLeftTopCornerOnScreenX; 
     pinToCornerOnScreenYDistance = 578 - canvasLeftTopCornerOnScreenY; 
     Log.d("Screen Diff", "X: " + pinToCornerOnScreenXDistance + " Y: " + pinToCornerOnScreenYDistance); 

     canvasToScreenDiffRatioX = canvasWidth * mScaleFactor/720; // screen of HTC One X --> 720*1280 
     canvasToScreenDiffRatioY = canvasHeight * mScaleFactor/1280; 
     Log.d("Ratio", canvasToScreenDiffRatioX + " " + canvasToScreenDiffRatioY); 

     pinOnCanvasX = 0 + pinToCornerOnScreenXDistance * canvasToScreenDiffRatioX; // canvas left top corner is the origin (0, 0) 
     pinOnCanvasY = 0 + pinToCornerOnScreenYDistance * canvasToScreenDiffRatioY; 
     Log.d("Pin on Canvas", "X: " + pinOnCanvasX + " Y: " + pinOnCanvasY); 

     Constant.setInitialX(pinOnCanvasX); 
     Constant.setInitialY(pinOnCanvasY); 
     historyXSeries.set(0, Constant.INITIAL_X); 
     historyYSeries.set(0, Constant.INITIAL_Y); 

     invalidate(); 
     return true; 
    } 
} 

아이디어는 내가 나 캔버스를 확대 또는 축소 할 때 내가 알 수 있다는 사실을 기반으로, 자사의 왼쪽 상단 모서리가 이동하지 않습니다. 즉, 캔버스 'let top corner가 확대/축소 센터입니다.

그런 다음 캔버스를 움직일 때 확대/축소 센터의 좌표를 성공적으로 업데이트하고 있습니다. 이렇게하면 캔버스를 움직이거나 확대/축소 할 때마다 항상 확대/축소 센터의 좌표가 내 canvasLeftTopCornerOnScreenXcanvasLeftTopCornerOnScreenY입니다.

그런 다음 확대/축소 중 줌 센터와 내 도트를 배치하려는 희망 위치 인 (336, 578) 사이의 거리를 활용하려고합니다. 나는 그것을 pinToCornerOnScreenDistance으로 계산합니다.

이름에서 알 수 있듯이 화면상의 거리입니다. 그리기 기능은 화면 좌표계 대신 캔버스 좌표계를 기반으로하기 때문에 점을 그릴 수 있도록 캔버스 거리로 크기를 조정해야합니다. 현재 코드는 기기마다 다릅니다 (예 : 1280 * 720 화면이있는 HTC One X에만 해당). 다음과 같이 그래서 스케일링을 수행

canvasToScreenDiffRatioX = canvasWidth * mScaleFactor/720; 
canvasToScreenDiffRatioY = canvasHeight * mScaleFactor/1280; 

다음, 마지막으로 내가 화면에 점 (336, 578)의 새로운 온 - 캔버스 좌표를 계산하고이 점을 그립니다.

그러나 결과가 올바르지 않습니다. 캔버스를 확대하면 그려지는 점이 화면의 (336, 578)에 남아 있지 않습니다.

어디에서 잘못 되었나요? 다른 방법을 제안 하시겠습니까?

모든 댓글이나 답변을 크게 높이세요!

답변

1

앱이 전체 화면을 사용하고 있습니까? 그렇지 않으면 높이가 1280이 아닙니다. 그러나 나는 이것이 당신의 문제라고 생각하지 않습니다.내 이해를 바탕으로

, 나는 가정

pinOnCanvasX = 336/mScaleFactor; 
pinOnCanvasY = 578/mScaleFactor; 

에 코드를 변경할 때 mScaleFactor == 1, 캔버스 화면에 동일에

0

이 하나를 시도하는 핀, 나는

pinOnCanvasX = (336 * mScaleFactor) + trans_x; 

pinOnCanvasY = (578 * mScaleFactor) + trans_y; 

here, trans_x and trans_y is translation of canvas on x and y axis. here in your case should be mPosX, mPosY but not sure what these points means for. 

내가 공유하고 싶습니다 방법 당신은 크기를 조절하고,이 문제에 유용 할 수 있다고 생각 캔버스처럼 원의 시작점 을 번역하십시오. 즉, 캔버스에 값을 입력하고 변환하면 시작 지점에도 같은 값이 적용됩니다.

희망이 문제를 해결할 것입니다.

관련 문제