Skip to content

Draw Analog Clock Hands

Mitch Todd edited this page Jan 30, 2015 · 1 revision

Clockwise provides a TimeUtil class that exposes utility methods for drawing UI components related to the time, namely analog clock hands. You can get hour/minute/second hands by utilizing getXXXDegrees() in TimeUtil and using that as an input to rotate the Canvas you are drawing on. The degrees returned by the utility are in reference to 12 o'clock (e.g. angle of 0 represents 12 o'clock), so you can draw the hand along the Y axis after rotating the canvas:

private void drawSecondHand(Canvas canvas) {
    WatchFaceTime currentTime = getTime();
    float secondDegrees = TimeUtil.getSecondDegrees(currentTime);

    canvas.save();
    canvas.rotate(secondDegrees, mWatchFaceCenter.x, mWatchFaceCenter.y);
    canvas.drawLine(mWatchFaceCenter.x, mWatchFaceCenter.y, mWatchFaceCenter.x, 
            mWatchFaceCenter.y - mSecondHandLength, mSecondHandPaint);
    canvas.restore();
}

In this case, you are still drawing from a 0, 0 origin, so you need to utilize the watch face center point to calculate your endpoints. You can also translate your canvas to draw your hand relative to the center of the watch face (NOTE: this will be negative along Y-axis):

private void drawSecondHand(Canvas canvas) {
    WatchFaceTime currentTime = getTime();
    float secondDegrees = TimeUtil.getSecondDegrees(currentTime);
    
    canvas.save();
    canvas.translate(mWatchFaceCenter.x, mWatchFaceCenter.y);
    canvas.rotate(secondDegrees, 0f, 0f);
    canvas.drawLine(0f, 0f, 0f, -mSecondHandLength, mSecondHandPaint);
    canvas.restore();
}

Finally, if you have a very simple analog clock hand (e.g. a line) you can also utilize the GeometryUtil class to determine your endpoints on a circle and then just draw the line:

private void drawSecondHand(Canvas canvas) {
    WatchFaceTime currentTime = getTime();
    float secondDegrees = TimeUtil.getSecondDegrees(currentTime);

    GeometryUtil.updatePointOnCircle(mSecondHandEndPoint, mSecondHandLength, 
            secondDegrees, mWatchFaceCenter);

    canvas.drawLine(mWatchFaceCenter.x, mWatchFaceCenter.y,
                    mSecondHandEndPoint.x, mSecondHandEndPoint.y, mSecondHandPaint);
}

GeometryUtil

You'll find GeometryUtil helpful for calculating points on a circle given degrees. This can be useful for drawing polygons and lines which move along the circumference of the clock. For instance, the Zodiac watch face utilizes this utility to draw a polygon between the logical hands.