I am following the \"FingerPaint\" demo in the API Demos.
I would need to get an \"airbrush\" effect, in the sense that when I draw over the same spot it gets darker and
This approach is more of a simulation the way something like Photoshop would do it: Integrate along the path and draw individual paint splashes with an adjustable spacing inbetween.
public class DrawView extends View {
public Paint mPaint;
private Bitmap mBitmap;
private Canvas mCanvas;
private int strokeRadius;
private ShapeDrawable mBrush;
private Paint mBitmapPaint;
private float mPreviousX, mPreviousY;
public DrawView(Context context, AttributeSet attrs) {
super( context, attrs);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
int strokeWidth = 20;
strokeRadius = strokeWidth/2;
Shape brushShape = new OvalShape();
mBrush = new ShapeDrawable(brushShape);
Paint paint = mBrush.getPaint();
// radial gradient shader with a transparency falloff, if you don't want this,
// just set a color on the paint and remove the setShader call
Shader shader = new RadialGradient(strokeRadius, strokeRadius, strokeRadius,
Color.argb(255, 0, 0, 0), Color.argb(0, 0, 0, 0), Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAlpha(0x10);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFF00B8F5);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
}
private void touch_start(float x, float y) {
mPreviousX = x;
mPreviousY = y;
}
private void touch_move(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
// get vector from previous to current position
float xdist = x - mPreviousX;
float ydist = y - mPreviousY;
// get the length
float segmentLength = (float) Math.sqrt(xdist * xdist + ydist * ydist);
// derive a suitable step size from stroke width
float stepSize = Math.max(strokeRadius / 10, 1f);
// calculate the number of steps we need to take
// NOTE: this draws a bunch of evenly spaced splashes from the start point
// to JUST BEFORE the end point. The end point will be drawn by the start point of the
// next stroke, or by the touch_up method. If we drew both the start and
// end point there it would be doubled up
int steps = Math.max(Math.round(segmentLength / stepSize), 2);
for(int i = 0; i < steps; ++i)
{
int currentX = (int) (mPreviousX + xdist * i / steps);
int currentY = (int) (mPreviousY + ydist * i / steps);
drawSplash(currentX, currentY);
}
// update the previous position
mPreviousX = x;
mPreviousY = y;
}
private void touch_up(MotionEvent event) {
drawSplash((int) event.getX(), (int)event.getY());
}
/**
* draws the brush to the canvas, centered around x and y
* @param x
* @param y
*/
private void drawSplash(int x, int y)
{
mBrush.setBounds(x - strokeRadius, y - strokeRadius, x + strokeRadius, y + strokeRadius);
mBrush.draw(mCanvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(event);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(event);
invalidate();
break;
}
return true;
}
}
Edit: snap shot (Raghunandan). Result Testing with White Background and Black Color paint.