j1225d commited on
Commit
2204142
·
verified ·
1 Parent(s): 840b422

In the share image - Duration, Calories, Exercises, and Progress need to be centered inside their respective boxes along with the emoji. The progress completion ring needs to be lower, positioned under all the boxes. - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +175 -42
index.html CHANGED
@@ -288,73 +288,206 @@
288
  canvas.width = 1080;
289
  canvas.height = 1080;
290
 
291
- // Draw gradient background
292
- const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
293
- gradient.addColorStop(0, '#1a1a2e');
 
 
 
 
294
  gradient.addColorStop(1, '#16213e');
295
  ctx.fillStyle = gradient;
296
  ctx.fillRect(0, 0, canvas.width, canvas.height);
297
 
298
- // Add gold decorative elements
299
- ctx.fillStyle = 'rgba(212, 175, 55, 0.1)';
300
- for (let i = 0; i < 5; i++) {
 
 
 
301
  ctx.beginPath();
302
- ctx.arc(
303
- Math.random() * canvas.width,
304
- Math.random() * canvas.height,
305
- Math.random() * 100 + 50,
306
- 0,
307
- Math.PI * 2
308
- );
309
  ctx.fill();
310
  }
311
 
312
- // Add title with better typography
 
 
313
  ctx.fillStyle = '#f9d423';
314
- ctx.font = 'bold 72px "Arial", sans-serif';
315
  ctx.textAlign = 'center';
316
  ctx.textBaseline = 'middle';
317
 
318
- // Main title
319
- ctx.fillText('WORKOUT COMPLETE', canvas.width/2, 150);
 
 
 
 
 
 
 
 
320
 
321
- // Stats container
322
- ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
323
- ctx.font = 'bold 42px "Arial", sans-serif';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
 
325
- // Stats with icons
326
  const stats = [
327
- { icon: '⏱️', text: 'Duration: 45:22 (+2:18)' },
328
- { icon: '🔥', text: 'Calories: 412 (New Record!)' },
329
- { icon: '💪', text: 'Exercises: 8 (+1 new)' },
330
- { icon: '📈', text: 'Weekly Progress: 3/5 (60%)' }
331
  ];
332
 
 
 
 
 
 
333
  stats.forEach((stat, i) => {
334
- const y = 300 + i * 100;
335
- ctx.fillText(`${stat.icon} ${stat.text}`, canvas.width/2, y);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  });
337
 
338
- // Progress bar
339
- ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
340
- ctx.fillRect(canvas.width/2 - 200, 700, 400, 30);
341
- ctx.fillStyle = '#f9d423';
342
- ctx.fillRect(canvas.width/2 - 200, 700, 400 * 0.6, 30);
343
 
344
- // Motivational quote
345
- ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
346
- ctx.font = 'italic 32px "Arial", sans-serif';
347
- ctx.fillText('"Strength grows in the moments', canvas.width/2, 800);
348
- ctx.fillText('when you think you can\'t go on"', canvas.width/2, 850);
 
349
 
350
- // Logo and branding
351
- ctx.fillStyle = '#f9d423';
 
 
 
 
 
 
 
 
352
  ctx.font = 'bold 36px "Arial", sans-serif';
353
- ctx.fillText('KINTSUGI FITNESS', canvas.width/2, 950);
 
 
 
 
 
 
 
 
 
354
 
355
- ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  ctx.font = '24px "Arial", sans-serif';
357
- ctx.fillText('Your journey, beautifully imperfect', canvas.width/2, 1000);
 
 
 
 
 
 
 
 
 
 
358
 
359
  // Convert canvas to image and download
