Fraser commited on
Commit
6eff815
·
1 Parent(s): deb38a3
Files changed (1) hide show
  1. src/lib/services/picletExport.ts +90 -2
src/lib/services/picletExport.ts CHANGED
@@ -10,9 +10,26 @@ 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 - full piclet size plus padding for name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  const canvasWidth = 1024;
15
- const canvasHeight = 1200; // Extra height for name
16
  canvas.width = canvasWidth;
17
  canvas.height = canvasHeight;
18
 
@@ -83,6 +100,77 @@ export async function generateShareableImage(piclet: PicletInstance): Promise<Bl
83
  ctx.shadowOffsetX = 0;
84
  ctx.shadowOffsetY = 0;
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  // Load and draw translucent watermark
87
  const logoImg = await loadImage('/assets/snap_logo.png');
88
  const logoSize = 150;
 
10
  const ctx = canvas.getContext('2d');
11
  if (!ctx) throw new Error('Could not create canvas context');
12
 
13
+ // Polyfill for roundRect if not available
14
+ if (!ctx.roundRect) {
15
+ ctx.roundRect = function(x: number, y: number, width: number, height: number, radius: number) {
16
+ ctx.beginPath();
17
+ ctx.moveTo(x + radius, y);
18
+ ctx.lineTo(x + width - radius, y);
19
+ ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
20
+ ctx.lineTo(x + width, y + height - radius);
21
+ ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
22
+ ctx.lineTo(x + radius, y + height);
23
+ ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
24
+ ctx.lineTo(x, y + radius);
25
+ ctx.quadraticCurveTo(x, y, x + radius, y);
26
+ ctx.closePath();
27
+ };
28
+ }
29
+
30
+ // Set canvas size - full piclet size plus padding for name and stats
31
  const canvasWidth = 1024;
32
+ const canvasHeight = 1400; // Extra height for name and stats
33
  canvas.width = canvasWidth;
34
  canvas.height = canvasHeight;
35
 
 
100
  ctx.shadowOffsetX = 0;
101
  ctx.shadowOffsetY = 0;
102
 
103
+ // Draw base stats in a sleek format
104
+ const statsY = picletY + picletSize + 50; // Position below piclet
105
+ const stats = [
106
+ { label: 'HP', value: piclet.baseHp, color: '#4caf50' },
107
+ { label: 'ATK', value: piclet.baseAttack, color: '#f44336' },
108
+ { label: 'DEF', value: piclet.baseDefense, color: '#2196f3' },
109
+ { label: 'S.ATK', value: piclet.baseFieldAttack, color: '#ff9800' },
110
+ { label: 'S.DEF', value: piclet.baseFieldDefense, color: '#9c27b0' },
111
+ { label: 'SPD', value: piclet.baseSpeed, color: '#00bcd4' }
112
+ ];
113
+
114
+ // Stats container background
115
+ const containerX = 100;
116
+ const containerY = statsY - 20;
117
+ const containerWidth = canvasWidth - 200;
118
+ const containerHeight = 150;
119
+
120
+ // Draw semi-transparent background
121
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
122
+ ctx.roundRect(containerX, containerY, containerWidth, containerHeight, 20);
123
+ ctx.fill();
124
+
125
+ // Draw stats bars
126
+ const barHeight = 16;
127
+ const barSpacing = 20;
128
+ const maxStatValue = 255;
129
+ const barMaxWidth = containerWidth - 240; // Leave room for labels and values
130
+
131
+ stats.forEach((stat, index) => {
132
+ const y = statsY + (index * barSpacing);
133
+
134
+ // Draw stat label
135
+ ctx.font = 'bold 14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif';
136
+ ctx.fillStyle = '#ffffff';
137
+ ctx.textAlign = 'left';
138
+ ctx.fillText(stat.label, containerX + 20, y + 3);
139
+
140
+ // Draw stat value
141
+ ctx.textAlign = 'right';
142
+ ctx.fillText(stat.value.toString(), containerX + 100, y + 3);
143
+
144
+ // Draw background bar
145
+ const barX = containerX + 120;
146
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
147
+ ctx.roundRect(barX, y - 8, barMaxWidth, barHeight, 8);
148
+ ctx.fill();
149
+
150
+ // Draw filled bar
151
+ const fillWidth = (stat.value / maxStatValue) * barMaxWidth;
152
+ ctx.fillStyle = stat.color;
153
+ ctx.roundRect(barX, y - 8, fillWidth, barHeight, 8);
154
+ ctx.fill();
155
+
156
+ // Add shine effect
157
+ const shineGradient = ctx.createLinearGradient(barX, y - 8, barX, y - 8 + barHeight);
158
+ shineGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');
159
+ shineGradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.1)');
160
+ shineGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
161
+ ctx.fillStyle = shineGradient;
162
+ ctx.roundRect(barX, y - 8, fillWidth, barHeight / 2, 8);
163
+ ctx.fill();
164
+ });
165
+
166
+ // Draw BST (Base Stat Total)
167
+ const bst = piclet.bst || (piclet.baseHp + piclet.baseAttack + piclet.baseDefense +
168
+ piclet.baseFieldAttack + piclet.baseFieldDefense + piclet.baseSpeed);
169
+ ctx.font = 'bold 18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif';
170
+ ctx.fillStyle = '#ffd700'; // Gold color
171
+ ctx.textAlign = 'center';
172
+ ctx.fillText(`BST: ${bst}`, canvasWidth / 2, containerY + containerHeight - 10);
173
+
174
  // Load and draw translucent watermark
175
  const logoImg = await loadImage('/assets/snap_logo.png');
176
  const logoSize = 150;