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