Header Ads

Drawing with Canvas in Android, Brushes

Continuing with our Drawing in Canvas series, let us see how to implement brushes.


Introduction
Drawing lines is boring, lets draw something else

Notes
• We would introduce a new package com.almondmendoza.drawings.brush
• The files are uploaded in http://goo.gl/ecHpE
• The project was build in IntelliJ and it should be easy to import to Eclipse

What Do I Need
IBrush.java
public interface IBrush {
public void mouseDown( Path path, float x, float y);
public void mouseMove( Path path, float x, float y);
public void mouseUp( Path path, float x, float y);
}


Brush.java
public class Brush implements  IBrush {
public void mouseDown(Path path, float x, float y) {
// add codes here if it would affect every brush
}

public void mouseMove(Path path, float x, float y) {
// add codes here if it would affect every brush
}

public void mouseUp(Path path, float x, float y) {
// add codes here if it would affect every brush
}

}



Pen.java
public class PenBrush extends Brush{
@Override
public void mouseDown(Path path, float x, float y) {
path.moveTo( x, y );
path.lineTo(x, y);
}

@Override
public void mouseMove(Path path, float x, float y) {
path.lineTo( x, y );
}

@Override
public void mouseUp(Path path, float x, float y) {
path.lineTo( x, y );
}
}


CircleBrush.java
public class CircleBrush extends Brush{
@Override
public void mouseMove(Path path, float x, float y) {
path.addCircle(x,y,10,Path.Direction.CW);
}
}


DrawingActivity.java
public class DrawingActivity extends Activity implements View.OnTouchListener{
...
private Brush currentBrush;
public void onCreate(Bundle savedInstanceState) {
...
currentBrush = new PenBrush();
...
}

public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
currentBrush.mouseDown(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY());
} else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
currentBrush.mouseMove( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
} else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
currentBrush.mouseUp( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
drawingSurface.isDrawing = true;
}
return true;
}

public void onClick(View view){
switch (view.getId()){
...
case R.id.circleBtn:
currentBrush = new CircleBrush();
break;
case R.id.pathBtn:
currentBrush = new PenBrush();
break;
}
}



Quick Explanation
Ads from Amazon:
Explanation
public interface IBrush {
  public void mouseDown( Path path, float x, float y);
  public void mouseMove( Path path, float x, float y);
  public void mouseUp( Path path, float x, float y);
}

We begin by creating a brush interface so that our brushes would be united :)

public class Brush implements IBrush {
  ...
}

Our brush class would serve as base classes for our other brushes, here we can implement codes that would be shared across different brushes

public class PenBrush extends Brush{ ... }
From our previous article from the series we had implemented these codes directly on onTouch function on DrawingActivity, here we just move it to its own Brush class.

public class CircleBrush extends Brush{
  @Override
  public void mouseMove(Path path, float x, float y) {
    path.addCircle(x,y,10,Path.Direction.CW);
  }
}

In here we only make use of the mouseMove of our Brush class, as you can see we have path.addCircle where we could make other brushes by changing this to other function or adding more then one path (For other shapes available kindly refer to the Path Reference

public boolean onTouch(View view, MotionEvent motionEvent) {
  if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
    currentBrush.mouseDown(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY());
  }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
    currentBrush.mouseMove( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
  }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
    currentBrush.mouseUp( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
    drawingSurface.isDrawing = true;
  }
  return true;
}

We rewrote the function to use our brushes to do the paths so that we could change the brush and not care about this function.

public void onClick(View view){
  switch (view.getId()){
    ...
    case R.id.circleBtn:
      currentBrush = new CircleBrush();
    break;
    case R.id.pathBtn:
      currentBrush = new PenBrush();
    break;
  }
}

This is now we change brushes

Conclusion
To add new brushes, just create a new class that extends the Brush class.

No comments:

Powered by Blogger.