PierreH commited on
Commit
57a23fc
·
verified ·
1 Parent(s): d74aa38

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +203 -20
index.html CHANGED
@@ -1,24 +1,100 @@
1
- function renderKeywords() {
2
- const container = document.getElementById('target-container');
3
- const centerX = container.offsetWidth / 2;
4
- const centerY = container.offsetHeight / 2;
5
- const radius = Math.min(centerX, centerY) * 0.35;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- container.querySelectorAll('.label').forEach(e => e.remove());
 
8
 
9
- keywords.forEach((word, index) => {
 
 
 
 
 
 
 
 
10
  const labelWidth = word.text.length * 8 + 16;
11
  const labelHeight = 24;
12
 
13
  if (word.x === null || word.y === null) {
14
- const angleStep = (2 * Math.PI) / keywords.length;
15
- const angle = index * angleStep - Math.PI / 2;
16
- word.x = centerX + radius * Math.cos(angle) - labelWidth / 2;
17
- word.y = centerY + radius * Math.sin(angle) - labelHeight / 2;
18
  }
19
 
20
  const label = document.createElement('div');
21
- label.className = 'label draggable';
22
  label.style.left = `${word.x}px`;
23
  label.style.top = `${word.y}px`;
24
  label.textContent = word.text;
@@ -26,16 +102,123 @@ function renderKeywords() {
26
 
27
  label.addEventListener('mousedown', (e) => startDrag(e, label, index));
28
  label.addEventListener('touchstart', (e) => {
29
- const touch = e.touches[0];
30
- startDrag(touch, label, index);
31
  });
32
 
33
- if (index === selectedKeywordIndex) {
34
- label.classList.add('selected');
35
- }
36
-
37
  container.appendChild(label);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  });
39
 
40
- resizeCanvas();
41
- }
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html><html lang="fr">
2
+ <head>
3
+ <meta charset="UTF-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <title>Toile Dynamique Minimaliste</title>
6
+ <script src="https://cdn.tailwindcss.com"></script>
7
+ <style>
8
+ .target-container {
9
+ position: relative;
10
+ width: 100%;
11
+ aspect-ratio: 1/1;
12
+ border-radius: 50%;
13
+ overflow: visible;
14
+ }
15
+ .circle { position: absolute; border-radius: 50%; z-index: 1; }
16
+ .circle1 { background-color: #fecaca; width: 8%; height: 8%; top: 46%; left: 46%; }
17
+ .circle2 { background-color: #fed7aa; width: 20%; height: 20%; top: 40%; left: 40%; }
18
+ .circle3 { background-color: #fef08a; width: 35%; height: 35%; top: 32.5%; left: 32.5%; }
19
+ .circle4 { background-color: #bbf7d0; width: 55%; height: 55%; top: 22.5%; left: 22.5%; }
20
+ .circle5 { background-color: #bfdbfe; width: 75%; height: 75%; top: 12.5%; left: 12.5%; }.label {
21
+ position: absolute;
22
+ font-weight: bold;
23
+ font-size: 0.75rem;
24
+ color: #333;
25
+ cursor: pointer;
26
+ user-select: none;
27
+ white-space: nowrap;
28
+ z-index: 7;
29
+ padding: 0.25rem 0.5rem;
30
+ background-color: rgba(255, 255, 255, 0.85);
31
+ border-radius: 0.25rem;
32
+ transition: all 0.2s ease;
33
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
34
+ }
35
+ .label:hover { transform: scale(1.05); background-color: rgba(255,255,255,0.95); }
36
+ .label.selected { background-color: #3b82f6; color: white; transform: scale(1.1); }
37
+
38
+ #canvas {
39
+ position: absolute;
40
+ top: 0; left: 0;
41
+ width: 100%; height: 100%;
42
+ z-index: 6;
43
+ pointer-events: none;
44
+ }
45
+
46
+ </style>
47
+ </head>
48
+ <body class="bg-gray-50 min-h-screen flex flex-col items-center justify-center p-4">
49
+ <div class="w-full max-w-md bg-white rounded-xl shadow-md p-6 space-y-6">
50
+ <h1 class="text-xl font-bold text-center text-gray-700">☆ Mon Étoile de Mots ☆</h1>
51
+ <textarea id="editKeyword" class="w-full p-2 rounded-lg border" placeholder="Modifier le mot sélectionné..."></textarea>
52
+ <div class="target-container bg-white shadow-inner" id="target-container">
53
+ <canvas id="canvas"></canvas>
54
+ <div class="circle circle5"></div>
55
+ <div class="circle circle4"></div>
56
+ <div class="circle circle3"></div>
57
+ <div class="circle circle2"></div>
58
+ <div class="circle circle1"></div>
59
+ </div>
60
+ </div> <script>
61
+ let keywords = [
62
+ { text: "Identification", x: null, y: null },
63
+ { text: "Gestion", x: null, y: null },
64
+ { text: "Adaptation", x: null, y: null },
65
+ { text: "Autonomie", x: null, y: null }
66
+ ];
67
+
68
+ let selectedKeywordIndex = null;
69
+ let isDragging = false;
70
+ let dragStartX, dragStartY;
71
+ let draggedLabel = null;
72
+ let draggedIndex = null;
73
 
74
+ const canvas = document.getElementById('canvas');
75
+ const ctx = canvas.getContext('2d');
76
 
77
+ function renderKeywords() {
78
+ const container = document.getElementById('target-container');
79
+ const centerX = container.offsetWidth / 2;
80
+ const centerY = container.offsetHeight / 2;
81
+ const radius = Math.min(centerX, centerY) * 0.35;
82
+
83
+ container.querySelectorAll('.label').forEach(e => e.remove());
84
+
85
+ keywords.forEach((word, index) => {
86
  const labelWidth = word.text.length * 8 + 16;
87
  const labelHeight = 24;
88
 
89
  if (word.x === null || word.y === null) {
90
+ const angleStep = (2 * Math.PI) / keywords.length;
91
+ const angle = index * angleStep - Math.PI / 2;
92
+ word.x = centerX + radius * Math.cos(angle) - labelWidth / 2;
93
+ word.y = centerY + radius * Math.sin(angle) - labelHeight / 2;
94
  }
95
 
96
  const label = document.createElement('div');
97
+ label.className = 'label';
98
  label.style.left = `${word.x}px`;
99
  label.style.top = `${word.y}px`;
100
  label.textContent = word.text;
 
102
 
103
  label.addEventListener('mousedown', (e) => startDrag(e, label, index));
104
  label.addEventListener('touchstart', (e) => {
105
+ const touch = e.touches[0];
106
+ startDrag(touch, label, index);
107
  });
108
 
109
+ if (index === selectedKeywordIndex) label.classList.add('selected');
 
 
 
110
  container.appendChild(label);
111
+ });
112
+
113
+ resizeCanvas();
114
+ }
115
+
116
+ function startDrag(e, label, index) {
117
+ isDragging = true;
118
+ draggedLabel = label;
119
+ draggedIndex = index;
120
+ dragStartX = e.clientX - parseFloat(label.style.left);
121
+ dragStartY = e.clientY - parseFloat(label.style.top);
122
+ selectKeyword(index);
123
+
124
+ document.addEventListener('mousemove', drag);
125
+ document.addEventListener('mouseup', stopDrag);
126
+ e.preventDefault();
127
+ }
128
+
129
+ function drag(e) {
130
+ if (!isDragging) return;
131
+
132
+ const container = document.getElementById('target-container');
133
+ let newX = e.clientX - dragStartX;
134
+ let newY = e.clientY - dragStartY;
135
+
136
+ newX = Math.max(0, Math.min(newX, container.offsetWidth - draggedLabel.offsetWidth));
137
+ newY = Math.max(0, Math.min(newY, container.offsetHeight - draggedLabel.offsetHeight));
138
+
139
+ draggedLabel.style.left = `${newX}px`;
140
+ draggedLabel.style.top = `${newY}px`;
141
+
142
+ keywords[draggedIndex].x = newX;
143
+ keywords[draggedIndex].y = newY;
144
+
145
+ resizeCanvas();
146
+ }
147
+
148
+ function stopDrag() {
149
+ isDragging = false;
150
+ draggedLabel = null;
151
+ draggedIndex = null;
152
+
153
+ document.removeEventListener('mousemove', drag);
154
+ document.removeEventListener('mouseup', stopDrag);
155
+ }
156
+
157
+ function selectKeyword(index) {
158
+ selectedKeywordIndex = index;
159
+ document.getElementById('editKeyword').value = keywords[index].text;
160
+ document.querySelectorAll('.label').forEach(label => label.classList.remove('selected'));
161
+ const selectedLabel = document.querySelector(`.label[data-index='${index}']`);
162
+ if (selectedLabel) selectedLabel.classList.add('selected');
163
+ }
164
+
165
+ function deselectKeyword() {
166
+ selectedKeywordIndex = null;
167
+ document.getElementById('editKeyword').value = '';
168
+ document.querySelectorAll('.label').forEach(label => label.classList.remove('selected'));
169
+ }
170
+
171
+ function resizeCanvas() {
172
+ const container = document.getElementById('target-container');
173
+ canvas.width = container.offsetWidth;
174
+ canvas.height = container.offsetHeight;
175
+ drawLines();
176
+ }
177
+
178
+ function drawLines() {
179
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
180
+ if (keywords.length < 2) return;
181
+
182
+ ctx.beginPath();
183
+ ctx.strokeStyle = '#3b82f6';
184
+ ctx.lineWidth = 1;
185
+ ctx.setLineDash([5, 3]);
186
+
187
+ const positions = keywords.map((k, i) => {
188
+ const label = document.querySelector(`.label[data-index='${i}']`);
189
+ return {
190
+ x: k.x + (label?.offsetWidth || 0) / 2,
191
+ y: k.y + (label?.offsetHeight || 0) / 2
192
+ };
193
+ });
194
+
195
+ for (let i = 0; i < positions.length; i++) {
196
+ const next = positions[(i + 1) % positions.length];
197
+ ctx.moveTo(positions[i].x, positions[i].y);
198
+ ctx.lineTo(next.x, next.y);
199
+ }
200
+
201
+ ctx.stroke();
202
+ }
203
+
204
+ document.addEventListener('DOMContentLoaded', () => {
205
+ renderKeywords();
206
+
207
+ document.addEventListener('click', (e) => {
208
+ if (!e.target.classList.contains('label') && !e.target.closest('.label')) {
209
+ deselectKeyword();
210
+ }
211
+ });
212
  });
213
 
214
+ document.addEventListener('touchmove', function(e) {
215
+ if (isDragging) {
216
+ const touch = e.touches[0];
217
+ drag(touch);
218
+ e.preventDefault();
219
+ }
220
+ }, { passive: false });
221
+
222
+ document.addEventListener('touchend', stopDrag);
223
+ </script></body>
224
+ </html>