我现在在画布上画一个点,可以放大或缩小。
据我所知,绘图功能canvas.drawCircle()
采用画布坐标系中的坐标。此外,当画布缩放时,坐标保持不变。
例如,之前您在画布坐标系中绘制了一个点(50, 50)
,然后放大画布,画布中的点坐标仍然保持不变(50, 50)
。但很明显,这个点已经在屏幕上移动了。
缩放画布时,点应保持在屏幕上的相同位置。*即点移动到屏幕后,我想将它移回屏幕上的原始位置。*
我的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;
}
}
这个想法是基于我注意到当我放大或缩小画布时,它的左上角永远不会移动的事实。也就是说,画布的让上角是缩放中心。
然后,当画布移动时,我成功地不断更新缩放中心的坐标。所以这样一来,无论我移动画布还是缩放它,我的canvasLeftTopCornerOnScreenX
and中总是有缩放中心的坐标canvasLeftTopCornerOnScreenY
。
然后我尝试利用从未移动过的缩放中心和我希望在(336, 578)
这里放置我的点的所需位置之间的距离。我将其计算为pinToCornerOnScreenDistance
。
顾名思义,就是屏幕上的距离。我必须将它缩放到画布距离以便我可以绘制点,因为绘图功能基于画布坐标系而不是屏幕坐标系。目前,该代码是特定于设备的,即目前仅适用于具有 1280*720 屏幕的 HTC One X。所以我按如下方式进行缩放:
canvasToScreenDiffRatioX = canvasWidth * mScaleFactor / 720;
canvasToScreenDiffRatioY = canvasHeight * mScaleFactor / 1280;
然后,最后我计算屏幕上点的新画布坐标,(336, 578)
然后在那里绘制点。
但结果不正确。当我缩放画布时,我绘制的点无法保留在(336, 578)
屏幕上。
谁能告诉我哪里出了问题?或者提出另一种方法?
任何评论或答案将不胜感激!