Monday, May 25, 2015

Android - Canvas

Android comes along with powerful open-source API libraries which support custom 2D and 3D graphics as well animations. In this tutorial, i am going to explain 2D graphics only.

Canvas allows the user to draw any shapes, text, bitmap on view and its also allow the user to override onDraw() method when user want to update it.








1. Arrow





 class Arrow {
    private float angle;
    private Path path;
    private boolean mDoubleHeader;
    private float mViewWidth;
    private float mViewHeight;
    private float mStartX;
    private float mStartY;
    private float mEndX;
    private float mEndY;

    public Arrow(int width, int height, float startX, float startY, float endX, float endY, boolean doubleHeader) {
        mDoubleHeader = doubleHeader;
        mViewWidth = width;
        mViewHeight = height;
        mStartX = startX;
        mStartY = startY;
        mEndX = endX;
        mEndY = endY;
        angle = (float) getAngle(startX, startY, endX, endY);
        float xm2 = getActualDimensionsX(getRatioX(1f));
        float tempX = 0, tempY = 0, tempX2 = getActualDimensionsX(getRatioX(40)), tempY2 = 0;
        float x0 = endX - tempX2;
        float deltaX = (tempX2 - tempX);
        float deltaY = (tempY2 - tempY);
        float frac = 0.25f;
        float point_x_1 = tempX + ((1 - frac) * deltaX + frac * deltaY);
        float point_y_1 = tempY + ((1 - frac) * deltaY - frac * deltaX);
        float point_x_2 = tempX2;
        float point_y_2 = tempY2;
        float point_x_3 = tempX + ((1 - frac) * deltaX - frac * deltaY);
        float point_y_3 = tempY + ((1 - frac) * deltaY + frac * deltaX);
        float px = (point_x_1 + point_x_3) / 2;
        float py = (point_y_1 + point_y_3) / 2;
        px = (px + point_x_2) / 2;
        py = (py + point_y_2) / 2;
        path = new Path();
        path.setFillType(Path.FillType.EVEN_ODD);
        path.moveTo(point_x_1 + x0 + xm2, point_y_1 + endY);
        path.lineTo(point_x_2 + x0 + xm2, point_y_2 + endY);
        path.lineTo(point_x_3 + x0 + xm2, point_y_3 + endY);
        path.lineTo(px + x0 + xm2, py + endY);
        path.lineTo(point_x_1 + x0 + xm2, point_y_1 + endY);
        path.close();
    }

    public void draw(Canvas canvas, Paint paint) {
        canvas.drawLine(mStartX, mStartY, mEndX, mEndY, paint);
        if (mDoubleHeader) {
            float xm = getActualDimensionsX(getRatioX(2));
            paint.setStyle(Paint.Style.STROKE);
            canvas.rotate(angle, mStartX, mStartY);
            canvas.drawCircle(mStartX - xm, mStartY, xm, paint);
            canvas.rotate(-angle, mStartX, mStartY);
        }
        paint.setStyle(Paint.Style.FILL);
        canvas.rotate(angle, mEndX, mEndY);
        canvas.drawPath(path, paint);
        canvas.rotate(-angle, mEndX, mEndY);
    }

    private double getAngle(float x0, float y0, float x1, float y1) {
        double dx = x1 - x0;
        double dy = -(y1 - y0);
        double inRads = Math.atan2(dy, dx);
        if (inRads < 0) {
            inRads = Math.abs(inRads);
        } else {
            inRads = 2 * Math.PI - inRads;
        }
        return Math.toDegrees(inRads);
    }

    /**
     * Getting X coordinate according device width
     */
    private float getActualDimensionsX(float ratio) {
        return ratio * mViewWidth;
    }

    /**
     * Convert X coordinates device respective
     */
    private static float getRatioX(float value) {
        return ((value * 100) / 320) / 100;
    }
}






2. Different shape



 public class Shape {
    private Path path;
    private float mViewWidth;
    private float mViewHeight;
    private float mCenterX
    private float mCenterY;

    public Shape(float x, float y, float width, float height) {
        mCenterX = x;
        mCenterY = y;
        mViewWidth = width;
        mViewHeight = height;
        path = new Path();
    }

    /**
     * set star path for draw on given position, radius and number of arrow in
     * star
     */
    public void setStar(float r1, float innerR1, int numOfPt) {
        float radius = getActualDimensionsX(getRatioX(r1));
        float innerRadius = getActualDimensionsX(getRatioX(innerR1));
        double section = 2.0 * Math.PI / numOfPt;
        path.reset();
        path.moveTo((float) (mCenterX + radius * Math.cos(0)), (float) (mCenterY + radius * Math.sin(0)));
        path.lineTo((float) (mCenterX + innerRadius * Math.cos(0 + section / 2.0)),
                (float) (mCenterY + innerRadius * Math.sin(0 + section / 2.0)));
        for (int i = 1; i < numOfPt; i++) {
            path.lineTo((float) (mCenterX + radius * Math.cos(section * i)), (float) (mCenterY + radius * Math.sin(section * i)));
            path.lineTo((float) (mCenterX + innerRadius * Math.cos(section * i + section / 2.0)), (float) (mCenterY + innerRadius
                    * Math.sin(section * i + section / 2.0)));
        }
        path.close();
    }

    /**
     * Getting X coordinate according device width
     */
    private float getActualDimensionsX(float ratio) {
        return ratio * mViewWidth;
    }

    /**
     * Convert X coordinates device respective
     */
    private static float getRatioX(float value) {
        return ((value * 100) / 320) / 100;
    }

    public void draw(Canvas canvas, Paint paint) {
        paint.setStyle(Paint.Style.FILL);
        canvas.rotate(90, mCenterX, mCenterY)
        canvas.drawPath(path, paint);
        canvas.rotate(-90, mCenterX, mCenterY);
    }

}


Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...