mirror of
https://github.com/ful1e5/apple_cursor.git
synced 2025-05-14 07:04:47 -04:00
📂 Constants frame rates
This commit is contained in:
parent
376b4d3596
commit
692ad284c8
6 changed files with 64 additions and 70 deletions
|
@ -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,57 +85,39 @@ 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
|
resumeAnimation(page);
|
||||||
|
const img = await screenshot(svg);
|
||||||
|
stopAnimation(page);
|
||||||
|
|
||||||
|
if (index > 1) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await page._client.send("Animation.setPlaybackRate", {
|
const diff = matchImages(prevImg, img);
|
||||||
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) {
|
if (diff <= 100) {
|
||||||
breakRendering = !breakRendering;
|
breakRendering = !breakRendering;
|
||||||
} else {
|
|
||||||
console.log("Saving", keyN, "...");
|
|
||||||
saveFrame(keyN, imgN);
|
|
||||||
|
|
||||||
// stop animation
|
|
||||||
// @ts-ignore
|
|
||||||
await page._client.send("Animation.setPlaybackRate", {
|
|
||||||
playbackRate: 0,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
7
bitmapper/src/utils/frameNumber.ts
Normal file
7
bitmapper/src/utils/frameNumber.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export const frameNumber = (index: number, padding: number) => {
|
||||||
|
let result = "" + index;
|
||||||
|
while (result.length < padding) {
|
||||||
|
result = "0" + result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
|
@ -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`;
|
|
||||||
};
|
|
11
bitmapper/src/utils/matchImages.ts
Normal file
11
bitmapper/src/utils/matchImages.ts
Normal 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,
|
||||||
|
});
|
||||||
|
};
|
|
@ -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 |
|
@ -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 |
Loading…
Add table
Add a link
Reference in a new issue