diff --git a/.all-contributorsrc b/.all-contributorsrc index dd996f2937..1ef7f7ddef 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1456,8 +1456,8 @@ { "login": "FreddieRa", "name": "Freddie Rawlins", - "avatar_url": "https://discourse-cdn-sjc2.com/standard10/user_avatar/discourse.processing.org/freddiera/120/4078_2.png", - "profile": "https://freddierawlins.wixsite.com/site", + "avatar_url": "https://avatars.githubusercontent.com/u/14854492?v=4", + "profile": "https://github.com/FreddieRa", "contributions": [ "code", "doc" @@ -1466,7 +1466,7 @@ { "login": "Luke_", "name": "Luc de wit", - "avatar_url": "https://media.discordapp.net/attachments/499488127245615135/499488260435869696/normal_luke.png", + "avatar_url": "https://avatars.githubusercontent.com/u/37410843?v=4", "profile": "https://github.com/justlucdewit", "contributions": [ "code", @@ -1860,7 +1860,7 @@ { "login": "shaharyar-shamshi", "name": "shaharyarshamshi", - "avatar_url": "https://avatars3.githubusercontent.com/u/17377195?v=4", + "avatar_url": "https://avatars.githubusercontent.com/u/17377195?v=4", "profile": "https://github.com/shaharyar-shamshi", "contributions": [ "translation" diff --git a/.github/workflows/contributors-png.yml b/.github/workflows/contributors-png.yml new file mode 100644 index 0000000000..79933b44a4 --- /dev/null +++ b/.github/workflows/contributors-png.yml @@ -0,0 +1,40 @@ +name: Generate Contributors PNG + +on: + push: + paths: + - '.all-contributorsrc' + +jobs: + build: + if: github.ref == 'refs/heads/main' && github.repository == 'processing/p5.js' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install dependencies + run: npm install canvas + + - name: Run contributors-png generator + run: node utils/contributors-png.js + + - name: Reset all changes except contributors.png + run: | + git restore --staged . + git add contributors.png + git checkout -- . + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "Update contributors.png from .all-contributorsrc" + branch: update-contributors-png + title: "chore: update contributors.png from .all-contributorsrc" + body: "This PR updates the contributors.png to reflect changes in .all-contributorsrc" + add-paths: contributors.png + token: ${{ secrets.ACCESS_TOKEN }} diff --git a/README.md b/README.md index 0130841268..77d56bd9be 100644 --- a/README.md +++ b/README.md @@ -121,4 +121,6 @@ Lead/Mentor Alumni We recognize all types of contributions. This project follows the [all-contributors specification](https://github.com/all-contributors/all-contributors) and the [Emoji Key](https://github.com/all-contributors/all-contributors/blob/master/docs/emoji-key.md) ✨ for contribution types. Instructions to add yourself or add contribution emojis to your name are [here](https://github.com/processing/p5.js/issues/2309). You can also post an issue or comment on a pull request with the text: `@all-contributors please add @YOUR-USERNAME for THINGS` (where `THINGS` is a comma-separated list of entries from the [list of possible contribution types](https://github.com/all-contributors/all-contributors/blob/master/docs/emoji-key.md)) and our nice bot will add you to [CONTRIBUTORS.md](./CONTRIBUTORS.md) automatically! +![Grid of avatars representing contributors to the p5.js project](contributors.png) + Thanks to all the wonderful contributors! 💓 diff --git a/contributors.png b/contributors.png new file mode 100644 index 0000000000..2651ac74a6 Binary files /dev/null and b/contributors.png differ diff --git a/utils/contributors-png.js b/utils/contributors-png.js new file mode 100644 index 0000000000..2686f1685f --- /dev/null +++ b/utils/contributors-png.js @@ -0,0 +1,61 @@ +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs'); + +const data = fs.readFileSync('.all-contributorsrc', 'utf-8'); +const parsed = JSON.parse(data); +const contributors = parsed.contributors; + +const AVATAR_SIZE = 50; +const GAP = 4; +const COLS = 40; +const ROWS = Math.ceil(contributors.length / COLS); + +const width = COLS * AVATAR_SIZE + (COLS - 1) * GAP; +const height = ROWS * AVATAR_SIZE + (ROWS - 1) * GAP; + +const canvas = createCanvas(width, height); +const ctx = canvas.getContext('2d'); + +async function loadAvatar(url) { + try { + const res = await fetch(url); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + + const buffer = Buffer.from(await res.arrayBuffer()); + return await loadImage(buffer); + } catch (err) { + return null; + } +} + +(async () => { + for (let i = 0; i < contributors.length; i++) { + const c = contributors[i]; + + const col = i % COLS; + const row = Math.floor(i / COLS); + + const x = col * (AVATAR_SIZE + GAP); + const y = row * (AVATAR_SIZE + GAP); + + const img = await loadAvatar(c.avatar_url); + + ctx.save(); + ctx.beginPath(); + ctx.arc( + x + AVATAR_SIZE / 2, + y + AVATAR_SIZE / 2, + AVATAR_SIZE / 2, + 0, + Math.PI * 2 + ); + ctx.clip(); + + if (img) { + ctx.drawImage(img, x, y, AVATAR_SIZE, AVATAR_SIZE); + } + ctx.restore(); + } + + fs.writeFileSync('contributors.png', canvas.toBuffer('image/png')); +})();