360
  canvas.toBlob((blob) => {
 
288
  canvas.width = 1080;
289
  canvas.height = 1080;
290
 
291
+ // Draw dynamic gradient background
292
+ const gradient = ctx.createRadialGradient(
293
+ canvas.width/2, canvas.height/2, 0,
294
+ canvas.width/2, canvas.height/2, canvas.width
295
+ );
296
+ gradient.addColorStop(0, '#000000');
297
+ gradient.addColorStop(0.7, '#1a1a2e');
298
  gradient.addColorStop(1, '#16213e');
299
  ctx.fillStyle = gradient;
300
  ctx.fillRect(0, 0, canvas.width, canvas.height);
301
 
302
+ // Add energetic gold particles
303
+ ctx.fillStyle = 'rgba(212, 175, 55, 0.3)';
304
+ for (let i = 0; i < 150; i++) {
305
+ const size = Math.random() * 5 + 2;
306
+ const x = Math.random() * canvas.width;
307
+ const y = Math.random() * canvas.height;
308
  ctx.beginPath();
309
+ ctx.arc(x, y, size, 0, Math.PI * 2);
 
 
 
 
 
 
310
  ctx.fill();
311
  }
312
 
313
+ // Add glowing title effect (adjusted font size for better fit)
314
+ ctx.shadowColor = '#f9d423';
315
+ ctx.shadowBlur = 30;
316
  ctx.fillStyle = '#f9d423';
317
+ ctx.font = 'bold 70px "Arial", sans-serif';
318
  ctx.textAlign = 'center';
319
  ctx.textBaseline = 'middle';
320
 
321
+ // Measure text width and adjust if needed
322
+ const titleText = '🔥 WORKOUT COMPLETE 🔥';
323
+ const maxTitleWidth = canvas.width - 100;
324
+ let titleFontSize = 70;
325
+
326
+ // Scale down if too wide
327
+ while (ctx.measureText(titleText).width > maxTitleWidth && titleFontSize > 40) {
328
+ titleFontSize -= 2;
329
+ ctx.font = `bold ${titleFontSize}px "Arial", sans-serif`;
330
+ }
331
 
332
+ ctx.fillText(titleText, canvas.width/2, 120);
333
+ ctx.shadowBlur = 0;
334
+
335
+ // Add animated burst effect behind title
336
+ ctx.fillStyle = 'rgba(249, 212, 35, 0.2)';
337
+ for (let i = 0; i < 8; i++) {
338
+ const angle = (i / 8) * Math.PI * 2;
339
+ const length = 150;
340
+ const x1 = canvas.width/2;
341
+ const y1 = canvas.height/2 - 180;
342
+ const x2 = x1 + Math.cos(angle) * length;
343
+ const y2 = y1 + Math.sin(angle) * length;
344
+
345
+ const gradient = ctx.createLinearGradient(x1, y1, x2, y2);
346
+ gradient.addColorStop(0, 'rgba(249, 212, 35, 0.3)');
347
+ gradient.addColorStop(1, 'rgba(249, 212, 35, 0)');
348
+
349
+ ctx.fillStyle = gradient;
350
+ ctx.beginPath();
351
+ ctx.moveTo(x1, y1);
352
+ ctx.lineTo(x2, y2);
353
+ ctx.lineTo(x2 + Math.cos(angle + 0.2) * 20, y2 + Math.sin(angle + 0.2) * 20);
354
+ ctx.lineTo(x2 + Math.cos(angle - 0.2) * 20, y2 + Math.sin(angle - 0.2) * 20);
355
+ ctx.closePath();
356
+ ctx.fill();
357
+ }
358
 
359
+ // Stats container with perfectly fitted cards
360
  const stats = [
361
+ { icon: '⏱️', text: 'Duration', value: '45:22', change: '+2:18' },
362
+ { icon: '🔥', text: 'Calories', value: '412', change: 'Record!' },
363
+ { icon: '💪', text: 'Exercises', value: '8', change: '+1 new' },
364
+ { icon: '📈', text: 'Progress', value: '3/5', change: '60%' }
365
  ];
366
 
367
+ const cardWidth = 220; // Adjusted width for better fit
368
+ const cardHeight = 140; // Adjusted height for better fit
369
+ const cardPadding = 20;
370
+ const startX = (canvas.width - (cardWidth * 2 + 30)) / 2; // Centered with proper spacing
371
+
372
  stats.forEach((stat, i) => {
373
+ const row = Math.floor(i / 2);
374
+ const col = i % 2;
375
+ const x = startX + col * (cardWidth + 40);
376
+ const y = 220 + row * (cardHeight + 20);
377
+
378
+ // Card background
379
+ ctx.fillStyle = 'rgba(40, 40, 60, 0.8)';
380
+ ctx.beginPath();
381
+ ctx.roundRect(x, y, cardWidth, cardHeight, 20);
382
+ ctx.fill();
383
+
384
+ // Gold border effect
385
+ ctx.strokeStyle = 'rgba(212, 175, 55, 0.5)';
386
+ ctx.lineWidth = 3;
387
+ ctx.beginPath();
388
+ ctx.roundRect(x, y, cardWidth, cardHeight, 20);
389
+ ctx.stroke();
390
+
391
+ // Card content with perfect alignment
392
+ ctx.fillStyle = '#f9d423';
393
+ ctx.font = 'bold 28px "Arial", sans-serif';
394
+ const iconX = x + (cardWidth - ctx.measureText(stat.icon).width) / 2;
395
+ ctx.fillText(stat.icon, iconX, y + 40);
396
+
397
+ // Stat label (centered)
398
+ ctx.fillStyle = '#ffffff';
399
+ ctx.font = 'bold 18px "Arial", sans-serif';
400
+ const maxTextWidth = cardWidth - 40;
401
+ let textSize = 18;
402
+
403
+ // Ensure text fits perfectly
404
+ while (ctx.measureText(stat.text).width > maxTextWidth && textSize > 12) {
405
+ textSize -= 1;
406
+ ctx.font = `bold ${textSize}px "Arial", sans-serif`;
407
+ }
408
+ const labelX = x + (cardWidth - ctx.measureText(stat.text).width) / 2;
409
+ ctx.fillText(stat.text, labelX, y + 40);
410
+
411
+ // Main value (centered)
412
+ ctx.fillStyle = '#f9d423';
413
+ ctx.font = 'bold 32px "Arial", sans-serif';
414
+ const valueX = x + (cardWidth - ctx.measureText(stat.value).width) / 2;
415
+ ctx.fillText(stat.value, valueX, y + 90);
416
+
417
+ // Change indicator (centered below value)
418
+ ctx.fillStyle = '#4ade80';
419
+ ctx.font = 'bold 16px "Arial", sans-serif';
420
+ const changeText = stat.change.length > 10 ? stat.change.substring(0, 8) + '...' : stat.change;
421
+ const changeX = x + (cardWidth - ctx.measureText(changeText).width) / 2;
422
+ ctx.fillText(changeText, changeX, y + 120);
423
  });
424
 
425
+ // Circular progress chart
426
+ const progressX = canvas.width/2;
427
+ const progressY = 600;
428
+ const radius = 100;
429
+ const progress = 0.6; // 60%
430
 
431
+ // Background circle
432
+ ctx.beginPath();
433
+ ctx.arc(progressX, progressY, radius, 0, Math.PI * 2);
434
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
435
+ ctx.lineWidth = 20;
436
+ ctx.stroke();
437
 
438
+ // Progress arc
439
+ ctx.beginPath();
440
+ ctx.arc(progressX, progressY, radius, -Math.PI/2, -Math.PI/2 + Math.PI * 2 * progress);
441
+ ctx.strokeStyle = '#f9d423';
442
+ ctx.lineWidth = 20;
443
+ ctx.lineCap = 'round';
444
+ ctx.stroke();
445
+
446
+ // Progress text
447
+ ctx.fillStyle = '#ffffff';
448
  ctx.font = 'bold 36px "Arial", sans-serif';
449
+ ctx.fillText(`${Math.round(progress * 100)}%`, progressX, progressY);
450
+
451
+ // Perfectly centered motivational text
452
+ ctx.shadowColor = '#f9d423';
453
+ ctx.shadowBlur = 15;
454
+ ctx.fillStyle = '#ffffff';
455
+
456
+ const motivationalText = 'CRUSHED IT!';
457
+ let motivationalSize = 36;
458
+ ctx.font = `italic ${motivationalSize}px "Arial", sans-serif`;
459
 
460
+ // Ensure perfect fit
461
+ while (ctx.measureText(motivationalText).width > canvas.width - 120 && motivationalSize > 24) {
462
+ motivationalSize -= 2;
463
+ ctx.font = `italic ${motivationalSize}px "Arial", sans-serif`;
464
+ }
465
+
466
+ const motivationalY = 720; // Adjusted vertical position
467
+ ctx.fillText(motivationalText, canvas.width/2, motivationalY);
468
+ ctx.shadowBlur = 0;
469
+
470
+ // Logo with gold gradient
471
+ const logoGradient = ctx.createLinearGradient(0, 800, 0, 880);
472
+ logoGradient.addColorStop(0, '#f9d423');
473
+ logoGradient.addColorStop(1, '#d4af37');
474
+ ctx.fillStyle = logoGradient;
475
+ ctx.font = 'bold 48px "Arial", sans-serif';
476
+ ctx.fillText('KINTSUGI', canvas.width/2, 850);
477
+
478
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
479
  ctx.font = '24px "Arial", sans-serif';
480
+ ctx.fillText('Transform through movement', canvas.width/2, 900);
481
+
482
+ // Add decorative gold elements
483
+ ctx.fillStyle = 'rgba(212, 175, 55, 0.1)';
484
+ ctx.beginPath();
485
+ ctx.ellipse(100, 200, 150, 60, Math.PI/4, 0, Math.PI * 2);
486
+ ctx.fill();
487
+
488
+ ctx.beginPath();
489
+ ctx.ellipse(canvas.width - 100, canvas.height - 150, 120, 50, -Math.PI/4, 0, Math.PI * 2);
490
+ ctx.fill();
491
 
492
  // Convert canvas to image and download
493
  canvas.toBlob((blob) => {