Add screenshot capture functionality

This commit is contained in:
Matt Isenhower 2022-08-29 22:05:59 -07:00
parent e59c15d761
commit 49c3708926
5 changed files with 873 additions and 51 deletions

View File

@ -0,0 +1,32 @@
import http from 'http';
import ecstatic from 'ecstatic';
export default class HttpServer
{
/** @var {http.Server} */
#server = null;
get port() {
return this.#server.address().port;
}
start() {
return new Promise((resolve, reject) => {
if (this.#server) {
return resolve();
}
const handler = ecstatic({ root: './dist' });
this.#server = http.createServer(handler);
this.#server.on('listening', () => resolve());
this.#server.listen();
});
}
async stop() {
if (this.#server) {
await this.#server.close();
this.#server = null;
}
}
}

View File

@ -0,0 +1,44 @@
import { URL } from 'url';
import puppeteer from 'puppeteer';
import HttpServer from './HttpServer.mjs';
const defaultViewport = {
// Using a 16:9 ratio here by default to match Twitter's image card dimensions
width: 1200,
height: 675,
deviceScaleFactor: 2,
};
export async function captureScreenshot(path, options = {}) {
const httpServer = new HttpServer;
await httpServer.start();
// Launch a new Chrome instance
const browser = await puppeteer.launch({
args: [
'--no-sandbox', // Allow running as root inside the Docker container
],
// headless: false, // For testing
});
// Create a new page and set the viewport
const page = await browser.newPage();
const viewport = { ...defaultViewport, ...options.viewport };
await page.setViewport(viewport);
// Navigate to the URL
let url = new URL(`http://localhost:${httpServer.port}/screenshots/`);
url.hash = path;
await page.goto(url, {
waitUntil: 'networkidle0', // Wait until the network is idle
});
// Take the screenshot
let result = await page.screenshot();
// Close the browser and HTTP server
await browser.close();
await httpServer.stop();
return result;
}

842
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,9 @@
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
},
"dependencies": {
"ecstatic": "^4.1.4",
"pinia": "^2.0.13",
"puppeteer": "^17.0.0",
"vue": "^3.2.33",
"vue-router": "^4.0.14"
},

View File

@ -1,10 +1,10 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHashHistory } from 'vue-router'
import ScreenshotsHomeView from '@/views/screenshots/ScreenshotsHomeView.vue'
import CountdownView from '@/views/screenshots/CountdownView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL + 'screenshots/'),
history: createWebHashHistory(import.meta.env.BASE_URL + 'screenshots/'),
routes: [
{
path: '/',