GUZBOMB commited on
Commit
352594e
·
verified ·
1 Parent(s): 0b78b50

are you able to make small edits - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +393 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Route Visual V1 Sample Fix
3
- emoji: 😻
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: route-visual-v1-sample-fix
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: purple
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,393 @@
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
+ <title>Football Route Visualizer</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .field {
11
+ background-color: #3a5f0b;
12
+ position: relative;
13
+ overflow: hidden;
14
+ }
15
+ .yard-line {
16
+ position: absolute;
17
+ width: 2px;
18
+ background-color: white;
19
+ height: 100%;
20
+ top: 0;
21
+ }
22
+ .yard-number {
23
+ position: absolute;
24
+ color: white;
25
+ font-weight: bold;
26
+ font-size: 12px;
27
+ transform: translateX(-50%);
28
+ }
29
+ .hash-mark {
30
+ position: absolute;
31
+ width: 10px;
32
+ height: 2px;
33
+ background-color: white;
34
+ }
35
+ .player {
36
+ transition: all 0.5s ease;
37
+ }
38
+ .route-path {
39
+ stroke-dasharray: 1000;
40
+ stroke-dashoffset: 1000;
41
+ animation: dash 2s linear forwards;
42
+ }
43
+ @keyframes dash {
44
+ to {
45
+ stroke-dashoffset: 0;
46
+ }
47
+ }
48
+ </style>
49
+ </head>
50
+ <body class="bg-gray-100">
51
+ <div class="container mx-auto px-4 py-8">
52
+ <header class="text-center mb-8">
53
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">Football Route Visualizer</h1>
54
+ <p class="text-lg text-gray-600">Interactive tool to understand receiver route concepts</p>
55
+ </header>
56
+
57
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
58
+ <!-- Route Selection Panel -->
59
+ <div class="bg-white rounded-lg shadow-md p-6">
60
+ <h2 class="text-2xl font-semibold mb-4 text-gray-800">Route Concepts</h2>
61
+
62
+ <div class="space-y-4">
63
+ <div class="grid grid-cols-2 gap-3">
64
+ <button onclick="showRoute('go')" class="route-btn bg-blue-100 hover:bg-blue-200 text-blue-800 py-2 px-4 rounded-lg transition">
65
+ <i class="fas fa-arrow-up mr-2"></i> Go Route
66
+ </button>
67
+ <button onclick="showRoute('slant')" class="route-btn bg-green-100 hover:bg-green-200 text-green-800 py-2 px-4 rounded-lg transition">
68
+ <i class="fas fa-arrow-up-right mr-2"></i> Slant
69
+ </button>
70
+ <button onclick="showRoute('curl')" class="route-btn bg-purple-100 hover:bg-purple-200 text-purple-800 py-2 px-4 rounded-lg transition">
71
+ <i class="fas fa-undo mr-2"></i> Curl
72
+ </button>
73
+ <button onclick="showRoute('out')" class="route-btn bg-yellow-100 hover:bg-yellow-200 text-yellow-800 py-2 px-4 rounded-lg transition">
74
+ <i class="fas fa-arrow-right mr-2"></i> Out Route
75
+ </button>
76
+ <button onclick="showRoute('post')" class="route-btn bg-red-100 hover:bg-red-200 text-red-800 py-2 px-4 rounded-lg transition">
77
+ <i class="fas fa-long-arrow-alt-up mr-2"></i> Post
78
+ </button>
79
+ <button onclick="showRoute('corner')" class="route-btn bg-indigo-100 hover:bg-indigo-200 text-indigo-800 py-2 px-4 rounded-lg transition">
80
+ <i class="fas fa-arrow-up-right mr-2"></i> Corner
81
+ </button>
82
+ </div>
83
+
84
+ <div class="pt-4 border-t border-gray-200">
85
+ <h3 class="font-medium text-gray-700 mb-2">Route Combinations</h3>
86
+ <div class="grid grid-cols-1 gap-3">
87
+ <button onclick="showRoute('smash')" class="route-btn bg-gray-100 hover:bg-gray-200 text-gray-800 py-2 px-4 rounded-lg transition">
88
+ Smash Concept
89
+ </button>
90
+ <button onclick="showRoute('levels')" class="route-btn bg-gray-100 hover:bg-gray-200 text-gray-800 py-2 px-4 rounded-lg transition">
91
+ Levels Concept
92
+ </button>
93
+ <button onclick="showRoute('mesh')" class="route-btn bg-gray-100 hover:bg-gray-200 text-gray-800 py-2 px-4 rounded-lg transition">
94
+ Mesh Concept
95
+ </button>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </div>
100
+
101
+ <!-- Football Field Visualization -->
102
+ <div class="lg:col-span-2">
103
+ <div class="bg-white rounded-lg shadow-md p-4">
104
+ <div class="flex justify-between items-center mb-4">
105
+ <h2 class="text-2xl font-semibold text-gray-800">Route Visualization</h2>
106
+ <div class="flex space-x-2">
107
+ <button onclick="resetField()" class="bg-gray-200 hover:bg-gray-300 text-gray-800 py-1 px-3 rounded-lg text-sm transition">
108
+ <i class="fas fa-redo mr-1"></i> Reset
109
+ </button>
110
+ <button onclick="toggleAnimation()" class="bg-gray-200 hover:bg-gray-300 text-gray-800 py-1 px-3 rounded-lg text-sm transition">
111
+ <i class="fas fa-play mr-1"></i> Animate
112
+ </button>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="field rounded-lg relative" style="height: 500px;">
117
+ <!-- Football field elements will be added here by JavaScript -->
118
+ <svg id="route-svg" width="100%" height="100%" style="position: absolute; top: 0; left: 0;"></svg>
119
+
120
+ <!-- Players -->
121
+ <div id="qb" class="player absolute w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 50px; left: 50%; transform: translateX(-50%);">QB</div>
122
+
123
+ <div id="wr1" class="player absolute w-8 h-8 bg-red-500 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 150px; left: 20%;">WR1</div>
124
+ <div id="wr2" class="player absolute w-8 h-8 bg-red-500 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 150px; left: 40%;">WR2</div>
125
+ <div id="wr3" class="player absolute w-8 h-8 bg-red-500 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 150px; left: 60%;">WR3</div>
126
+ <div id="wr4" class="player absolute w-8 h-8 bg-red-500 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 150px; left: 80%;">WR4</div>
127
+
128
+ <!-- Defense -->
129
+ <div id="cb1" class="player absolute w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 200px; left: 20%; opacity: 0.7;">CB</div>
130
+ <div id="cb2" class="player absolute w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 200px; left: 40%; opacity: 0.7;">CB</div>
131
+ <div id="cb3" class="player absolute w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 200px; left: 60%; opacity: 0.7;">CB</div>
132
+ <div id="cb4" class="player absolute w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center text-white font-bold" style="bottom: 200px; left: 80%; opacity: 0.7;">CB</div>
133
+ </div>
134
+
135
+ <div id="route-description" class="mt-4 p-4 bg-gray-50 rounded-lg">
136
+ <h3 class="font-semibold text-lg text-gray-800 mb-2">Route Information</h3>
137
+ <p class="text-gray-600">Select a route from the panel to see visualization and details.</p>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ <script>
145
+ // Initialize field markings
146
+ document.addEventListener('DOMContentLoaded', function() {
147
+ drawField();
148
+ });
149
+
150
+ function drawField() {
151
+ const field = document.querySelector('.field');
152
+ const width = field.offsetWidth;
153
+ const height = field.offsetHeight;
154
+
155
+ // Draw yard lines
156
+ for (let i = 0; i <= 100; i += 5) {
157
+ const yardLine = document.createElement('div');
158
+ yardLine.className = 'yard-line';
159
+ yardLine.style.left = `${(i / 100) * 100}%`;
160
+
161
+ // Add yard numbers every 10 yards
162
+ if (i % 10 === 0 && i > 0 && i < 100) {
163
+ const yardNumber = document.createElement('div');
164
+ yardNumber.className = 'yard-number';
165
+ yardNumber.style.left = `${(i / 100) * 100}%`;
166
+ yardNumber.style.top = '10px';
167
+ yardNumber.textContent = i;
168
+ field.appendChild(yardNumber);
169
+
170
+ const yardNumberBottom = document.createElement('div');
171
+ yardNumberBottom.className = 'yard-number';
172
+ yardNumberBottom.style.left = `${(i / 100) * 100}%`;
173
+ yardNumberBottom.style.bottom = '10px';
174
+ yardNumberBottom.textContent = i;
175
+ field.appendChild(yardNumberBottom);
176
+ }
177
+
178
+ field.appendChild(yardLine);
179
+ }
180
+
181
+ // Draw hash marks (simplified)
182
+ for (let i = 10; i < 100; i += 5) {
183
+ const hashTop = document.createElement('div');
184
+ hashTop.className = 'hash-mark';
185
+ hashTop.style.left = `${(i / 100) * 100}%`;
186
+ hashTop.style.top = '30%';
187
+ field.appendChild(hashTop);
188
+
189
+ const hashBottom = document.createElement('div');
190
+ hashBottom.className = 'hash-mark';
191
+ hashBottom.style.left = `${(i / 100) * 100}%`;
192
+ hashBottom.style.bottom = '30%';
193
+ field.appendChild(hashBottom);
194
+ }
195
+ }
196
+
197
+ // Route visualization functions
198
+ function showRoute(routeType) {
199
+ resetField();
200
+ const svg = document.getElementById('route-svg');
201
+ svg.innerHTML = '';
202
+
203
+ // Highlight selected route button
204
+ document.querySelectorAll('.route-btn').forEach(btn => {
205
+ btn.classList.remove('ring-2', 'ring-blue-500');
206
+ });
207
+ event.target.classList.add('ring-2', 'ring-blue-500');
208
+
209
+ // Route descriptions
210
+ const descriptions = {
211
+ 'go': {
212
+ text: 'The Go Route (or Fly Route) is a straight sprint downfield. The receiver aims to get behind the defender for a deep pass. Key points: Explode off the line, maintain speed, track the ball over your shoulder.',
213
+ color: 'blue'
214
+ },
215
+ 'slant': {
216
+ text: 'The Slant Route is a quick inside cut at about 5 yards. The receiver takes 3 hard steps forward then cuts at a 45-degree angle. Key points: Sharp cut, protect the ball in traffic, find the open window.',
217
+ color: 'green'
218
+ },
219
+ 'curl': {
220
+ text: 'The Curl Route is a deep out-and-back move. The receiver runs 10-12 yards downfield then turns back toward the QB. Key points: Sell the go route first, plant hard on the back foot, create separation.',
221
+ color: 'purple'
222
+ },
223
+ 'out': {
224
+ text: 'The Out Route is a 90-degree cut toward the sideline at 5-10 yards. The receiver runs vertically then makes a sharp outside cut. Key points: Depth depends on QB arm strength, keep feet in bounds, accelerate out of break.',
225
+ color: 'yellow'
226
+ },
227
+ 'post': {
228
+ text: 'The Post Route is a deep diagonal cut toward the goalposts. The receiver runs 10-15 yards then cuts at a 45-degree angle toward the middle. Key points: Sell the go route first, maintain speed through cut, track the deep ball.',
229
+ color: 'red'
230
+ },
231
+ 'corner': {
232
+ text: 'The Corner Route is a deep outside cut toward the corner of the end zone. The receiver runs 10-15 yards then cuts at a 45-degree angle toward the sideline. Key points: Sell the post route first, create separation with speed change.',
233
+ color: 'indigo'
234
+ },
235
+ 'smash': {
236
+ text: 'The Smash Concept combines a short corner route (5-7 yards) with a deeper curl (12-15 yards). This creates a high-low read for the QB against zone coverage. The corner route occupies the flat defender while the curl works behind.',
237
+ color: 'gray'
238
+ },
239
+ 'levels': {
240
+ text: 'The Levels Concept uses multiple receivers running crossing routes at different depths (typically 5 and 10 yards). This stretches zone coverage vertically and creates natural picks against man coverage.',
241
+ color: 'gray'
242
+ },
243
+ 'mesh': {
244
+ text: 'The Mesh Concept has two receivers crossing close to the line of scrimmage (3-5 yards depth) while other receivers clear out. The crossing routes create natural picks and confusion in man coverage.',
245
+ color: 'gray'
246
+ }
247
+ };
248
+
249
+ // Update description
250
+ const descDiv = document.getElementById('route-description');
251
+ descDiv.innerHTML = `
252
+ <h3 class="font-semibold text-lg text-gray-800 mb-2">${routeType.charAt(0).toUpperCase() + routeType.slice(1)} Route</h3>
253
+ <p class="text-gray-600">${descriptions[routeType].text}</p>
254
+ `;
255
+
256
+ // Draw routes based on type
257
+ const routeColor = descriptions[routeType].color;
258
+
259
+ switch(routeType) {
260
+ case 'go':
261
+ drawPath(svg, 20, 150, 20, 50, routeColor);
262
+ animatePlayer('wr1', 20, 150, 20, 50);
263
+ break;
264
+ case 'slant':
265
+ drawPath(svg, 20, 150, 40, 100, routeColor);
266
+ animatePlayer('wr1', 20, 150, 40, 100);
267
+ break;
268
+ case 'curl':
269
+ drawPath(svg, 40, 150, 40, 100, routeColor);
270
+ drawPath(svg, 40, 100, 30, 100, routeColor);
271
+ animatePlayer('wr2', 40, 150, 40, 100, () => {
272
+ animatePlayer('wr2', 40, 100, 30, 100);
273
+ });
274
+ break;
275
+ case 'out':
276
+ drawPath(svg, 60, 150, 60, 100, routeColor);
277
+ drawPath(svg, 60, 100, 80, 100, routeColor);
278
+ animatePlayer('wr3', 60, 150, 60, 100, () => {
279
+ animatePlayer('wr3', 60, 100, 80, 100);
280
+ });
281
+ break;
282
+ case 'post':
283
+ drawPath(svg, 80, 150, 80, 80, routeColor);
284
+ drawPath(svg, 80, 80, 60, 50, routeColor);
285
+ animatePlayer('wr4', 80, 150, 80, 80, () => {
286
+ animatePlayer('wr4', 80, 80, 60, 50);
287
+ });
288
+ break;
289
+ case 'corner':
290
+ drawPath(svg, 20, 150, 20, 80, routeColor);
291
+ drawPath(svg, 20, 80, 40, 50, routeColor);
292
+ animatePlayer('wr1', 20, 150, 20, 80, () => {
293
+ animatePlayer('wr1', 20, 80, 40, 50);
294
+ });
295
+ break;
296
+ case 'smash':
297
+ // WR1 runs corner
298
+ drawPath(svg, 20, 150, 20, 120, routeColor);
299
+ drawPath(svg, 20, 120, 40, 100, routeColor);
300
+ // WR2 runs curl
301
+ drawPath(svg, 40, 150, 40, 100, routeColor);
302
+ drawPath(svg, 40, 100, 30, 100, routeColor);
303
+
304
+ animatePlayer('wr1', 20, 150, 20, 120, () => {
305
+ animatePlayer('wr1', 20, 120, 40, 100);
306
+ });
307
+ animatePlayer('wr2', 40, 150, 40, 100, () => {
308
+ animatePlayer('wr2', 40, 100, 30, 100);
309
+ });
310
+ break;
311
+ case 'levels':
312
+ // WR1 runs shallow cross
313
+ drawPath(svg, 20, 150, 80, 130, routeColor);
314
+ // WR2 runs medium cross
315
+ drawPath(svg, 40, 150, 60, 100, routeColor);
316
+
317
+ animatePlayer('wr1', 20, 150, 80, 130);
318
+ animatePlayer('wr2', 40, 150, 60, 100);
319
+ break;
320
+ case 'mesh':
321
+ // WR1 runs left to right
322
+ drawPath(svg, 20, 150, 80, 130, routeColor);
323
+ // WR2 runs right to left
324
+ drawPath(svg, 80, 150, 20, 130, routeColor);
325
+
326
+ animatePlayer('wr1', 20, 150, 80, 130);
327
+ animatePlayer('wr2', 80, 150, 20, 130);
328
+ break;
329
+ }
330
+ }
331
+
332
+ function drawPath(svg, x1, y1, x2, y2, color) {
333
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
334
+ path.setAttribute('d', `M ${x1}% ${y1} L ${x2}% ${y2}`);
335
+ path.setAttribute('stroke', color);
336
+ path.setAttribute('stroke-width', '3');
337
+ path.setAttribute('fill', 'none');
338
+ path.classList.add('route-path');
339
+ svg.appendChild(path);
340
+ }
341
+
342
+ function animatePlayer(playerId, startX, startY, endX, endY, callback) {
343
+ const player = document.getElementById(playerId);
344
+ player.style.left = `${startX}%`;
345
+ player.style.bottom = `${startY}px`;
346
+
347
+ setTimeout(() => {
348
+ player.style.left = `${endX}%`;
349
+ player.style.bottom = `${endY}px`;
350
+
351
+ if (callback) {
352
+ setTimeout(callback, 1000);
353
+ }
354
+ }, 100);
355
+ }
356
+
357
+ function resetField() {
358
+ const svg = document.getElementById('route-svg');
359
+ svg.innerHTML = '';
360
+
361
+ // Reset players to starting positions
362
+ document.getElementById('wr1').style.left = '20%';
363
+ document.getElementById('wr1').style.bottom = '150px';
364
+
365
+ document.getElementById('wr2').style.left = '40%';
366
+ document.getElementById('wr2').style.bottom = '150px';
367
+
368
+ document.getElementById('wr3').style.left = '60%';
369
+ document.getElementById('wr3').style.bottom = '150px';
370
+
371
+ document.getElementById('wr4').style.left = '80%';
372
+ document.getElementById('wr4').style.bottom = '150px';
373
+
374
+ // Reset description
375
+ document.getElementById('route-description').innerHTML = `
376
+ <h3 class="font-semibold text-lg text-gray-800 mb-2">Route Information</h3>
377
+ <p class="text-gray-600">Select a route from the panel to see visualization and details.</p>
378
+ `;
379
+ }
380
+
381
+ function toggleAnimation() {
382
+ const paths = document.querySelectorAll('.route-path');
383
+ paths.forEach(path => {
384
+ if (path.style.animationPlayState === 'paused') {
385
+ path.style.animationPlayState = 'running';
386
+ } else {
387
+ path.style.animationPlayState = 'paused';
388
+ }
389
+ });
390
+ }
391
+ </script>
392
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=GUZBOMB/route-visual-v1-sample-fix" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
393
+ </html>