我遗漏了一些东西,所以我希望你能分享一些关于我的事情。
我正在画布中绘制一些文字。为此,我有一个班级Word
public class Word {
private int x;
private int y;
private String text;
}
该应用允许用户旋转文字,我使用onDraw
protected void onDraw(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(angle, centerX, centerY)
...
canvas.drawText(word.getText(), word.getX(), word.getY())
....
canvas.restore();
}
我得到的问题是用户拖动画布并且有旋转设置。当角度= 0时,运动按预期进行。
@Override
public boolean onTouchEvent(MotionEvent event) {
case MotionEvent.ACTION_DOWN:
initialX = (int) event.getX();
initialY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int currentX = (int) event.getX();
int currentY = (int) event.getY();
int xMovement = currentX - initialX;
int yMovement = currentY - initialY;
dragWords(xMovement, yMovement);
.....
对于我所做的每个单词,请在和dragWords
上填写:
private void dragText(int xMovement, int yMovement){
for (Word word : words) {
word.setX(word.getX() + xMovement);
word.setY(word.getY() + yMovement);
}
invalidate();
}
当旋转角度为0时,向上/向下/向左/向右移动会使单词移动相同的距离。随着角度变大,单词开始以不同的方向移动,例如60,它开始向斜上方移动,当180它只向上/向下移动而不是向左/向右移动。
我想我需要根据角度计算某种差异并将其添加到xMovement / yMovement ......但是我应该怎么做呢?
LE:这是一个关于它如何表现的图像: 蓝线是文本在拖动时移动的方式,而橙色是手指在屏幕上拖动。当角度为0时,效果非常好,当角度增加时,它开始沿左/右对角移动,而当角度更大时,它只上下移动而不响应左/右
答案 0 :(得分:3)
如果我理解正确,问题是Canvas.rotate()
不仅会旋转文字方向,还会旋转整个画布。因此,单词的x-y坐标也会从指定的轴心点旋转。
为了匹配拖动动作,您可以使用Matrix
,更具体地说,您可以使用inverse matrix来旋转画布。它将用于将单词的x-y坐标转换为其原始的预旋转位置。
例如,计算一次,并在angle
,centerX
或centerY
更改时更新。
// rotMatrix is the same operation applied on the canvas.
Matrix rotMatrix = new Matrix();
rotMatrix.postRotate(mAngle, centerX, centerY);
// Invert it to convert x, y to their transformed positions.
Matrix matrix = new Matrix();
rotMatrix.invert(matrix);
然后,在绘制每个单词时:
int wordX = ...
int wordY = ...
String text = ...
float[] coords = new float[] { wordX, wordY };
matrix.mapPoints(coords);
canvas.drawText(text, coords[0], coords[1], paint);
答案 1 :(得分:0)
在以下代码的ellipses
部分中:
dragWords(xMovement, yMovement);
..... <<<--------------------- I hope you are updating initialX and initialY
initialX = currentX;
initialY = currentY;
否则,您的x和y值将与触摸手势期间移动的距离量无法正确对应。
如用户matiash
所示,您应使用Matrix#mapPoints(float[])
转换x和y值。声明并初始化矩阵:
Matrix correctionMatrix;
// Your view's constructor
public MyView() {
....
correctionMatrix = new Matrix();
}
以下是onDraw(Canvas)
的外观:
@Override
protected void onDraw(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(angle, centerX, centerY);
...
// Neutralize the rotation
correctionMatrix.setRotate(-angle, centerX, centerY);
// Initialize a float array that holds the original coordinates
float[] src = {word.getX(), word.getY()};
// Load transformed values into `src` array
correctionMatrix.mapPoints(src);
// `src[0]` and `src[1]` hold the transformed `X` and `Y` coordinates
canvas.drawText(word.text, src[0], src[1], somePaint);
....
canvas.restore();
}
这应该可以提供所需的结果 - 无论画布旋转如何,都可以在X轴和Y轴上移动。
您显然可以将setRotate(float, float, float)
的电话转移到更好的地方。更改angle
值后,您只需要调用一次。