How to resolve the algorithm Draw a clock step by step in the Go programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Draw a clock step by step in the Go programming language
Table of Contents
Problem Statement
Draw a clock.
More specific:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Draw a clock step by step in the Go programming language
The provided Go code implements a simple web server that displays an interactive clock using the WebSocket protocol for real-time updates. Here's a detailed explanation of the code:
-
Package and Imports:
package main
: The main program package.- It imports various libraries, including
golang.org/x/net/websocket
for handling WebSockets,flag
for command-line argument parsing,fmt
,html/template
for template rendering,io
,math
,net/http
, andtime
.
-
Variables:
Portnum
: Stores the port number on which the server will listen for incoming connections.Hostsite
: Stores the hostname or IP address where the server will be hosted.
-
Structs:
PageSettings
: A struct that holds the host and port information for the WebSocket connection.
-
Constants:
Canvaswidth
andCanvasheight
: Define the dimensions of the clock's canvas in pixels (512x512).- Color constants:
HourColor
,MinuteColor
, andSecondColor
define the colors used for drawing the hour, minute, and second hands, respectively.
-
Main Function:
- Parses command-line arguments for
Port
andSite
using theflag
package. - Sets up HTTP route handlers for the root URL ("/") and the WebSocket endpoint ("/ws").
- Starts the HTTP server on the specified port and host using
http.ListenAndServe
.
- Parses command-line arguments for
-
HTTP Handler:
webhandler
handles HTTP requests to the root URL.- It renders a template called "clock.html," which contains the HTML and JavaScript code for displaying the clock.
-
WebSocket Handler:
wshandle
handles WebSocket connections.- It enters an infinite loop where it continuously reads the current time and updates the position of the hour, minute, and second hands on the clock.
- It uses the
HourCords
,MinSecCords
, andfmt.Sprintf
functions to calculate the coordinates for drawing the hands and sends them as a message to the connected client.
-
Coordinate Calculation Functions:
MinSecCords
andHourCords
: These functions calculate the coordinates for the endpoints of the minute, second, and hour hands, respectively, based on the current time. They take the time value (in minutes or hours) and the radius of the clock as inputs.
-
HTML Template:
- The HTML template
clock.html
defines the web page that displays the clock. - It includes JavaScript code that establishes a WebSocket connection to the server and handles incoming messages to draw the hands of the clock.
- The HTML template
-
JavaScript Code:
- The JavaScript code in the HTML template:
- Connects to the WebSocket server using
new WebSocket()
. - On successful connection, sends a "READY" message to the server.
- Listens for incoming messages from the server and handles them by parsing the data and drawing the clock hands accordingly.
- Renders lines on the specified canvas based on the received coordinates and color.
- Connects to the WebSocket server using
Source code in the go programming language
package main
import (
"golang.org/x/net/websocket"
"flag"
"fmt"
"html/template"
"io"
"math"
"net/http"
"time"
)
var (
Portnum string
Hostsite string
)
type PageSettings struct {
Host string
Port string
}
const (
Canvaswidth = 512
Canvasheight = 512
//color constants
HourColor = "#ff7373" // pinkish
MinuteColor = "#00b7e4" //light blue
SecondColor = "#b58900" //gold
)
func main() {
flag.StringVar(&Portnum, "Port", "1234", "Port to host server.")
flag.StringVar(&Hostsite, "Site", "localhost", "Site hosting server")
flag.Parse()
http.HandleFunc("/", webhandler)
http.Handle("/ws", websocket.Handler(wshandle))
err := http.ListenAndServe(Hostsite+":"+Portnum, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println("server running")
}
func webhandler(w http.ResponseWriter, r *http.Request) {
wsurl := PageSettings{Host: Hostsite, Port: Portnum}
template, _ := template.ParseFiles("clock.html")
template.Execute(w, wsurl)
}
//Given a websocket connection,
//serves updating time function
func wshandle(ws *websocket.Conn) {
for {
hour, min, sec := time.Now().Clock()
hourx, houry := HourCords(hour, Canvasheight/2)
minx, miny := MinSecCords(min, Canvasheight/2)
secx, secy := MinSecCords(sec, Canvasheight/2)
msg := "CLEAR\n"
msg += fmt.Sprintf("HOUR %d %d %s\n", hourx, houry, HourColor)
msg += fmt.Sprintf("MIN %d %d %s\n", minx, miny, MinuteColor)
msg += fmt.Sprintf("SEC %d %d %s", secx, secy, SecondColor)
io.WriteString(ws, msg)
time.Sleep(time.Second / 60.0)
}
}
//Given current minute or second time(i.e 30 min, 60 minutes)
//and the radius, returns pair of cords to draw line to
func MinSecCords(ctime int, radius int) (int, int) {
//converts min/sec to angle and then to radians
theta := ((float64(ctime)*6 - 90) * (math.Pi / 180))
x := float64(radius) * math.Cos(theta)
y := float64(radius) * math.Sin(theta)
return int(x) + 256, int(y) + 256
}
//Given current hour time(i.e. 12, 8) and the radius,
//returns pair of cords to draw line to
func HourCords(ctime int, radius int) (int, int) {
//converts hours to angle and then to radians
theta := ((float64(ctime)*30 - 90) * (math.Pi / 180))
x := float64(radius) * math.Cos(theta)
y := float64(radius) * math.Sin(theta)
return int(x) + 256, int(y) + 256
}
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Clock</title>
<script language="javascript" type="text/javascript">
var connurl = "ws://{{.Host}}:{{.Port}}/ws";
//var ctx;
var secondhand;
var minutehand;
var hourhand;
function wsConnect()
{
//get contexts for drawing
//var canvas = document.getElementById( "canvas" );
//ctx = canvas.getContext( '2d' );
var canvas = document.getElementById("rim");
//draw circle for rim
rim = canvas.getContext('2d');
rim.beginPath();
rim.arc(256,256,256,0,2*Math.PI);
rim.stroke();
//minute hand
canvas = document.getElementById("minutehand");
minutehand = canvas.getContext('2d');
//hour hand
canvas = document.getElementById("hourhand");
hourhand = canvas.getContext('2d');
//second hand
canvas = document.getElementById("secondhand");
secondhand = canvas.getContext('2d');
ws = new WebSocket( connurl );
ws.onopen = function( e ) {
console.log( "CONNECTED" );
ws.send( "READY" );
};
/*ws.onclose = function( e ) {
console.log( "DISCONNECTED" );
};*/
ws.onmessage = function( e ) {
var data = e.data.split("\n");
for ( var line in data ) {
var msg = data[line].split(" ");
var cmd = msg[0];
if (cmd =="CLEAR"){
minutehand.clearRect(0,0,512,512);
secondhand.clearRect(0,0,512,512);
hourhand.clearRect(0,0,512,512);
}else if (cmd === "HOUR"){
renderline(hourhand, msg);
}else if (cmd === "MIN"){
renderline(minutehand, msg);
}else if (cmd === "SEC"){
renderline(secondhand, msg);
}else if (cmd ===""){
cmd = "";
}else{
console.log("BAD COMMAND: "+cmd + "; "+msg);
}
}
};
ws.onerror = function( e ) {
console.log( 'WS Error: ' + e.data );
};
}
//render line given paramets
function renderline(ctx, msg){
ctx.clearRect(0,0,512,512);
ctx.width = ctx.width;
var x = parseInt(msg[1],10);
var y = parseInt(msg[2],10);
var color = msg[3];
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(256,256);
ctx.lineTo(x,y);
ctx.stroke();
}
window.addEventListener( "load", wsConnect, false );
</script>
<body>
<h2>Clock</h2>
<canvas id="rim" width="512" height="512" style="position: absolute; left: 0; top: 0; z-index: 0;">
Sorry, your browser does not support Canvas
</canvas>
<canvas id="hourhand" width="512" height="512"style="position: absolute; left: 0; top: 0; z-index: 1;">
Sorry, your browser does not support Canvas
</canvas>
<canvas id="minutehand" width="512" height="512"style="position: absolute; left: 0; top: 0; z-index: 2;">
Sorry, your browser does not support Canvas
</canvas>
<canvas id="secondhand" width="512" height="512"style="position: absolute; left: 0; top: 0; z-index: 3;">
Sorry, your browser does not support Canvas
</canvas>
</body>
</html>
You may also check:How to resolve the algorithm Empty program step by step in the COBOL programming language
You may also check:How to resolve the algorithm Loops/Nested step by step in the SPL programming language
You may also check:How to resolve the algorithm EKG sequence convergence step by step in the REXX programming language
You may also check:How to resolve the algorithm Scope/Function names and labels step by step in the Ring programming language
You may also check:How to resolve the algorithm Amb step by step in the D programming language