11{
2- "cells" : [
3- {
4- "cell_type" : " code" ,
5- "execution_count" : null ,
6- "metadata" : {},
7- "outputs" : [],
8- "source" : [
9- " from ipycanvas import Canvas, hold_canvas\n " ,
10- " import numpy as np\n " ,
11- " \n " ,
12- " CLOCK_RADIUS = 100\n " ,
13- " \n " ,
14- " canvas = Canvas(width=CLOCK_RADIUS * 2.5, height=CLOCK_RADIUS * 2.5)\n " ,
15- " canvas.translate(CLOCK_RADIUS * 1.2, CLOCK_RADIUS * 1.2)\n " ,
16- " \n " ,
17- " \n " ,
18- " def clear_drawing():\n " ,
19- " canvas.clear_rect(\n " ,
20- " -CLOCK_RADIUS * 1.2, -CLOCK_RADIUS * 1.2, canvas.width, canvas.height\n " ,
21- " )\n " ,
22- " \n " ,
23- " \n " ,
24- " def minutes_vec(minutes):\n " ,
25- " a = minutes * np.pi / 30\n " ,
26- " return [np.sin(a), -np.cos(a)]\n " ,
27- " \n " ,
28- " \n " ,
29- " def draw_dial():\n " ,
30- " ht = 10\n " ,
31- " mt = 6\n " ,
32- " ho = 20\n " ,
33- " mo = 10\n " ,
34- " \n " ,
35- " canvas.text_align = \" center\"\n " ,
36- " canvas.text_baseline = \" middle\"\n " ,
37- " \n " ,
38- " canvas.line_width = 2\n " ,
39- " canvas.stroke_circle(0, 0, CLOCK_RADIUS)\n " ,
40- " \n " ,
41- " for m in range(60):\n " ,
42- " a = m * np.pi / 30\n " ,
43- " x, y = np.sin(a), -np.cos(a)\n " ,
44- " \n " ,
45- " canvas.line_width = 1\n " ,
46- " if m % 5 == 0:\n " ,
47- " canvas.stroke_line(\n " ,
48- " x * (CLOCK_RADIUS - ht),\n " ,
49- " y * (CLOCK_RADIUS - ht),\n " ,
50- " x * CLOCK_RADIUS,\n " ,
51- " y * CLOCK_RADIUS,\n " ,
52- " )\n " ,
53- " canvas.font = \" 12px serif\"\n " ,
54- " canvas.stroke_text(str(m), x * (CLOCK_RADIUS + mo), y * (CLOCK_RADIUS + mo))\n " ,
55- " canvas.font = \" 16px serif\"\n " ,
56- " canvas.stroke_text(\n " ,
57- " str(m // 5 if m > 0 else 12),\n " ,
58- " x * (CLOCK_RADIUS - ho),\n " ,
59- " y * (CLOCK_RADIUS - ho),\n " ,
60- " )\n " ,
61- " else:\n " ,
62- " canvas.stroke_line(\n " ,
63- " x * (CLOCK_RADIUS - mt),\n " ,
64- " y * (CLOCK_RADIUS - mt),\n " ,
65- " x * CLOCK_RADIUS,\n " ,
66- " y * CLOCK_RADIUS,\n " ,
67- " )\n " ,
68- " \n " ,
69- " \n " ,
70- " def draw_hands(minutes):\n " ,
71- " ms = 35\n " ,
72- " hs = 50\n " ,
73- " \n " ,
74- " hrs = minutes // 60\n " ,
75- " mins = minutes % 60\n " ,
76- " \n " ,
77- " mv = minutes_vec(mins)\n " ,
78- " hv = minutes_vec(hrs * 5 + (mins / 12))\n " ,
79- " \n " ,
80- " canvas.line_width = 5\n " ,
81- " canvas.stroke_line(0, 0, mv[0] * (CLOCK_RADIUS - ms), mv[1] * (CLOCK_RADIUS - ms))\n " ,
82- " canvas.stroke_line(0, 0, hv[0] * (CLOCK_RADIUS - hs), hv[1] * (CLOCK_RADIUS - hs))\n " ,
83- " \n " ,
84- " \n " ,
85- " def draw_clock(hours, minutes):\n " ,
86- " with hold_canvas():\n " ,
87- " clear_drawing()\n " ,
88- " draw_dial()\n " ,
89- " draw_hands((hours % 12) * 60 + minutes)\n " ,
90- " \n " ,
91- " \n " ,
92- " canvas"
93- ]
2+ "metadata" : {
3+ "kernelspec" : {
4+ "display_name" : " xeus-python" ,
5+ "language" : " python" ,
6+ "name" : " xeus-python"
7+ },
8+ "language_info" : {
9+ "file_extension" : " .py" ,
10+ "mimetype" : " text/x-python" ,
11+ "name" : " python" ,
12+ "version" : " 3.10.2"
13+ }
9414 },
95- {
96- "cell_type" : " code" ,
97- "execution_count" : null ,
98- "metadata" : {},
99- "outputs" : [],
100- "source" : [
101- " import datetime\n " ,
102- " import ipywidgets as widgets\n " ,
103- " \n " ,
104- " now = datetime.datetime.now()\n " ,
105- " \n " ,
106- " hour_text = widgets.IntText(\n " ,
107- " value=now.hour, continuous_update=True, layout={\" width\" : \" 50px\" }\n " ,
108- " )\n " ,
109- " minute_text = widgets.IntText(\n " ,
110- " value=now.minute, continuous_update=True, layout={\" width\" : \" 50px\" }\n " ,
111- " )\n " ,
112- " \n " ,
113- " \n " ,
114- " def on_text_change(change):\n " ,
115- " draw_clock(int(hour_text.value), int(minute_text.value))\n " ,
116- " \n " ,
117- " \n " ,
118- " hour_text.observe(on_text_change, names=\" value\" )\n " ,
119- " minute_text.observe(on_text_change, names=\" value\" )\n " ,
120- " \n " ,
121- " on_text_change(0)\n " ,
122- " \n " ,
123- " widgets.HBox([hour_text, widgets.Label(value=\" :\" ), minute_text])"
124- ]
125- }
126- ],
127- "metadata" : {
128- "kernelspec" : {
129- "display_name" : " xeus-python" ,
130- "language" : " python" ,
131- "name" : " xeus-python"
132- },
133- "language_info" : {
134- "codemirror_mode" : {
135- "name" : " ipython" ,
136- "version" : 3
137- },
138- "file_extension" : " .py" ,
139- "mimetype" : " text/x-python" ,
140- "name" : " python" ,
141- "nbconvert_exporter" : " python" ,
142- "pygments_lexer" : " ipython3" ,
143- "version" : " 3.10.4"
144- }
145- },
146- "nbformat" : 4 ,
147- "nbformat_minor" : 4
148- }
15+ "nbformat_minor" : 4 ,
16+ "nbformat" : 4 ,
17+ "cells" : [
18+ {
19+ "cell_type" : " code" ,
20+ "source": "from ipycanvas import Canvas, hold_canvas\nimport numpy as np\n\nCLOCK_RADIUS = 100\n\ncanvas = Canvas(width=CLOCK_RADIUS * 2.5, height=CLOCK_RADIUS * 2.5)\ncanvas.translate(CLOCK_RADIUS * 1.2, CLOCK_RADIUS * 1.2)\n\n\ndef clear_drawing():\n canvas.clear_rect(\n -CLOCK_RADIUS * 1.2, -CLOCK_RADIUS * 1.2, canvas.width, canvas.height\n )\n canvas.fill_style = 'white'\n canvas.fill_rect(-canvas.width/2, -canvas.height/2, canvas.width, canvas.height)\n\n\ndef minutes_vec(minutes):\n a = minutes * np.pi / 30\n return [np.sin(a), -np.cos(a)]\n\n\ndef draw_dial():\n ht = 10\n mt = 6\n ho = 20\n mo = 10\n\n canvas.text_align = \"center\"\n canvas.text_baseline = \"middle\"\n\n canvas.line_width = 2\n canvas.stroke_circle(0, 0, CLOCK_RADIUS)\n\n for m in range(60):\n a = m * np.pi / 30\n x, y = np.sin(a), -np.cos(a)\n\n canvas.line_width = 1\n if m % 5 == 0:\n canvas.stroke_line(\n x * (CLOCK_RADIUS - ht),\n y * (CLOCK_RADIUS - ht),\n x * CLOCK_RADIUS,\n y * CLOCK_RADIUS,\n )\n canvas.font = \"12px serif\"\n canvas.stroke_text(str(m), x * (CLOCK_RADIUS + mo), y * (CLOCK_RADIUS + mo))\n canvas.font = \"16px serif\"\n canvas.stroke_text(\n str(m // 5 if m > 0 else 12),\n x * (CLOCK_RADIUS - ho),\n y * (CLOCK_RADIUS - ho),\n )\n else:\n canvas.stroke_line(\n x * (CLOCK_RADIUS - mt),\n y * (CLOCK_RADIUS - mt),\n x * CLOCK_RADIUS,\n y * CLOCK_RADIUS,\n )\n\n\ndef draw_hands(minutes):\n ms = 35\n hs = 50\n\n hrs = minutes // 60\n mins = minutes % 60\n\n mv = minutes_vec(mins)\n hv = minutes_vec(hrs * 5 + (mins / 12))\n\n canvas.line_width = 5\n canvas.stroke_line(0, 0, mv[0] * (CLOCK_RADIUS - ms), mv[1] * (CLOCK_RADIUS - ms))\n canvas.stroke_line(0, 0, hv[0] * (CLOCK_RADIUS - hs), hv[1] * (CLOCK_RADIUS - hs))\n\n\ndef draw_clock(hours, minutes):\n with hold_canvas():\n clear_drawing()\n draw_dial()\n draw_hands((hours % 12) * 60 + minutes)\n\n\ncanvas",
21+ "metadata" : {
22+ "trusted" : true
23+ },
24+ "execution_count" : null ,
25+ "outputs" : []
26+ },
27+ {
28+ "cell_type" : " code" ,
29+ "source" : " import datetime\n import ipywidgets as widgets\n\n now = datetime.datetime.now()\n\n hour_text = widgets.IntText(\n value=now.hour, continuous_update=True, layout={\" width\" : \" 50px\" }\n )\n minute_text = widgets.IntText(\n value=now.minute, continuous_update=True, layout={\" width\" : \" 50px\" }\n )\n\n\n def on_text_change(change):\n draw_clock(int(hour_text.value), int(minute_text.value))\n\n\n hour_text.observe(on_text_change, names=\" value\" )\n minute_text.observe(on_text_change, names=\" value\" )\n\n on_text_change(0)\n\n widgets.HBox([hour_text, widgets.Label(value=\" :\" ), minute_text])" ,
30+ "metadata" : {
31+ "trusted" : true
32+ },
33+ "execution_count" : null ,
34+ "outputs" : []
35+ },
36+ {
37+ "cell_type" : " code" ,
38+ "source" : " " ,
39+ "metadata" : {},
40+ "execution_count" : null ,
41+ "outputs" : []
42+ }
43+ ]
44+ }
0 commit comments