orca/clock Orca

Code

main.odin ¶
168 linesSource

1package src
2
3/*
4Original Source: https://github.com/orca-app/orca/blob/main/samples/clock/src/main.c
5
6Can be run using in the local folder
71. odin.exe build main.odin -file -target:orca_wasm32 -out:module.wasm 
82. orca bundle --name orca_output --resource-dir data module.wasm
93. orca_output\bin\orca_output.exe
10*/
11
12import "core:math"
13import oc "core:sys/orca"
14
15clockNumberStrings := [?]string{"12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}
16
17surface: oc.surface = {}
18renderer: oc.canvas_renderer = {}
19canvas: oc.canvas_context = {}
20font: oc.font = {}
21frameSize: oc.vec2 = {100, 100}
22lastSeconds: f64 = 0
23
24mat_transform :: proc "contextless" (x, y, radians: f32) -> oc.mat2x3 {
25	rotation := oc.mat2x3_rotate(radians)
26	translation := oc.mat2x3_translate(x, y)
27	return oc.mat2x3_mul_m(translation, rotation)
28}
29
30main :: proc() {
31	oc.window_set_title("clock")
32	oc.window_set_size({400, 400})
33
34	renderer = oc.canvas_renderer_create()
35	surface = oc.canvas_surface_create(renderer)
36	canvas = oc.canvas_context_create()
37
38	ranges := [?]oc.unicode_range {
39		oc.UNICODE_BASIC_LATIN,
40		oc.UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
41		oc.UNICODE_LATIN_EXTENDED_A,
42		oc.UNICODE_LATIN_EXTENDED_B,
43		oc.UNICODE_SPECIALS,
44	}
45
46	oc.font_create_from_path("segoeui.ttf", 5, &ranges[0])
47}
48
49@(export)
50oc_on_resize :: proc "c" (width, height: u32) {
51	frameSize.x = f32(width)
52	frameSize.y = f32(height)
53}
54
55// TODO replace this after round_f64 is fixed: https://github.com/odin-lang/Odin/issues/3856
56remainder_f64 :: proc "contextless" (x, y: f64) -> f64 {
57	return x - round_slow(x / y) * y
58}
59
60round_slow :: proc "contextless" (x: f64) -> f64 {
61	t := math.trunc(x)
62	if abs(x - t) >= 0.5 {
63		return t + math.copy_sign(1, x)
64	}
65	return t
66}
67
68mod_f64 :: proc "contextless" (x, y: f64) -> (n: f64) {
69	z := abs(y)
70	n = remainder_f64(abs(x), z)
71	if math.sign(n) < 0 {
72		n += z
73	}
74	return math.copy_sign(n, x)
75}
76
77@(export)
78oc_on_frame_refresh :: proc "c" () {
79	// context = runtime.default_context()
80
81	oc.canvas_context_select(canvas)
82	oc.set_color_rgba(.05, .05, .05, 1)
83	oc.clear()
84
85	timestampSecs := f64(oc.clock_time(.DATE))
86	secs := mod_f64(timestampSecs, 60.0)
87	minutes := mod_f64(timestampSecs, 60.0 * 60.0) / 60.0
88	hours := mod_f64(timestampSecs, 60.0 * 60.0 * 24) / (60.0 * 60.0)
89	hoursAs12Format := mod_f64(hours, 12.0)
90
91	if lastSeconds != math.floor(secs) {
92		lastSeconds = math.floor(secs)
93
94		// oc.log_infof(
95		// 	"current time: %.0f:%.0f:%.0f",
96		// 	math.floor(hours),
97		// 	math.floor(minutes),
98		// 	math.floor(secs),
99		// )
100	}
101
102	secondsRotation := (math.PI * 2) * (secs / 60.0) - (math.PI / 2)
103	minutesRotation := (math.PI * 2) * (minutes / 60.0) - (math.PI / 2)
104	hoursRotation := (math.PI * 2) * (hoursAs12Format / 12.0) - (math.PI / 2)
105
106	centerX := frameSize.x / 2
107	centerY := frameSize.y / 2
108	clockRadius := min(frameSize.x, frameSize.y) * 0.5 * 0.85
109
110	DEFAULT_CLOCK_RADIUS :: 260
111	uiScale := clockRadius / DEFAULT_CLOCK_RADIUS
112
113	fontSize := 26 * uiScale
114	oc.set_font(font)
115	oc.set_font_size(fontSize)
116
117	// clock backing
118	oc.set_color_rgba(1, 1, 1, 1)
119	oc.circle_fill(centerX, centerY, clockRadius)
120
121	// clock face
122	for i in 0 ..< len(clockNumberStrings) {
123		str := clockNumberStrings[i]
124		textRect := oc.font_text_metrics(font, fontSize, str).ink
125
126		angle := f32(i) * ((math.PI * 2) / f32(12.0)) - (math.PI / 2)
127		transform := mat_transform(
128			centerX - (textRect.w / 2) - textRect.x,
129			centerY - (textRect.h / 2) - textRect.y,
130			angle,
131		)
132
133		pos := oc.mat2x3_mul(transform, {clockRadius * 0.8, 0})
134
135		oc.set_color_rgba(0.2, 0.2, 0.2, 1)
136		oc.text_fill(pos.x, pos.y, str)
137	}
138
139	// hours hand
140	oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(hoursRotation)))
141	{
142		oc.set_color_rgba(.2, 0.2, 0.2, 1)
143		oc.rounded_rectangle_fill(0, -7.5 * uiScale, clockRadius * 0.5, 15 * uiScale, 5 * uiScale)
144	}
145	oc.matrix_pop()
146
147	// minutes hand
148	oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(minutesRotation)))
149	{
150		oc.set_color_rgba(.2, 0.2, 0.2, 1)
151		oc.rounded_rectangle_fill(0, -5 * uiScale, clockRadius * 0.7, 10 * uiScale, 5 * uiScale)
152	}
153	oc.matrix_pop()
154
155	// seconds hand
156	oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(secondsRotation)))
157	{
158		oc.set_color_rgba(1, 0.2, 0.2, 1)
159		oc.rounded_rectangle_fill(0, -2.5 * uiScale, clockRadius * 0.8, 5 * uiScale, 5 * uiScale)
160	}
161	oc.matrix_pop()
162
163	oc.set_color_srgba(.2, 0.2, 0.2, 1)
164	oc.circle_fill(centerX, centerY, 10 * uiScale)
165
166	oc.canvas_render(renderer, canvas, surface)
167	oc.canvas_present(renderer, surface)
168}

Assets 2

Declarations Used 42