-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathogImages.js
109 lines (99 loc) · 4.24 KB
/
ogImages.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const puppeteer = require("puppeteer");
const fs = require("fs");
const fsp = require("fs").promises;
const path = require("path");
async function getData() {
data = await fsp.readFile(path.join(__dirname, "_site/og_images_data.json"));
return JSON.parse(data);
}
async function createTemplate(data) {
return `<!DOCTYPE html><html lang="en"><meta charset="UTF-8" /><meta content="width=device-width,initial-scale=1" name="viewport" /><link href=https://fonts.gstatic.com rel=preconnect><link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;700;900&display=swap" rel="stylesheet" /> <body> <style> body { margin: 0; } .wrapper { width: 1200px; height: 630px; padding: 80px 100px; box-sizing: border-box; display: grid; grid-template-rows: 70px min-content 1fr 46px; grid-gap: 20px; font-family: "Source Sans Pro"; } .name { font-size: 36px; font-weight: 700; line-height: 1.5; margin-top: -13px; align-self: end; } .name:after { content: ""; display: block; height: 7px; width: 105px; background: #1d4ed8; margin-top: 20px; margin-bottom: 0; } .title { font-size: 76px; font-weight: 900; margin: 0; letter-spacing: 0.1px; line-height: 1.1; margin-bottom: 10px; } .tags { font-size: 32px; line-height: 1.5; display: flex; list-style: none; margin: 0; padding: 0; color: #6a6a6a; } .tags li:not(:first-child):before { content: "|"; display: inline-block; margin: 0 0.75ch; } .link { font-size: 32px; color: #6a6a6a; line-height: 1.5; margin-top: 10px; } </style>
<div class="wrapper">
<span class="name">${!data.description ? "Tomas Pustelnik" : ""}</span>
<h1 class="title">${data.title}</h1>
${
data.description
? '<span class="tags">' + data.description + "</span>"
: ""
}
<ul class="tags">${data.tags.map((tag) => `<li>${tag}</li>`).join("")}</ul>
<span class="link">pustelto.com</span>
</div>
</body>
</html>`;
}
async function createSocialImages() {
console.log("SOCIAL IMAGES GENERATION STARTED...");
const browser = await puppeteer.launch({
args: [
"--disable-gpu",
"--renderer",
"--no-sandbox",
"--no-service-autorun",
"--no-experiments",
"--no-default-browser-check",
"--disable-dev-shm-usage",
"--disable-setuid-sandbox",
"--no-first-run",
"--no-zygote",
"--single-process",
"--disable-extensions",
],
});
try {
const data = await getData();
const page = await browser.newPage();
const imagesFolderPath = path.join(__dirname, "_site/images/share");
if (!fs.existsSync(imagesFolderPath)) {
await fsp.mkdir(imagesFolderPath);
}
await page.setViewport({
width: 1200,
height: 628,
deviceScaleFactor: 2,
});
// Fill the template with data and create screenshot
for (imageData of data) {
const content = await createTemplate(imageData);
await page.setContent(content, {
waitUntil: "domcontentloaded",
});
// Wait until all images and fonts have loaded
await page.evaluate(async () => {
const selectors = Array.from(document.querySelectorAll("img"));
await Promise.all([
document.fonts.ready,
...selectors.map((img) => {
// Image has already finished loading, let’s see if it worked
if (img.complete) {
// Image loaded and has presence
if (img.naturalHeight !== 0) return;
// Image failed, so it has no height
throw new Error("Image failed to load");
}
// Image hasn’t loaded yet, added an event listener to know when it does
return new Promise((resolve, reject) => {
img.addEventListener("load", resolve);
img.addEventListener("error", reject);
});
}),
]);
});
// Take a screenshot of the page
image = await page.screenshot({
path: path.join(
imagesFolderPath,
(imageData.filename ||
imageData.title.toLowerCase().split(" ").join("-")) + ".png"
),
});
}
console.log("SOCIAL IMAGES SUCCESSFULLY GENERATED");
} catch (e) {
console.log("SOCIAL IMAGES ERROR:", e);
} finally {
await browser.close();
return;
}
}
module.exports = createSocialImages;