Brozy123 commited on
Commit
ad88c31
·
verified ·
1 Parent(s): 57163e2

Update lineupRenderer.js

Browse files
Files changed (1) hide show
  1. lineupRenderer.js +93 -90
lineupRenderer.js CHANGED
@@ -154,9 +154,10 @@ function drawPitch(ctx, W, H) {
154
  * @param {string} title - Title to display on the image
155
  * @param {Array} formation - Array of [posKey, posLabel]
156
  * @param {object} client - Discord client for fetching user data
 
157
  * @returns {Promise<Buffer>} PNG image buffer
158
  */
159
- async function renderLineupImage(lineup, title, formation, client) {
160
  const PITCH_W = 900;
161
  const SIDEBAR_W = 280;
162
  const W = PITCH_W + SIDEBAR_W;
@@ -306,105 +307,107 @@ async function renderLineupImage(lineup, title, formation, client) {
306
  ctx.fillText('No substitutes yet', SIDEBAR_W / 2, subY + 20);
307
  }
308
 
309
- // --- Start Drawing Players ---
310
- const avatarSize = 48;
311
- const avatarRadius = avatarSize / 2;
312
-
313
- for (const [posKey, posLabel] of formation) {
314
- const coords = POSITION_COORDS[posKey];
315
- if (!coords) continue;
316
-
317
- const x = SIDEBAR_W + (coords[0] / 100) * PITCH_W;
318
- const y = (coords[1] / 100) * H;
319
- const players = lineup.get(posKey) || [];
320
-
321
- if (players.length > 0) {
322
- ctx.save();
323
- ctx.shadowColor = '#00ff88';
324
- ctx.shadowBlur = 18;
325
- ctx.beginPath();
326
- ctx.arc(x, y, avatarRadius + 4, 0, Math.PI * 2);
327
- ctx.fillStyle = 'rgba(0,255,136,0.3)';
328
- ctx.fill();
329
- ctx.restore();
330
- }
331
 
332
- if (players.length > 0 && client) {
333
- const userId = players[0];
334
- const data = userDataMap.get(userId);
335
-
336
- if (data && data.img) {
337
- ctx.save();
338
- ctx.beginPath();
339
- ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
340
- ctx.clip();
341
- ctx.drawImage(data.img, x - avatarRadius, y - avatarRadius, avatarSize, avatarSize);
342
- ctx.restore();
343
-
344
- ctx.beginPath();
345
- ctx.arc(x, y, avatarRadius + 2, 0, Math.PI * 2);
346
- ctx.strokeStyle = '#ffffff';
347
- ctx.lineWidth = 2.5;
348
- ctx.stroke();
349
- } else {
350
- ctx.beginPath();
351
- ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
352
- ctx.fillStyle = '#5865F2';
353
- ctx.fill();
354
- ctx.strokeStyle = '#ffffff';
355
- ctx.lineWidth = 2;
356
- ctx.stroke();
357
- ctx.fillStyle = '#ffffff';
358
- ctx.font = 'bold 16px Arial, sans-serif';
359
- ctx.textAlign = 'center';
360
- ctx.textBaseline = 'middle';
361
- ctx.fillText('?', x, y);
362
- }
363
 
364
- if (data && data.user) {
365
- const displayName = data.user.globalName || data.user.username;
366
- const truncated = displayName.length > 10 ? displayName.slice(0, 9) + '…' : displayName;
367
- const labelY = y + avatarRadius + 14;
368
- ctx.font = 'bold 11px Arial, sans-serif';
369
- ctx.textAlign = 'center';
370
- const textWidth = ctx.measureText(truncated).width;
371
- const pillW = textWidth + 12;
372
- const pillH = 16;
373
-
374
- roundRect(ctx, x - pillW / 2, labelY - pillH / 2, pillW, pillH, 4);
375
- ctx.fillStyle = 'rgba(0,0,0,0.75)';
376
- ctx.fill();
377
-
378
- ctx.fillStyle = '#ffffff';
379
- ctx.textBaseline = 'middle';
380
- ctx.fillText(truncated, x, labelY);
381
- }
382
- } else {
383
- ctx.beginPath();
384
- ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
385
- ctx.fillStyle = 'rgba(0,0,0,0.35)';
386
- ctx.fill();
387
- ctx.setLineDash([4, 4]);
388
- ctx.strokeStyle = 'rgba(255,255,255,0.5)';
389
- ctx.lineWidth = 1.5;
390
- ctx.stroke();
391
- ctx.setLineDash([]);
392
- }
393
 
394
- const posLabelY = players.length > 0 ? y - avatarRadius - 10 : y - avatarRadius - 8;
395
- ctx.font = 'bold 12px Arial, sans-serif';
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  ctx.textAlign = 'center';
397
  ctx.textBaseline = 'middle';
 
 
 
 
 
 
 
 
 
 
 
 
398
 
399
- const posTextW = ctx.measureText(posLabel).width + 10;
400
- roundRect(ctx, x - posTextW / 2, posLabelY - 8, posTextW, 16, 3);
401
- ctx.fillStyle = players.length > 0 ? 'rgba(88,101,242,0.9)' : 'rgba(100,100,100,0.8)';
402
  ctx.fill();
403
 
404
  ctx.fillStyle = '#ffffff';
405
- ctx.fillText(posLabel, x, posLabelY);
 
 
 
 
 
 
 
 
 
 
 
 
406
  }
407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  // 4. Footer watermark
409
  ctx.fillStyle = 'rgba(0,0,0,0.5)';
410
  ctx.fillRect(0, H - 22, W, 22);
@@ -427,4 +430,4 @@ async function createLineupAttachment(lineup, title, formation, client) {
427
  return new AttachmentBuilder(buffer, { name: 'lineup.png' });
428
  }
429
 
430
- module.exports = { renderLineupImage, createLineupAttachment };
 
154
  * @param {string} title - Title to display on the image
155
  * @param {Array} formation - Array of [posKey, posLabel]
156
  * @param {object} client - Discord client for fetching user data
157
+ * @param {boolean} flipY - If true, flip Y coordinates (for opposing team view)
158
  * @returns {Promise<Buffer>} PNG image buffer
159
  */
160
+ async function renderLineupImage(lineup, title, formation, client, flipY = false) {
161
  const PITCH_W = 900;
162
  const SIDEBAR_W = 280;
163
  const W = PITCH_W + SIDEBAR_W;
 
307
  ctx.fillText('No substitutes yet', SIDEBAR_W / 2, subY + 20);
308
  }
309
 
310
+ // --- Start Drawing Players ---
311
+ const avatarSize = 48;
312
+ const avatarRadius = avatarSize / 2;
313
+
314
+ for (const [posKey, posLabel] of formation) {
315
+ const coords = POSITION_COORDS[posKey];
316
+ if (!coords) continue;
317
+
318
+ const x = SIDEBAR_W + (coords[0] / 100) * PITCH_W;
319
+ const y = flipY ? ((100 - coords[1]) / 100) * H : (coords[1] / 100) * H;
320
+ const players = lineup.get(posKey) || [];
321
+
322
+ if (players.length > 0) {
323
+ ctx.save();
324
+ ctx.shadowColor = '#00ff88';
325
+ ctx.shadowBlur = 18;
326
+ ctx.beginPath();
327
+ ctx.arc(x, y, avatarRadius + 4, 0, Math.PI * 2);
328
+ ctx.fillStyle = 'rgba(0,255,136,0.3)';
329
+ ctx.fill();
330
+ ctx.restore();
331
+ }
332
 
333
+ if (players.length > 0 && client) {
334
+ const userId = players[0];
335
+ const data = userDataMap.get(userId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
+ if (data && data.img) {
338
+ ctx.save();
339
+ ctx.beginPath();
340
+ ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
341
+ ctx.clip();
342
+ ctx.drawImage(data.img, x - avatarRadius, y - avatarRadius, avatarSize, avatarSize);
343
+ ctx.restore();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
345
+ ctx.beginPath();
346
+ ctx.arc(x, y, avatarRadius + 2, 0, Math.PI * 2);
347
+ ctx.strokeStyle = '#ffffff';
348
+ ctx.lineWidth = 2.5;
349
+ ctx.stroke();
350
+ } else {
351
+ ctx.beginPath();
352
+ ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
353
+ ctx.fillStyle = '#5865F2';
354
+ ctx.fill();
355
+ ctx.strokeStyle = '#ffffff';
356
+ ctx.lineWidth = 2;
357
+ ctx.stroke();
358
+ ctx.fillStyle = '#ffffff';
359
+ ctx.font = 'bold 16px Arial, sans-serif';
360
  ctx.textAlign = 'center';
361
  ctx.textBaseline = 'middle';
362
+ ctx.fillText('?', x, y);
363
+ }
364
+
365
+ if (data && data.user) {
366
+ const displayName = data.user.globalName || data.user.username;
367
+ const truncated = displayName.length > 10 ? displayName.slice(0, 9) + '...' : displayName;
368
+ const labelY = flipY ? y - avatarRadius - 14 : y + avatarRadius + 14;
369
+ ctx.font = 'bold 11px Arial, sans-serif';
370
+ ctx.textAlign = 'center';
371
+ const textWidth = ctx.measureText(truncated).width;
372
+ const pillW = textWidth + 12;
373
+ const pillH = 16;
374
 
375
+ roundRect(ctx, x - pillW / 2, labelY - pillH / 2, pillW, pillH, 4);
376
+ ctx.fillStyle = 'rgba(0,0,0,0.75)';
 
377
  ctx.fill();
378
 
379
  ctx.fillStyle = '#ffffff';
380
+ ctx.textBaseline = 'middle';
381
+ ctx.fillText(truncated, x, labelY);
382
+ }
383
+ } else {
384
+ ctx.beginPath();
385
+ ctx.arc(x, y, avatarRadius, 0, Math.PI * 2);
386
+ ctx.fillStyle = 'rgba(0,0,0,0.35)';
387
+ ctx.fill();
388
+ ctx.setLineDash([4, 4]);
389
+ ctx.strokeStyle = 'rgba(255,255,255,0.5)';
390
+ ctx.lineWidth = 1.5;
391
+ ctx.stroke();
392
+ ctx.setLineDash([]);
393
  }
394
 
395
+ const posLabelY = flipY
396
+ ? (players.length > 0 ? y + avatarRadius + 10 : y + avatarRadius + 8)
397
+ : (players.length > 0 ? y - avatarRadius - 10 : y - avatarRadius - 8);
398
+ ctx.font = 'bold 12px Arial, sans-serif';
399
+ ctx.textAlign = 'center';
400
+ ctx.textBaseline = 'middle';
401
+
402
+ const posTextW = ctx.measureText(posLabel).width + 10;
403
+ roundRect(ctx, x - posTextW / 2, posLabelY - 8, posTextW, 16, 3);
404
+ ctx.fillStyle = players.length > 0 ? 'rgba(88,101,242,0.9)' : 'rgba(100,100,100,0.8)';
405
+ ctx.fill();
406
+
407
+ ctx.fillStyle = '#ffffff';
408
+ ctx.fillText(posLabel, x, posLabelY);
409
+ }
410
+
411
  // 4. Footer watermark
412
  ctx.fillStyle = 'rgba(0,0,0,0.5)';
413
  ctx.fillRect(0, H - 22, W, 22);
 
430
  return new AttachmentBuilder(buffer, { name: 'lineup.png' });
431
  }
432
 
433
+ module.exports = { renderLineupImage, createLineupAttachment };