Skip to content

Commit 79cc4f1

Browse files
committed
feat(apps): replace basketball theme with gta theme in github thumbnail generator
1 parent f640df4 commit 79cc4f1

File tree

4 files changed

+115
-96
lines changed

4 files changed

+115
-96
lines changed

src/pages/apps/github-thumbnail/GithubThumbnailGeneratorPage.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const THEME_OPTIONS = [
3737
{ value: 'popart', label: 'POP_ART_COMIC' },
3838
{ value: 'cod', label: 'TACTICAL_OPS' },
3939
{ value: 'crtAmber', label: 'RETRO_AMBER_CRT' },
40-
{ value: 'basketball', label: 'COURT_SIDE' },
40+
{ value: 'gta', label: 'GRAND_THEFT_AUTO' },
4141
{ value: 'rich', label: 'LUXURY_GOLD' },
4242
];
4343

src/pages/apps/github-thumbnail/themes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { bauhaus } from './themes/bauhaus';
1717
import { popart } from './themes/popart';
1818
import { cod } from './themes/callofduty';
1919
import { crtAmber } from './themes/crtAmber';
20-
import { basketball } from './themes/basketball';
20+
import { gta } from './themes/gta';
2121
import { rich } from './themes/rich';
2222

2323
export const themeRenderers = {
@@ -40,6 +40,6 @@ export const themeRenderers = {
4040
popart,
4141
cod,
4242
crtAmber,
43-
basketball,
43+
gta,
4444
rich,
4545
};

src/pages/apps/github-thumbnail/themes/basketball.js

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { wrapText } from '../utils';
2+
3+
export const gta = (ctx, width, height, scale, data) => {
4+
const { repoOwner, repoName, description, stars } = data;
5+
// GRAND THEFT AUTO Style
6+
7+
// Background: Warm sunset gradient (Los Santos vibe)
8+
const grad = ctx.createLinearGradient(0, 0, width, height);
9+
grad.addColorStop(0, '#ffce00'); // Yellow
10+
grad.addColorStop(0.5, '#ff9900'); // Orange
11+
grad.addColorStop(1, '#cd0074'); // Deep Pink/Purple
12+
ctx.fillStyle = grad;
13+
ctx.fillRect(0, 0, width, height);
14+
15+
// Silhouette of a city (Procedural)
16+
ctx.fillStyle = '#000';
17+
ctx.beginPath();
18+
ctx.moveTo(0, height);
19+
let h = height * 0.8;
20+
for(let x=0; x<=width; x+= 40*scale) {
21+
h = height * (0.6 + Math.random() * 0.3);
22+
ctx.lineTo(x, h);
23+
ctx.lineTo(x + 40*scale, h);
24+
}
25+
ctx.lineTo(width, height);
26+
ctx.fill();
27+
28+
// Black Borders (The Collage Look)
29+
ctx.strokeStyle = '#000';
30+
ctx.lineWidth = 15 * scale;
31+
ctx.strokeRect(0, 0, width, height);
32+
33+
// Title ("Pricedown" emulation)
34+
ctx.fillStyle = '#fff';
35+
ctx.strokeStyle = '#000';
36+
ctx.lineWidth = 8 * scale;
37+
ctx.textAlign = 'left';
38+
// Impact is the closest web-safe font to Pricedown
39+
ctx.font = `900 ${150 * scale}px "Impact", "Arial Black", sans-serif`;
40+
41+
const titleX = 60 * scale;
42+
const titleY = height * 0.4;
43+
44+
ctx.strokeText(repoName, titleX, titleY);
45+
ctx.fillText(repoName, titleX, titleY);
46+
47+
// "The Price is Right" sub-style text
48+
ctx.fillStyle = '#000';
49+
ctx.font = `bold ${40 * scale}px "Arial Narrow", sans-serif`;
50+
ctx.fillText(repoOwner.toUpperCase(), titleX + 10*scale, titleY - 120*scale);
51+
52+
// "WANTED" Stars (Top Right)
53+
ctx.textAlign = 'right';
54+
55+
// Draw "Wanted" Stars
56+
const numStars = Math.min(5, Math.ceil((parseInt(stars) || 0) / 100)) || 1;
57+
58+
ctx.font = `900 ${60 * scale}px "Impact", sans-serif`;
59+
ctx.fillStyle = '#fff';
60+
ctx.strokeStyle = '#000';
61+
ctx.lineWidth = 4 * scale;
62+
63+
let currentStarX = width - 60*scale;
64+
for(let i=0; i<5; i++) {
65+
ctx.fillStyle = i < numStars ? '#fff' : 'rgba(0,0,0,0.3)';
66+
ctx.beginPath();
67+
// Simple Star shape
68+
const r = 30 * scale;
69+
const cx = currentStarX;
70+
const cy = 80 * scale;
71+
for(let j=0; j<5; j++) {
72+
ctx.lineTo(Math.cos((18+j*72)/180*Math.PI)*r + cx,
73+
-Math.sin((18+j*72)/180*Math.PI)*r + cy);
74+
ctx.lineTo(Math.cos((54+j*72)/180*Math.PI)*(r/2) + cx,
75+
-Math.sin((54+j*72)/180*Math.PI)*(r/2) + cy);
76+
}
77+
ctx.closePath();
78+
ctx.fill();
79+
ctx.stroke();
80+
currentStarX -= 70 * scale;
81+
}
82+
83+
// Description Box (Bottom Left)
84+
// Comic style box
85+
ctx.fillStyle = '#fff';
86+
ctx.strokeStyle = '#000';
87+
ctx.lineWidth = 6 * scale;
88+
const boxX = 40 * scale;
89+
const boxY = height * 0.6;
90+
const boxW = width * 0.5;
91+
const boxH = height * 0.3;
92+
93+
ctx.fillRect(boxX, boxY, boxW, boxH);
94+
ctx.strokeRect(boxX, boxY, boxW, boxH);
95+
96+
ctx.fillStyle = '#000';
97+
ctx.textAlign = 'left';
98+
ctx.font = `bold ${30 * scale}px "Courier New", monospace`;
99+
wrapText(ctx, description, boxX + 30*scale, boxY + 50*scale, boxW - 60*scale, 40*scale);
100+
101+
// Sticker (Bottom Right)
102+
ctx.save();
103+
ctx.translate(width - 200*scale, height - 150*scale);
104+
ctx.rotate(-0.2);
105+
ctx.fillStyle = '#000';
106+
ctx.fillRect(-150*scale, -50*scale, 300*scale, 100*scale);
107+
ctx.fillStyle = '#fff';
108+
ctx.textAlign = 'center';
109+
ctx.font = `900 ${40 * scale}px "Impact", sans-serif`;
110+
ctx.fillText("WASTED", 0, 15*scale);
111+
ctx.restore();
112+
};

0 commit comments

Comments
 (0)