Fraser commited on
Commit
f444918
·
1 Parent(s): c6f0353
src/lib/components/Piclets/PicletDetail.svelte CHANGED
@@ -83,6 +83,19 @@
83
  <div class="content-scroll">
84
  <!-- Header Card -->
85
  <div class="header-card">
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  <div class="header-layout">
87
  <div class="image-column">
88
  <div class="image-container">
@@ -242,12 +255,7 @@
242
  <button class="btn btn-danger" onclick={handleDelete}>Yes, Release</button>
243
  <button class="btn btn-secondary" onclick={() => showDeleteConfirm = false}>Cancel</button>
244
  {:else}
245
- <div style="display: flex; flex-direction: column; gap: 8px;">
246
- <button class="btn btn-primary" onclick={handleShare} disabled={isSharing}>
247
- {isSharing ? 'Creating...' : 'Share Piclet'}
248
- </button>
249
- <button class="btn btn-danger" onclick={() => showDeleteConfirm = true}>Release Piclet</button>
250
- </div>
251
  {/if}
252
  </div>
253
  </div>
@@ -315,6 +323,43 @@
315
  border-radius: 16px;
316
  background: linear-gradient(135deg, #636366, #48484a);
317
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  }
319
 
320
  .header-layout {
 
83
  <div class="content-scroll">
84
  <!-- Header Card -->
85
  <div class="header-card">
86
+ <button
87
+ class="share-button"
88
+ onclick={handleShare}
89
+ disabled={isSharing}
90
+ aria-label="Share Piclet"
91
+ >
92
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
93
+ <path d="M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8"></path>
94
+ <polyline points="16 6 12 2 8 6"></polyline>
95
+ <line x1="12" y1="2" x2="12" y2="15"></line>
96
+ </svg>
97
+ </button>
98
+
99
  <div class="header-layout">
100
  <div class="image-column">
101
  <div class="image-container">
 
255
  <button class="btn btn-danger" onclick={handleDelete}>Yes, Release</button>
256
  <button class="btn btn-secondary" onclick={() => showDeleteConfirm = false}>Cancel</button>
257
  {:else}
258
+ <button class="btn btn-danger" onclick={() => showDeleteConfirm = true}>Release Piclet</button>
 
 
 
 
 
259
  {/if}
260
  </div>
261
  </div>
 
323
  border-radius: 16px;
324
  background: linear-gradient(135deg, #636366, #48484a);
325
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
326
+ position: relative;
327
+ }
328
+
329
+ .share-button {
330
+ position: absolute;
331
+ top: 16px;
332
+ right: 16px;
333
+ width: 40px;
334
+ height: 40px;
335
+ border-radius: 20px;
336
+ background: rgba(255, 255, 255, 0.2);
337
+ border: none;
338
+ cursor: pointer;
339
+ display: flex;
340
+ align-items: center;
341
+ justify-content: center;
342
+ transition: all 0.2s;
343
+ color: white;
344
+ }
345
+
346
+ .share-button:hover {
347
+ background: rgba(255, 255, 255, 0.3);
348
+ transform: scale(1.05);
349
+ }
350
+
351
+ .share-button:active {
352
+ transform: scale(0.95);
353
+ }
354
+
355
+ .share-button:disabled {
356
+ opacity: 0.5;
357
+ cursor: not-allowed;
358
+ }
359
+
360
+ .share-button svg {
361
+ width: 20px;
362
+ height: 20px;
363
  }
364
 
365
  .header-layout {
src/lib/services/picletExport.ts CHANGED
@@ -10,49 +10,61 @@ export async function generateShareableImage(piclet: PicletInstance): Promise<Bl
10
  const ctx = canvas.getContext('2d');
11
  if (!ctx) throw new Error('Could not create canvas context');
12
 
13
- // Set canvas size to match original piclet resolution
14
- const canvasSize = 1024;
15
- canvas.width = canvasSize;
16
- canvas.height = canvasSize;
 
17
 
18
  // Fill background with solid sky blue
19
  ctx.fillStyle = '#87CEEB';
20
- ctx.fillRect(0, 0, canvasSize, canvasSize);
21
 
22
- // Load piclet image first to maintain original size
23
  const picletImg = await loadImage(piclet.imageData || piclet.imageUrl);
24
- const picletSize = 512; // Display at half the canvas size for better composition
25
- const picletX = (canvasSize - picletSize) / 2;
26
- const picletY = canvasSize / 2 - picletSize / 2 + 50; // Center with slight offset down
27
 
28
  // Load and draw grass platform positioned under the piclet
29
  const grassImg = await loadImage('/assets/grass.PNG');
30
  const platformSize = picletSize + 100; // Slightly larger than piclet
31
- const platformX = (canvasSize - platformSize) / 2;
32
- const platformY = picletY + picletSize - 150; // Position so piclet sits on platform
33
  ctx.drawImage(grassImg, platformX, platformY, platformSize, platformSize);
34
 
35
  // Draw piclet on top of platform
36
  ctx.drawImage(picletImg, picletX, picletY, picletSize, picletSize);
37
 
38
- // Add piclet name only (no level)
39
  ctx.fillStyle = 'white';
40
- ctx.strokeStyle = 'black';
41
- ctx.lineWidth = 6;
42
- ctx.font = 'bold 64px Arial';
 
43
  ctx.textAlign = 'center';
 
 
 
 
44
 
45
  const nameText = piclet.nickname || piclet.typeId;
46
 
47
- // Draw name with outline
48
- ctx.strokeText(nameText, canvasSize / 2, 120);
49
- ctx.fillText(nameText, canvasSize / 2, 120);
 
 
 
 
 
 
50
 
51
  // Load and draw translucent watermark
52
  const logoImg = await loadImage('/assets/snap_logo.png');
53
- const logoSize = 150;
54
  ctx.globalAlpha = 0.3; // More translucent
55
- ctx.drawImage(logoImg, canvasSize - logoSize - 30, canvasSize - logoSize - 30, logoSize, logoSize);
56
  ctx.globalAlpha = 1.0;
57
 
58
  // Get the image as blob
 
10
  const ctx = canvas.getContext('2d');
11
  if (!ctx) throw new Error('Could not create canvas context');
12
 
13
+ // Set canvas size - narrower width to match content
14
+ const canvasWidth = 700;
15
+ const canvasHeight = 1536; // Taller to accommodate piclet at bottom
16
+ canvas.width = canvasWidth;
17
+ canvas.height = canvasHeight;
18
 
19
  // Fill background with solid sky blue
20
  ctx.fillStyle = '#87CEEB';
21
+ ctx.fillRect(0, 0, canvasWidth, canvasHeight);
22
 
23
+ // Load piclet image first
24
  const picletImg = await loadImage(piclet.imageData || piclet.imageUrl);
25
+ const picletSize = 512;
26
+ const picletX = (canvasWidth - picletSize) / 2;
27
+ const picletY = canvasHeight - picletSize - 50; // Position near bottom with small margin
28
 
29
  // Load and draw grass platform positioned under the piclet
30
  const grassImg = await loadImage('/assets/grass.PNG');
31
  const platformSize = picletSize + 100; // Slightly larger than piclet
32
+ const platformX = (canvasWidth - platformSize) / 2;
33
+ const platformY = picletY + picletSize - 180; // Position so piclet sits on platform
34
  ctx.drawImage(grassImg, platformX, platformY, platformSize, platformSize);
35
 
36
  // Draw piclet on top of platform
37
  ctx.drawImage(picletImg, picletX, picletY, picletSize, picletSize);
38
 
39
+ // Add piclet name with video game font
40
  ctx.fillStyle = 'white';
41
+ ctx.strokeStyle = '#1e3a8a'; // Dark blue outline
42
+ ctx.lineWidth = 8;
43
+ // Try to use a more gaming-style font, fallback to Impact
44
+ ctx.font = 'bold 72px "Press Start 2P", "Courier New", Impact, monospace';
45
  ctx.textAlign = 'center';
46
+ ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
47
+ ctx.shadowBlur = 10;
48
+ ctx.shadowOffsetX = 4;
49
+ ctx.shadowOffsetY = 4;
50
 
51
  const nameText = piclet.nickname || piclet.typeId;
52
 
53
+ // Draw name with outline and shadow
54
+ ctx.strokeText(nameText, canvasWidth / 2, 150);
55
+ ctx.fillText(nameText, canvasWidth / 2, 150);
56
+
57
+ // Reset shadow
58
+ ctx.shadowColor = 'transparent';
59
+ ctx.shadowBlur = 0;
60
+ ctx.shadowOffsetX = 0;
61
+ ctx.shadowOffsetY = 0;
62
 
63
  // Load and draw translucent watermark
64
  const logoImg = await loadImage('/assets/snap_logo.png');
65
+ const logoSize = 120;
66
  ctx.globalAlpha = 0.3; // More translucent
67
+ ctx.drawImage(logoImg, canvasWidth - logoSize - 20, canvasHeight - logoSize - 20, logoSize, logoSize);
68
  ctx.globalAlpha = 1.0;
69
 
70
  // Get the image as blob