Skip to content

Commit abaae24

Browse files
committed
feat: add contributors png generator
1 parent c0513a3 commit abaae24

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

utils/contributors-png.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const { createCanvas, loadImage } = require('canvas');
2+
const fs = require('fs');
3+
4+
const data = fs.readFileSync('.all-contributorsrc', 'utf-8');
5+
const parsed = JSON.parse(data);
6+
const contributors = parsed.contributors;
7+
8+
const AVATAR_SIZE = 50;
9+
const GAP = 4;
10+
const COLS = 40;
11+
const ROWS = Math.ceil(contributors.length / COLS);
12+
13+
const width = COLS * AVATAR_SIZE + (COLS - 1) * GAP;
14+
const height = ROWS * AVATAR_SIZE + (ROWS - 1) * GAP;
15+
16+
const canvas = createCanvas(width, height);
17+
const ctx = canvas.getContext('2d');
18+
19+
async function loadAvatar(url) {
20+
try {
21+
const res = await fetch(url);
22+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
23+
24+
const buffer = Buffer.from(await res.arrayBuffer());
25+
return await loadImage(buffer);
26+
} catch (err) {
27+
return null;
28+
}
29+
}
30+
31+
(async () => {
32+
for (let i = 0; i < contributors.length; i++) {
33+
const c = contributors[i];
34+
35+
const col = i % COLS;
36+
const row = Math.floor(i / COLS);
37+
38+
const x = col * (AVATAR_SIZE + GAP);
39+
const y = row * (AVATAR_SIZE + GAP);
40+
41+
const img = await loadAvatar(c.avatar_url);
42+
43+
ctx.save();
44+
ctx.beginPath();
45+
ctx.arc(
46+
x + AVATAR_SIZE / 2,
47+
y + AVATAR_SIZE / 2,
48+
AVATAR_SIZE / 2,
49+
0,
50+
Math.PI * 2
51+
);
52+
ctx.clip();
53+
54+
if (img) {
55+
ctx.drawImage(img, x, y, AVATAR_SIZE, AVATAR_SIZE);
56+
}
57+
ctx.restore();
58+
}
59+
60+
fs.writeFileSync('contributors.png', canvas.toBuffer('image/png'));
61+
})();

0 commit comments

Comments
 (0)