📂 Constants frame rates

This commit is contained in:
ful1e5 2021-02-04 17:51:55 +05:30
parent 376b4d3596
commit 692ad284c8
6 changed files with 64 additions and 70 deletions

View file

@ -1,12 +1,10 @@
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import Pixelmatch from "pixelmatch";
import { PNG } from "pngjs";
import puppeteer, { ElementHandle, Page } from "puppeteer"; import puppeteer, { ElementHandle, Page } from "puppeteer";
import { animatedCursors, outDir, staticCursors } from "./config"; import { animatedCursors, outDir, staticCursors } from "./config";
import { getFrameName } from "./utils/getFrameName"; import { frameNumber } from "./utils/frameNumber";
import { matchImages } from "./utils/matchImages";
import { toHTML } from "./utils/toHTML"; import { toHTML } from "./utils/toHTML";
const getSVGElement = async (page: Page) => { const getSVGElement = async (page: Page) => {
@ -19,13 +17,27 @@ const getSVGElement = async (page: Page) => {
}; };
const screenshot = async (element: ElementHandle<Element>): Promise<Buffer> => { const screenshot = async (element: ElementHandle<Element>): Promise<Buffer> => {
return await element.screenshot({ return element.screenshot({
omitBackground: true, omitBackground: true,
encoding: "binary", encoding: "binary",
}); });
}; };
const saveFrame = (key: string, frame: Buffer) => { const stopAnimation = async (page: Page) => {
// @ts-ignore
await page._client.send("Animation.setPlaybackRate", {
playbackRate: 0,
});
};
const resumeAnimation = async (page: Page, playbackRate: number = 0.1) => {
// @ts-ignore
await page._client.send("Animation.setPlaybackRate", {
playbackRate,
});
};
const saveFrameImage = (key: string, frame: Buffer) => {
const out_path = path.resolve(outDir, key); const out_path = path.resolve(outDir, key);
fs.writeFileSync(out_path, frame, { encoding: "binary" }); fs.writeFileSync(out_path, frame, { encoding: "binary" });
}; };
@ -73,56 +85,38 @@ const main = async () => {
await page.setContent(html); await page.setContent(html);
const svg = await getSVGElement(page); const svg = await getSVGElement(page);
await stopAnimation(page);
let index = 1; let index = 1;
const playbackRate = 0.1; const frameLimit = 300;
let breakRendering = false; let breakRendering = false;
let prevImg: Buffer;
// Rendering 1st frame // Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
const img1 = await screenshot(svg);
const key1 = getFrameName(index, svgFilePath, 4);
console.log("Saving", key1, "...");
saveFrame(key1, img1);
// stop animation
// @ts-ignore
await page._client.send("Animation.setPlaybackRate", {
playbackRate: 0,
});
// Rendering frames till `imgN` matched to `img1`
while (!breakRendering) { while (!breakRendering) {
++index; if (index > frameLimit) {
throw new Error("Reached the frame limit.");
// resume animation
// @ts-ignore
await page._client.send("Animation.setPlaybackRate", {
playbackRate,
});
const imgN = await screenshot(svg);
const keyN = getFrameName(index, svgFilePath, 4);
const { data: img1Data, width, height } = PNG.sync.read(img1);
const { data: imgNData } = PNG.sync.read(imgN);
const diff = Pixelmatch(img1Data, imgNData, null, width, height, {
threshold: 0.12,
});
if (diff <= 100) {
breakRendering = !breakRendering;
} else {
console.log("Saving", keyN, "...");
saveFrame(keyN, imgN);
// stop animation
// @ts-ignore
await page._client.send("Animation.setPlaybackRate", {
playbackRate: 0,
});
} }
resumeAnimation(page);
const img = await screenshot(svg);
stopAnimation(page);
if (index > 1) {
// @ts-ignore
const diff = matchImages(prevImg, img);
if (diff <= 100) {
breakRendering = !breakRendering;
}
}
const frame = frameNumber(index, 3);
const key = `${path.basename(svgFilePath, ".svg")}-${frame}.png`;
console.log("Saving", key, "...");
saveFrameImage(key, img);
prevImg = img;
++index;
} }
await page.close(); await page.close();

View file

@ -0,0 +1,7 @@
export const frameNumber = (index: number, padding: number) => {
let result = "" + index;
while (result.length < padding) {
result = "0" + result;
}
return result;
};

View file

@ -1,18 +0,0 @@
import path from "path";
export const frameNumber = (index: number, endIndex: number) => {
let result = "" + index;
while (result.length < endIndex) {
result = "0" + result;
}
return result;
};
export const getFrameName = (
index: number,
fileName: string,
padding: number = 2
) => {
const frame = frameNumber(index, padding);
return `${path.basename(fileName, ".svg")}-${frame}.png`;
};

View file

@ -0,0 +1,11 @@
import Pixelmatch from "pixelmatch";
import { PNG } from "pngjs";
export const matchImages = (img1: Buffer, img2: Buffer): number => {
const { data: img1Data, width, height } = PNG.sync.read(img1);
const { data: imgNData } = PNG.sync.read(img2);
return Pixelmatch(img1Data, imgNData, null, width, height, {
threshold: 0.1,
});
};

View file

@ -1,7 +1,7 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<g> <g>
<animateTransform attributeName="transform" type="rotate" from="0 105 144" to="360 105 144" additive="sum" <animateTransform attributeName="transform" type="rotate" from="0 105 144" to="360 105 144" additive="sum"
begin="0s" dur="1.2s" repeatCount="indefinite" /> begin="0s" dur="0.6s" repeatCount="1" />
<path d="M153 143.997C152.716 117.612 131.38 96.2814 105 95.9973V143.997H153Z" fill="url(#paint0_linear)" /> <path d="M153 143.997C152.716 117.612 131.38 96.2814 105 95.9973V143.997H153Z" fill="url(#paint0_linear)" />
<path d="M56.9973 144C57.2814 170.385 78.6176 191.716 104.997 192V144H56.9973Z" fill="url(#paint1_linear)" /> <path d="M56.9973 144C57.2814 170.385 78.6176 191.716 104.997 192V144H56.9973Z" fill="url(#paint1_linear)" />
<path d="M153 144C152.716 170.385 131.38 191.716 105 192V144H153Z" fill="url(#paint2_linear)" /> <path d="M153 144C152.716 170.385 131.38 191.716 105 192V144H153Z" fill="url(#paint2_linear)" />

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

View file

@ -4,7 +4,7 @@
</g> </g>
<g> <g>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" additive="sum" <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" additive="sum"
begin="0s" dur="0.6s" repeatCount="indefinite" /> begin="0s" dur="0.6s" repeatCount="1" />
<path <path
d="M48.8356 150.752C35.8793 137.872 28.1997 119.687 28.1997 100.06C28.1997 93.609 29.0651 87.3584 30.6869 81.416C30.6937 81.412 30.7004 81.4081 30.7072 81.4041C54.815 67.2655 86.0938 75.4985 100.013 99.9873C72.506 99.9873 49.3739 122.926 48.8356 150.752Z" d="M48.8356 150.752C35.8793 137.872 28.1997 119.687 28.1997 100.06C28.1997 93.609 29.0651 87.3584 30.6869 81.416C30.6937 81.412 30.7004 81.4081 30.7072 81.4041C54.815 67.2655 86.0938 75.4985 100.013 99.9873C72.506 99.9873 49.3739 122.926 48.8356 150.752Z"
fill="url(#paint0_linear)" /> fill="url(#paint0_linear)" />

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before After
Before After