Dav*_*ave 5 android drawing paint width stroke
我的代码基本上来自这个例子(http://corner.squareup.com/2010/07/smooth-signatures.html)和Google API(FingerPaint),但现在我想使用该类VelocityTracker
来改变笔画宽度,具体取决于在我的手指速度.
我以为我可以将路径分成更小的部分,但我没有找到任何例子.还有第二篇文章(http://corner.squareup.com/2012/07/smoother-signatures.html),但我没有特定的bezier曲线类,也没有收集所有的点,ArrayList
所以他们的例子用于调整笔划宽度不是很有帮助.
有谁知道如何处理这个?两周前我开始学习代码,所以我对这些东西都很新.
编辑:我试图实现我的MotionEvents的速度,我使用LogCat来跟踪运行应用程序时的当前速度.它确实有效,但当我尝试使用速度作为mPaint.setStrokeWidth参数的一部分时,我没有得到我真正想要的东西.我从画布上绘制的路径的宽度从我开始绘制线条的那一刻起一直在变化,直到我将手指向上移动.这就是为什么我想将路径分成更小的部分,因为现在只有最后一个跟踪的速度会影响strokeWidth.
public class SignatureView extends View {
private static final String TAG = SignatureView.class.getSimpleName();
private static final float STROKE_WIDTH = 10;
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
private final double TOUCH_TOLERANCE = 5;
private int h = getResources().getDisplayMetrics().heightPixels;
private int w = getResources().getDisplayMetrics().widthPixels;
private Path mPath = new Path();
private Paint mPaint = new Paint();
private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
private Bitmap mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
private Canvas mCanvas = new Canvas(mBitmap);
private float mX, mY;
private float lastTouchX, lastTouchY;
private final RectF dirtyRect = new RectF();
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(INITIAL_STROKE_WIDTH);
Log.d(TAG, "TOUCH_TOLERANCE = " +TOUCH_TOLERANCE);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
int historySize = event.getHistorySize();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
resetDirtyRect(eventX, eventY);
mPath.reset();
mPath.moveTo(eventX, eventY);
mX = eventX;
mY = eventY;
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(eventX - mX);
float dy = Math.abs(eventY - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
mX = eventX;
mY = eventY;
}
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
break;
case MotionEvent.ACTION_UP:
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
break;
default:
Log.d(TAG, "Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
invalidate( (int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = eventX;
lastTouchY = eventY;
return true;
}
private void expandDirtyRect(float historicalX, float historicalY) {
if (historicalX < dirtyRect.left) {
dirtyRect.left = historicalX;
} else if (historicalX > dirtyRect.right) {
dirtyRect.right = historicalX;
}
if (historicalY < dirtyRect.top) {
dirtyRect.top = historicalY;
} else if (historicalY > dirtyRect.bottom) {
dirtyRect.bottom = historicalY;
}
}
private void resetDirtyRect(float eventX, float eventY) {
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}
Run Code Online (Sandbox Code Playgroud)
每次行程值根据速度发生变化时,您可以使用分割路径对象。在你的SignatureView
班级中添加
private Path mPath = new Path();
ArrayList<Path> mPaths = new ArrayList<Path>();
Run Code Online (Sandbox Code Playgroud)
并使用另一个 ArrayList 来保存每个路径的笔划值
ArrayList<int> strokes = new ArrayList<int>();
Run Code Online (Sandbox Code Playgroud)
lastStroke
与lastTouchX
和一起添加变量lastTouchY
。我会推荐你制作lastStroke
类型int
。
private int lastStroke = -1; //give an initial value
Run Code Online (Sandbox Code Playgroud)
现在你的onTouchEvent
方法应该是这样的
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
int historySize = event.getHistorySize();
int eventStroke= //calculate stroke size with velocity and make it between 1-10 or any range you seem fit
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
resetDirtyRect(eventX, eventY);
mPath.reset();
mPath.moveTo(eventX, eventY);
mX = eventX;
mY = eventY;
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(eventX - mX);
float dy = Math.abs(eventY - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
if(lastStroke != evetnStroke){
mPath = new Path();
mPath.moveTo(mX,mY);
mPaths.Add(mPath);
mStrokes.Add(eventStroke);
}
mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
mX = eventX;
mY = eventY;
}
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
break;
case MotionEvent.ACTION_UP:
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
mPath.lineTo(mX, mY);
break;
default:
Log.d(TAG, "Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
invalidate( (int) (dirtyRect.left - HALF_STROKE_WIDTH),
(int) (dirtyRect.top - HALF_STROKE_WIDTH),
(int) (dirtyRect.right + HALF_STROKE_WIDTH),
(int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
lastTouchX = eventX;
lastTouchY = eventY;
lastStroke = eventStroke;
return true;
}
Run Code Online (Sandbox Code Playgroud)
你的 ondraw 方法是
@Override
protected void onDraw(Canvas canvas) {
for(int i=0; i<mPaths.size();i++){
mPaint.setStrokeWidth(strokes.get(i));
canvas.drawPath(mPaths.get(i), mPaint);
}
}
Run Code Online (Sandbox Code Playgroud)
这是基本思想。你需要修改它才能使其工作。
归档时间: |
|
查看次数: |
7049 次 |
最近记录: |