ParulPandey commited on
Commit
4a15e90
·
verified ·
1 Parent(s): c4700cb

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +395 -18
index.html CHANGED
@@ -1,19 +1,396 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta name="description" content="Interactive app to teach kids about rotation symmetry in shapes" />
7
+ <meta name="keywords" content="rotation symmetry, kids education, shapes, interactive learning" />
8
+ <title>Rotation Symmetry Explorer</title>
9
+ <style>
10
+ :root {
11
+ --bg: #ffffff;
12
+ --text: #111827; /* gray-900 */
13
+ --muted: #6b7280; /* gray-500 */
14
+ --grid: #e5e7eb; /* gray-200 */
15
+ --accent: #2563eb; /* blue-600 */
16
+ --good: #16a34a; /* green-600 */
17
+ --danger: #ef4444; /* red-500 */
18
+ --card: #f9fafb; /* gray-50 */
19
+ --shadow: 0 6px 20px rgba(0,0,0,0.08);
20
+ --radius: 16px;
21
+ }
22
+ * { box-sizing: border-box; }
23
+ body { margin: 0; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji"; color: var(--text); background: var(--bg); }
24
+ header { padding: 24px 16px; text-align: center; }
25
+ header h1 { margin: 0 0 4px; font-size: 2rem; }
26
+ header p { margin: 0; color: #374151; }
27
+
28
+ main { padding: 16px; max-width: 1200px; margin: 0 auto; }
29
+
30
+ .intro { background: var(--card); padding: 16px; border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 20px; }
31
+ .intro h2 { margin-top: 0; font-size: 1.25rem; }
32
+
33
+ .explorer { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; align-items: start; }
34
+ @media (max-width: 900px) { .explorer { grid-template-columns: 1fr; } }
35
+
36
+ .shape-container { background: var(--card); padding: 12px; border-radius: var(--radius); box-shadow: var(--shadow); }
37
+ .shape-stage { position: relative; border-radius: 12px; overflow: hidden; background: #fff; height: 420px; border: 1px solid #e5e7eb; }
38
+ canvas { width: 100%; height: 100%; display: block; cursor: default; }
39
+ canvas.drawing { cursor: crosshair; }
40
+
41
+ .controls { background: #fff; padding: 16px; border-radius: var(--radius); box-shadow: var(--shadow); display: grid; gap: 12px; }
42
+ .controls label { font-size: 0.9rem; color: #374151; display: block; margin-bottom: 4px; }
43
+ .row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
44
+ .row input[type="range"] { flex: 1; }
45
+ .btn { appearance: none; border: 1px solid #e5e7eb; background: #fff; padding: 8px 12px; border-radius: 12px; box-shadow: var(--shadow); font-weight: 600; cursor: pointer; }
46
+ .btn:active { transform: translateY(1px); }
47
+ .btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
48
+ .btn.ghost { background: #f3f4f6; }
49
+ .toggle { display: inline-flex; align-items: center; gap: 8px; }
50
+
51
+ select, input[type="range"], input[type="checkbox"] { accent-color: var(--accent); }
52
+ select { width: 100%; padding: 8px 10px; border-radius: 12px; border: 1px solid #e5e7eb; background: #fff; }
53
+
54
+ .info { background: var(--card); padding: 12px 16px; border-radius: var(--radius); box-shadow: var(--shadow); }
55
+ .info h3 { margin: 0 0 6px; }
56
+
57
+ .examples { margin-top: 24px; }
58
+ .shapes-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
59
+ @media (max-width: 900px) { .shapes-grid { grid-template-columns: repeat(3, 1fr); } }
60
+ .shape-item { background: #fff; padding: 10px; text-align: center; border: 1px solid #e5e7eb; border-radius: 12px; cursor: pointer; box-shadow: var(--shadow); }
61
+ .shape-item p { margin: 8px 0 0; font-size: 0.9rem; }
62
+ .example-shape { width: 56px; height: 56px; margin: 0 auto; background: #f3f4f6; border: 2px solid #d1d5db; }
63
+ .example-shape.square { }
64
+ .example-shape.triangle { clip-path: polygon(50% 10%, 90% 90%, 10% 90%); }
65
+ .example-shape.circle { border-radius: 50%; }
66
+ .example-shape.rectangle { }
67
+ .example-shape.star { clip-path: polygon(50% 8%, 61% 35%, 90% 38%, 66% 58%, 72% 86%, 50% 70%, 28% 86%, 34% 58%, 10% 38%, 39% 35%); }
68
+ .example-shape.hexagon { clip-path: polygon(25% 5%, 75% 5%, 95% 50%, 75% 95%, 25% 95%, 5% 50%); }
69
+
70
+ footer { text-align: center; color: #6b7280; padding: 24px 16px; }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <header>
75
+ <h1>Rotation Symmetry Explorer</h1>
76
+ <p>Learn about shapes that look the same when rotated!</p>
77
+ </header>
78
+
79
+ <main>
80
+ <section class="intro">
81
+ <h2>What is Rotation Symmetry?</h2>
82
+ <p>A shape has rotation symmetry when it looks exactly the same after being rotated around its center. The number of times it matches as it rotates through 360° is called its <strong>order</strong>.</p>
83
+ </section>
84
+
85
+ <section class="explorer">
86
+ <div class="shape-container">
87
+ <div class="shape-stage">
88
+ <canvas id="stage"></canvas>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="controls">
93
+ <div>
94
+ <label for="rotation-slider">Rotate Shape:</label>
95
+ <div class="row">
96
+ <input type="range" id="rotation-slider" min="0" max="360" value="0" />
97
+ <span id="rotation-value" style="width:48px; text-align:right; font-weight:700;">0°</span>
98
+ </div>
99
+ </div>
100
+
101
+ <div>
102
+ <label for="shape-select">Choose Shape:</label>
103
+ <select id="shape-select">
104
+ <option value="square">Square (Order: 4)</option>
105
+ <option value="triangle">Triangle (Order: 3)</option>
106
+ <option value="circle">Circle (Order: ∞)</option>
107
+ <option value="rectangle">Rectangle (Order: 2)</option>
108
+ <option value="star">Star (Order: 5)</option>
109
+ <option value="hexagon">Hexagon (Order: 6)</option>
110
+ <option value="drawing">My drawing</option>
111
+ </select>
112
+ </div>
113
+
114
+ <div class="row">
115
+ <button id="animate-btn" class="btn primary">Animate Rotation</button>
116
+ <button id="reset-btn" class="btn">Reset</button>
117
+ </div>
118
+
119
+ <div class="row" style="justify-content: space-between;">
120
+ <label class="toggle"><input type="checkbox" id="tracing-toggle" checked /> Tracing paper</label>
121
+ <label class="toggle"><input type="checkbox" id="draw-toggle" /> Draw mode</label>
122
+ </div>
123
+
124
+ <div class="row" id="pen-row" style="display:none;">
125
+ <label for="pen-size">Pen size</label>
126
+ <input type="range" id="pen-size" min="1" max="16" value="4" />
127
+ <span id="pen-size-value" style="width:36px; text-align:right;">4px</span>
128
+ <button id="clear-drawing" class="btn ghost">Clear drawing</button>
129
+ </div>
130
+
131
+ <div class="info">
132
+ <h3>Symmetry Order: <span id="order-value">4</span></h3>
133
+ <p id="shape-info">A square looks the same 4 times during a full rotation of 360°.</p>
134
+ <p style="font-size:12px; color:#6b7280; margin-top:8px;">Tip: Watch the small dark dot on the shape. It is a <strong>reference point</strong> that shows how the shape turns.</p>
135
+ </div>
136
+ </div>
137
+ </section>
138
+
139
+ <section class="examples">
140
+ <h2>Common Shapes with Rotation Symmetry</h2>
141
+ <div class="shapes-grid">
142
+ <div class="shape-item" data-shape="square">
143
+ <div class="example-shape square"></div>
144
+ <p>Square</p>
145
+ </div>
146
+ <div class="shape-item" data-shape="triangle">
147
+ <div class="example-shape triangle"></div>
148
+ <p>Triangle</p>
149
+ </div>
150
+ <div class="shape-item" data-shape="circle">
151
+ <div class="example-shape circle"></div>
152
+ <p>Circle</p>
153
+ </div>
154
+ <div class="shape-item" data-shape="rectangle">
155
+ <div class="example-shape rectangle"></div>
156
+ <p>Rectangle</p>
157
+ </div>
158
+ <div class="shape-item" data-shape="star">
159
+ <div class="example-shape star"></div>
160
+ <p>Star</p>
161
+ </div>
162
+ <div class="shape-item" data-shape="hexagon">
163
+ <div class="example-shape hexagon"></div>
164
+ <p>Hexagon</p>
165
+ </div>
166
+ </div>
167
+ </section>
168
+ </main>
169
+
170
+ <footer>
171
+ <p>Created for kids to learn about rotation symmetry | Made with HTML, CSS, and JavaScript</p>
172
+ </footer>
173
+
174
+ <script>
175
+ // --- State ---
176
+ const canvas = document.getElementById('stage');
177
+ const slider = document.getElementById('rotation-slider');
178
+ const rotationValue = document.getElementById('rotation-value');
179
+ const shapeSelect = document.getElementById('shape-select');
180
+ const orderValue = document.getElementById('order-value');
181
+ const shapeInfo = document.getElementById('shape-info');
182
+ const animateBtn = document.getElementById('animate-btn');
183
+ const resetBtn = document.getElementById('reset-btn');
184
+ const tracingToggle = document.getElementById('tracing-toggle');
185
+ const drawToggle = document.getElementById('draw-toggle');
186
+ const penRow = document.getElementById('pen-row');
187
+ const penSizeInput = document.getElementById('pen-size');
188
+ const penSizeValue = document.getElementById('pen-size-value');
189
+ const clearDrawingBtn = document.getElementById('clear-drawing');
190
+
191
+ const ctx = canvas.getContext('2d');
192
+
193
+ let angle = 0; // degrees
194
+ let shape = 'square';
195
+ let tracing = true;
196
+ let drawMode = false;
197
+ let penDown = false;
198
+ let penSize = 4;
199
+ let strokes = []; // Array of arrays of points in center coords
200
+ let animating = false;
201
+ let rafId = null;
202
+ let lastTs = 0;
203
+
204
+ function setupCanvas() {
205
+ const dpr = window.devicePixelRatio || 1;
206
+ const rect = canvas.getBoundingClientRect();
207
+ canvas.width = Math.round(rect.width * dpr);
208
+ canvas.height = Math.round(rect.height * dpr);
209
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
210
+ }
211
+
212
+ function getCenter() {
213
+ return { cx: canvas.clientWidth / 2, cy: canvas.clientHeight / 2 };
214
+ }
215
+
216
+ function deg2rad(d) { return (d * Math.PI) / 180; }
217
+
218
+ function makeShapePath() {
219
+ const size = Math.min(canvas.clientWidth, canvas.clientHeight) * 0.32;
220
+ switch (shape) {
221
+ case 'square':
222
+ return { type: 'poly', pts: [
223
+ {x: -size, y: -size}, {x: size, y: -size}, {x: size, y: size}, {x: -size, y: size}
224
+ ]};
225
+ case 'triangle':
226
+ return { type: 'poly', pts: [
227
+ {x: 0, y: -size}, {x: size, y: size}, {x: -size, y: size}
228
+ ]};
229
+ case 'circle':
230
+ return { type: 'circle', r: size };
231
+ case 'rectangle': {
232
+ const w = size * 1.8, h = size; // wider than tall
233
+ return { type: 'poly', pts: [
234
+ {x: -w, y: -h}, {x: w, y: -h}, {x: w, y: h}, {x: -w, y: h}
235
+ ]};
236
+ }
237
+ case 'star': {
238
+ const pts = []; const spikes = 5; const outer = size; const inner = size * 0.45;
239
+ for (let i = 0; i < spikes * 2; i++) {
240
+ const r = (i % 2 === 0) ? outer : inner;
241
+ const a = (i * Math.PI) / spikes - Math.PI / 2;
242
+ pts.push({ x: r * Math.cos(a), y: r * Math.sin(a) });
243
+ }
244
+ return { type: 'poly', pts };
245
+ }
246
+ case 'hexagon': {
247
+ const pts = []; const r = size;
248
+ for (let i = 0; i < 6; i++) {
249
+ const a = (i * Math.PI) / 3 - Math.PI / 2;
250
+ pts.push({ x: r * Math.cos(a), y: r * Math.sin(a) });
251
+ }
252
+ return { type: 'poly', pts };
253
+ }
254
+ case 'drawing':
255
+ return { type: 'strokes', strokes };
256
+ }
257
+ }
258
+
259
+ function drawGrid(w, h) {
260
+ ctx.save();
261
+ ctx.clearRect(0, 0, w, h);
262
+ ctx.lineWidth = 1; ctx.strokeStyle = '#e5e7eb';
263
+ for (let x = 0; x < w; x += 40) { ctx.beginPath(); ctx.moveTo(x + 0.5, 0); ctx.lineTo(x + 0.5, h); ctx.stroke(); }
264
+ for (let y = 0; y < h; y += 40) { ctx.beginPath(); ctx.moveTo(0, y + 0.5); ctx.lineTo(w, y + 0.5); ctx.stroke(); }
265
+ ctx.restore();
266
+ }
267
+
268
+ function drawReference(cx, cy) {
269
+ ctx.save();
270
+ // center point
271
+ ctx.fillStyle = '#ef4444';
272
+ ctx.beginPath(); ctx.arc(cx, cy, 6, 0, Math.PI * 2); ctx.fill();
273
+ // 0° reference line
274
+ ctx.strokeStyle = '#2563eb'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(cx + 160, cy); ctx.stroke();
275
+ // current angle line
276
+ ctx.save(); ctx.translate(cx, cy); ctx.rotate(deg2rad(angle));
277
+ ctx.strokeStyle = '#16a34a'; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(160, 0); ctx.stroke(); ctx.restore();
278
+ // angle arc
279
+ const radius = 36; ctx.strokeStyle = '#6b7280'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(cx, cy, radius, 0, deg2rad(angle), angle >= 0); ctx.stroke();
280
+ // label
281
+ ctx.fillStyle = '#111827'; ctx.font = 'bold 14px ui-sans-serif, system-ui'; ctx.fillText(Math.round(angle) + '°', cx + radius + 10, cy - 8);
282
+ ctx.restore();
283
+ }
284
+
285
+ function drawPoly(pts) {
286
+ if (!pts.length) return; ctx.beginPath(); ctx.moveTo(pts[0].x, pts[0].y); for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x, pts[i].y); ctx.closePath();
287
+ }
288
+
289
+ function drawStrokesSet(s, lw) {
290
+ ctx.lineJoin = 'round'; ctx.lineCap = 'round';
291
+ for (const stroke of s) {
292
+ if (stroke.length < 2) continue; ctx.beginPath(); ctx.moveTo(stroke[0].x, stroke[0].y); for (let i = 1; i < stroke.length; i++) ctx.lineTo(stroke[i].x, stroke[i].y); ctx.lineWidth = lw; ctx.stroke();
293
+ }
294
+ }
295
+
296
+ function drawShapeWithOptions(cx, cy, color, alpha, atAngleDeg, showMarker) {
297
+ const path = makeShapePath();
298
+ ctx.save(); ctx.translate(cx, cy); ctx.rotate(deg2rad(atAngleDeg)); ctx.globalAlpha = alpha; ctx.strokeStyle = color; ctx.fillStyle = 'rgba(0,0,0,0)';
299
+ if (path.type === 'poly') {
300
+ drawPoly(path.pts); ctx.lineWidth = 4; ctx.stroke();
301
+ if (showMarker && path.pts.length) { const p = path.pts[0]; ctx.fillStyle = '#111827'; ctx.beginPath(); ctx.arc(p.x, p.y, 6, 0, Math.PI * 2); ctx.fill(); }
302
+ } else if (path.type === 'circle') {
303
+ ctx.beginPath(); ctx.arc(0, 0, path.r, 0, Math.PI * 2); ctx.lineWidth = 4; ctx.stroke(); if (showMarker) { ctx.fillStyle = '#111827'; ctx.beginPath(); ctx.arc(path.r, 0, 6, 0, Math.PI * 2); ctx.fill(); }
304
+ } else if (path.type === 'strokes') {
305
+ ctx.lineWidth = penSize; drawStrokesSet(path.strokes, penSize);
306
+ if (showMarker && path.strokes.length && path.strokes[0].length) { const p = path.strokes[0][0]; ctx.fillStyle = '#111827'; ctx.beginPath(); ctx.arc(p.x, p.y, 6, 0, Math.PI * 2); ctx.fill(); }
307
+ }
308
+ ctx.restore();
309
+ }
310
+
311
+ function draw() {
312
+ const w = canvas.clientWidth, h = canvas.clientHeight; const { cx, cy } = getCenter();
313
+ drawGrid(w, h); drawReference(cx, cy);
314
+ if (tracing) drawShapeWithOptions(cx, cy, '#6b7280', 0.35, 0, true); // faint original at 0°
315
+ drawShapeWithOptions(cx, cy, '#111827', 1, angle, true); // active rotated shape
316
+ }
317
+
318
+ // --- Drawing (pen) ---
319
+ function toLocal(clientX, clientY) {
320
+ const rect = canvas.getBoundingClientRect(); const x = clientX - rect.left; const y = clientY - rect.top; const { cx, cy } = getCenter(); return { x: x - cx, y: y - cy };
321
+ }
322
+
323
+ canvas.addEventListener('pointerdown', (e) => {
324
+ if (!drawMode) return; const p = toLocal(e.clientX, e.clientY); penDown = true; strokes.push([p]); if (shape !== 'drawing') { shape = 'drawing'; shapeSelect.value = 'drawing'; updateInfo(); }
325
+ draw();
326
+ });
327
+ canvas.addEventListener('pointermove', (e) => {
328
+ if (!drawMode || !penDown) return; const p = toLocal(e.clientX, e.clientY); const last = strokes[strokes.length - 1]; last.push(p); draw();
329
+ });
330
+ function endStroke() { penDown = false; }
331
+ canvas.addEventListener('pointerup', endStroke);
332
+ canvas.addEventListener('pointerleave', endStroke);
333
+
334
+ // --- UI events ---
335
+ slider.addEventListener('input', () => { angle = Number(slider.value); rotationValue.textContent = Math.round(angle) + '°'; draw(); });
336
+
337
+ shapeSelect.addEventListener('change', () => { shape = shapeSelect.value; updateInfo(); draw(); });
338
+
339
+ animateBtn.addEventListener('click', () => { animating = !animating; animateBtn.textContent = animating ? 'Stop' : 'Animate Rotation'; if (animating) { lastTs = performance.now(); rafId = requestAnimationFrame(loop); } else if (rafId) { cancelAnimationFrame(rafId); } });
340
+
341
+ resetBtn.addEventListener('click', () => { angle = 0; slider.value = '0'; rotationValue.textContent = '0°'; tracing = true; tracingToggle.checked = true; drawMode = false; drawToggle.checked = false; canvas.classList.remove('drawing'); strokes = []; shape = 'square'; shapeSelect.value = 'square'; penSize = 4; penSizeInput.value = '4'; penSizeValue.textContent = '4px'; updateInfo(); draw(); });
342
+
343
+ tracingToggle.addEventListener('change', () => { tracing = tracingToggle.checked; draw(); });
344
+
345
+ drawToggle.addEventListener('change', () => { drawMode = drawToggle.checked; penRow.style.display = drawMode ? 'flex' : 'none'; canvas.classList.toggle('drawing', drawMode); if (drawMode) { shape = 'drawing'; shapeSelect.value = 'drawing'; updateInfo(); } draw(); });
346
+
347
+ penSizeInput.addEventListener('input', () => { penSize = Number(penSizeInput.value); penSizeValue.textContent = penSize + 'px'; draw(); });
348
+
349
+ clearDrawingBtn.addEventListener('click', () => { strokes = []; draw(); });
350
+
351
+ document.querySelectorAll('.shape-item').forEach(card => {
352
+ card.addEventListener('click', () => { const val = card.getAttribute('data-shape'); shape = val; shapeSelect.value = val; if (val !== 'drawing') { drawMode = false; drawToggle.checked = false; penRow.style.display = 'none'; canvas.classList.remove('drawing'); } updateInfo(); draw(); });
353
+ });
354
+
355
+ // --- Animate loop ---
356
+ function loop(ts) {
357
+ const dt = Math.min(32, ts - lastTs); lastTs = ts; // ms
358
+ angle = (angle + (dt * 0.12)) % 360; // ~43° per second
359
+ slider.value = String(angle); rotationValue.textContent = Math.round(angle) + '°';
360
+ draw();
361
+ if (animating) rafId = requestAnimationFrame(loop);
362
+ }
363
+
364
+ // --- Info / order ---
365
+ function getOrder(s) {
366
+ switch (s) {
367
+ case 'square': return 4;
368
+ case 'triangle': return 3;
369
+ case 'circle': return '∞';
370
+ case 'rectangle': return 2;
371
+ case 'star': return 5; // regular 5-point star
372
+ case 'hexagon': return 6;
373
+ case 'drawing': return '?';
374
+ }
375
+ }
376
+
377
+ function updateInfo() {
378
+ const ord = getOrder(shape); orderValue.textContent = ord;
379
+ const textMap = {
380
+ square: 'A square looks the same 4 times during a full rotation of 360°.',
381
+ triangle: 'An equilateral triangle matches itself 3 times in 360°.',
382
+ circle: 'A circle looks the same at any angle, so its order is infinite.',
383
+ rectangle: 'A rectangle matches itself 2 times in 360° (every 180°).',
384
+ star: 'A 5-point star matches itself 5 times in 360°.',
385
+ hexagon: 'A regular hexagon matches itself 6 times in 360°.',
386
+ drawing: 'Draw your own shape. The order depends on your design.'
387
+ };
388
+ shapeInfo.textContent = textMap[shape];
389
+ }
390
+
391
+ // --- Init ---
392
+ window.addEventListener('resize', () => { setupCanvas(); draw(); });
393
+ setupCanvas(); updateInfo(); draw();
394
+ </script>
395
+ </body>
396
  </html>