💝 Performance tweak & prettier

This commit is contained in:
ful1e5 2021-01-26 19:52:54 +05:30
parent 75bba67132
commit 0fe8b2f1d3
7 changed files with 197 additions and 204 deletions

View file

@ -1,4 +1,4 @@
{ {
"tabWidth": 4, "tabWidth": 2,
"useTabs": false "useTabs": false
} }

View file

@ -1,102 +1,102 @@
{ {
"all_scroll": { "xhot": 100, "yhot": 100 }, "all_scroll": { "xhot": 100, "yhot": 100 },
"bottom_left_corner": { "xhot": 100, "yhot": 100 }, "bottom_left_corner": { "xhot": 100, "yhot": 100 },
"fd_double_arrow": { "xhot": 100, "yhot": 100 }, "fd_double_arrow": { "xhot": 100, "yhot": 100 },
"top_right_corner": { "xhot": 100, "yhot": 100 }, "top_right_corner": { "xhot": 100, "yhot": 100 },
"bottom_right_corner": { "xhot": 100, "yhot": 100 }, "bottom_right_corner": { "xhot": 100, "yhot": 100 },
"bd_double_arrow": { "xhot": 100, "yhot": 100 }, "bd_double_arrow": { "xhot": 100, "yhot": 100 },
"top_left_corner": { "xhot": 100, "yhot": 100 }, "top_left_corner": { "xhot": 100, "yhot": 100 },
"bottom_tee": { "xhot": 141, "yhot": 99 }, "bottom_tee": { "xhot": 141, "yhot": 99 },
"center_ptr": { "xhot": 61, "yhot": 100 }, "center_ptr": { "xhot": 61, "yhot": 100 },
"circle": { "xhot": 47, "yhot": 39 }, "circle": { "xhot": 47, "yhot": 39 },
"crossed_circle": { "xhot": 47, "yhot": 39 }, "crossed_circle": { "xhot": 47, "yhot": 39 },
"dnd_no_drop": { "xhot": 47, "yhot": 39 }, "dnd_no_drop": { "xhot": 47, "yhot": 39 },
"context_menu": { "xhot": 61, "yhot": 58 }, "context_menu": { "xhot": 61, "yhot": 58 },
"copy": { "xhot": 47, "yhot": 39 }, "copy": { "xhot": 47, "yhot": 39 },
"dnd_copy": { "xhot": 47, "yhot": 39 }, "dnd_copy": { "xhot": 47, "yhot": 39 },
"cross": { "xhot": 100, "yhot": 100 }, "cross": { "xhot": 100, "yhot": 100 },
"tcross": { "xhot": 100, "yhot": 100 }, "tcross": { "xhot": 100, "yhot": 100 },
"crosshair": { "xhot": 100, "yhot": 100 }, "crosshair": { "xhot": 100, "yhot": 100 },
"dotbox": { "xhot": 100, "yhot": 100 }, "dotbox": { "xhot": 100, "yhot": 100 },
"hand1": { "xhot": 94, "yhot": 105 }, "hand1": { "xhot": 94, "yhot": 105 },
"hand2": { "xhot": 66, "yhot": 34 }, "hand2": { "xhot": 66, "yhot": 34 },
"left_ptr": { "xhot": 68, "yhot": 41 }, "left_ptr": { "xhot": 68, "yhot": 41 },
"left_side": { "xhot": 100, "yhot": 100 }, "left_side": { "xhot": 100, "yhot": 100 },
"right_side": { "xhot": 100, "yhot": 100 }, "right_side": { "xhot": 100, "yhot": 100 },
"left_tee": { "xhot": 100, "yhot": 58 }, "left_tee": { "xhot": 100, "yhot": 58 },
"link": { "xhot": 61, "yhot": 105 }, "link": { "xhot": 61, "yhot": 105 },
"dnd_link": { "xhot": 61, "yhot": 105 }, "dnd_link": { "xhot": 61, "yhot": 105 },
"ll_angle": { "xhot": 141, "yhot": 58 }, "ll_angle": { "xhot": 141, "yhot": 58 },
"lr_angle": { "xhot": 141, "yhot": 138 }, "lr_angle": { "xhot": 141, "yhot": 138 },
"move": { "xhot": 80, "yhot": 106 }, "move": { "xhot": 80, "yhot": 106 },
"dnd_move": { "xhot": 80, "yhot": 106 }, "dnd_move": { "xhot": 80, "yhot": 106 },
"dnd_none": { "xhot": 80, "yhot": 106 }, "dnd_none": { "xhot": 80, "yhot": 106 },
"grabbing": { "xhot": 80, "yhot": 106 }, "grabbing": { "xhot": 80, "yhot": 106 },
"pointer_move": { "xhot": 80, "yhot": 106 }, "pointer_move": { "xhot": 80, "yhot": 106 },
"pencil": { "xhot": 141, "yhot": 58 }, "pencil": { "xhot": 141, "yhot": 58 },
"plus": { "xhot": 100, "yhot": 100 }, "plus": { "xhot": 100, "yhot": 100 },
"question_arrow": { "xhot": 105, "yhot": 105 }, "question_arrow": { "xhot": 105, "yhot": 105 },
"dnd_ask": { "xhot": 105, "yhot": 105 }, "dnd_ask": { "xhot": 105, "yhot": 105 },
"right_ptr": { "xhot": 61, "yhot": 138 }, "right_ptr": { "xhot": 61, "yhot": 138 },
"right_tee": { "xhot": 100, "yhot": 138 }, "right_tee": { "xhot": 100, "yhot": 138 },
"sb_down_arrow": { "xhot": 133, "yhot": 99 }, "sb_down_arrow": { "xhot": 133, "yhot": 99 },
"sb_h_double_arrow": { "xhot": 100, "yhot": 100 }, "sb_h_double_arrow": { "xhot": 100, "yhot": 100 },
"sb_left_arrow": { "xhot": 100, "yhot": 68 }, "sb_left_arrow": { "xhot": 100, "yhot": 68 },
"sb_right_arrow": { "xhot": 100, "yhot": 138 }, "sb_right_arrow": { "xhot": 100, "yhot": 138 },
"sb_up_arrow": { "xhot": 68, "yhot": 99 }, "sb_up_arrow": { "xhot": 68, "yhot": 99 },
"sb_v_double_arrow": { "xhot": 100, "yhot": 100 }, "sb_v_double_arrow": { "xhot": 100, "yhot": 100 },
"top_side": { "xhot": 100, "yhot": 100 }, "top_side": { "xhot": 100, "yhot": 100 },
"bottom_side": { "xhot": 100, "yhot": 100 }, "bottom_side": { "xhot": 100, "yhot": 100 },
"top_tee": { "xhot": 61, "yhot": 99 }, "top_tee": { "xhot": 61, "yhot": 99 },
"ul_angle": { "xhot": 61, "yhot": 65 }, "ul_angle": { "xhot": 61, "yhot": 65 },
"ur_angle": { "xhot": 61, "yhot": 138 }, "ur_angle": { "xhot": 61, "yhot": 138 },
"vertical_text": { "xhot": 100, "yhot": 102 }, "vertical_text": { "xhot": 100, "yhot": 102 },
"wait": { "xhot": 104, "yhot": 105 }, "wait": { "xhot": 104, "yhot": 105 },
"left_ptr_watch": { "xhot": 104, "yhot": 105 }, "left_ptr_watch": { "xhot": 104, "yhot": 105 },
"wayland_cursor": { "xhot": 100, "yhot": 100 }, "wayland_cursor": { "xhot": 100, "yhot": 100 },
"x_cursor": { "xhot": 100, "yhot": 100 }, "x_cursor": { "xhot": 100, "yhot": 100 },
"xterm": { "xhot": 97, "yhot": 97 }, "xterm": { "xhot": 97, "yhot": 97 },
"zoom_in": { "xhot": 76, "yhot": 78 }, "zoom_in": { "xhot": 76, "yhot": 78 },
"zoom_out": { "xhot": 76, "yhot": 78 } "zoom_out": { "xhot": 76, "yhot": 78 }
} }

View file

@ -1,13 +1,13 @@
{ {
"restartable": "rs", "restartable": "rs",
"ignore": [".git", "node_modules/**/node_modules"], "ignore": [".git", "node_modules/**/node_modules"],
"verbose": true, "verbose": true,
"execMap": { "execMap": {
"ts": "node --require ts-node/register" "ts": "node --require ts-node/register"
}, },
"watch": ["src/"], "watch": ["src/"],
"env": { "env": {
"NODE_ENV": "development" "NODE_ENV": "development"
}, },
"ext": "js,json,ts" "ext": "js,json,ts"
} }

View file

@ -1,33 +1,33 @@
{ {
"name": "apple_cursor", "name": "apple_cursor",
"version": "1.0.6", "version": "1.0.6",
"description": "🍎 macOS Cursor Theme", "description": "🍎 macOS Cursor Theme",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"clean": "rm -rf bitmaps themes", "clean": "rm -rf bitmaps themes",
"dev": "nodemon src/index.ts", "dev": "nodemon src/index.ts",
"watch": "nodemon --inspect src/index.ts", "watch": "nodemon --inspect src/index.ts",
"py_install": "pip install -r requirements.txt", "py_install": "pip install -r requirements.txt",
"render": "yarn ts-node src/index.ts", "render": "yarn ts-node src/index.ts",
"build": "python build.py", "build": "python build.py",
"compile": "yarn clean && yarn render && yarn build" "compile": "yarn clean && yarn render && yarn build"
}, },
"repository": "git@github.com:ful1e5/apple_cursor.git", "repository": "git@github.com:ful1e5/apple_cursor.git",
"author": "Kaiz Khatri", "author": "Kaiz Khatri",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@types/pixelmatch": "^5.2.2", "@types/pixelmatch": "^5.2.2",
"@types/pngjs": "^3.4.2", "@types/pngjs": "^3.4.2",
"@types/puppeteer": "^3.0.1", "@types/puppeteer": "^3.0.1",
"nodemon": "^2.0.4", "nodemon": "^2.0.4",
"ts-node": "^8.10.2", "ts-node": "^8.10.2",
"tslint": "^6.1.2", "tslint": "^6.1.2",
"typescript": "^3.9.7" "typescript": "^3.9.7"
}, },
"dependencies": { "dependencies": {
"pixelmatch": "^5.2.1", "pixelmatch": "^5.2.1",
"pngjs": "^6.0.0", "pngjs": "^6.0.0",
"puppeteer": "^5.2.1" "puppeteer": "^5.2.1"
} }
} }

View file

@ -2,13 +2,12 @@ import { resolve } from "path";
import { readdirSync, existsSync } from "fs"; import { readdirSync, existsSync } from "fs";
// Source Directory // Source Directory
const svgsDir = resolve(__dirname, "svg"); const staticCursorsDir = resolve(__dirname, "svg", "static");
if (!existsSync(svgsDir)) { const animatedCursorsDir = resolve(__dirname, "svg", "animated");
console.log("Source .svg files not found");
}
const staticCursorsDir = resolve(svgsDir, "static"); if (!existsSync(staticCursorsDir) || !existsSync(animatedCursorsDir)) {
const animatedCursorsDir = resolve(svgsDir, "animated"); throw new Error("svg directory not found");
}
// Out Directory // Out Directory
const bitmapsDir = resolve(__dirname, "../", "bitmaps"); const bitmapsDir = resolve(__dirname, "../", "bitmaps");

View file

@ -1,16 +1,40 @@
import "module-alias/register";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import puppeteer from "puppeteer"; import Pixelmatch from "pixelmatch";
import { htmlTemplate } from "./utils/htmlTemplate"; import { PNG } from "pngjs";
import { staticCursors, bitmapsDir, animatedCursors } from "./config"; import puppeteer, { ElementHandle, Page } from "puppeteer";
import { matchImages } from "./utils/matchImages";
import { saveFrames, Frames } from "./utils/saveFrames"; import { animatedCursors, bitmapsDir, staticCursors } from "./config";
import { getFrameName } from "./utils/getFrameName"; import { getFrameName } from "./utils/getFrameName";
import { toHTML } from "./utils/toHTML";
const getSVGElement = async (page: Page) => {
const svg = await page.$("#container svg");
if (!svg) {
throw new Error("svg element not found!");
}
return svg;
};
const screenshot = async (element: ElementHandle<Element>): Promise<Buffer> => {
return await element.screenshot({
omitBackground: true,
encoding: "binary",
});
};
const saveFrame = (key: string, frame: Buffer) => {
const out_path = path.resolve(bitmapsDir, key);
fs.writeFileSync(out_path, frame, { encoding: "binary" });
};
const main = async () => { const main = async () => {
const browser = await puppeteer.launch({ const browser = await puppeteer.launch({
ignoreDefaultArgs: [" --single-process ", "--no-sandbox"], ignoreDefaultArgs: ["--single-process", "--no-sandbox"],
headless: true, headless: true,
}); });
@ -18,100 +42,70 @@ const main = async () => {
fs.mkdirSync(bitmapsDir); fs.mkdirSync(bitmapsDir);
} }
try { for (const svgFilePath of staticCursors) {
console.log("📸 Rendering Static Cursors..."); const svgData = fs.readFileSync(svgFilePath, "utf-8");
if (!svgData) {
for (let svgPath of staticCursors) { throw new Error(`${svgFilePath} File Read error`);
const buffer = fs.readFileSync(path.resolve(svgPath), "utf8");
if (!buffer) throw new Error(`${svgPath} File Read error`);
// Generating HTML Template
const data = buffer.toString();
const template = htmlTemplate(data);
// config
const bitmapName = `${path.basename(svgPath, ".svg")}.png`;
const out = path.resolve(bitmapsDir, bitmapName);
// Render
const page = await browser.newPage();
await page.setContent(template);
await page.waitForSelector("#container");
const svgElement = await page.$("#container svg");
if (!svgElement) throw new Error("svg element not found");
await svgElement.screenshot({ omitBackground: true, path: out });
await page.close();
} }
console.log("🎥 Rendering Animated Cursors..."); const page = await browser.newPage();
const html = toHTML(svgData);
for (let svgPath of animatedCursors) { await page.setContent(html);
const buffer = fs.readFileSync(svgPath, "utf8"); const svg = await getSVGElement(page);
if (!buffer) throw new Error(`${svgPath} File Read error`);
// Generating HTML Template const key = `${path.basename(svgFilePath, ".svg")}.png`;
const data = buffer.toString(); const out = path.join(bitmapsDir, key);
const template = htmlTemplate(data);
const page = await browser.newPage(); console.log("Saving", key, "...");
await page.setContent(template, { waitUntil: "networkidle2" }); await svg.screenshot({ omitBackground: true, path: out });
await page.close();
await page.waitForSelector("#container");
const svgElement = await page.$("#container svg");
if (!svgElement) throw new Error("svg element not found");
// Render Config
let index = 1;
let breakRendering = false;
const frames: Frames = {};
const firstKey = getFrameName(index, svgPath);
console.log("Rendering", path.basename(svgPath), "...");
console.log(firstKey);
// 1st Frame
frames[firstKey] = {
buffer: await svgElement.screenshot({
omitBackground: true,
encoding: "binary",
}),
};
// Pushing frames until it match to 1st frame
index++;
while (!breakRendering) {
const newFrame = await svgElement.screenshot({
omitBackground: true,
encoding: "binary",
});
const key = getFrameName(index, svgPath);
console.log(key);
const diff = matchImages({
img1Buff: frames[firstKey].buffer,
img2Buff: newFrame,
});
if (!(diff < 700)) {
frames[key] = { buffer: newFrame };
} else {
breakRendering = true;
}
index++;
}
saveFrames(frames);
await page.close();
}
console.log(`\nBitmaps stored at ${bitmapsDir}\n\n🎉 Render Done.`);
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
} }
for (const svgFilePath of animatedCursors) {
const svgData = fs.readFileSync(svgFilePath, "utf8");
if (!svgData) {
throw new Error(`${svgFilePath} File Read error`);
}
const page = await browser.newPage();
const html = toHTML(svgData);
await page.setContent(html);
const svg = await getSVGElement(page);
let index = 1;
let breakRendering = false;
// Rendering 1st frame
const img1 = await screenshot(svg);
const key1 = getFrameName(index, svgFilePath);
console.log("Saving", key1, "...");
saveFrame(key1, img1);
// Rendering frames till `imgN` matched to `img1`
while (!breakRendering) {
++index;
const imgN = await screenshot(svg);
const keyN = getFrameName(index, svgFilePath);
console.log("Saving", keyN, "...");
saveFrame(keyN, imgN);
const { data: img1Data, width, height } = PNG.sync.read(img1);
const { data: imgNData } = PNG.sync.read(imgN);
const diff = Pixelmatch(img1Data, imgNData, null, width, height);
if (diff <= 100) {
breakRendering = !breakRendering;
}
}
await page.close();
}
await browser.close();
}; };
main(); main();

View file

@ -16,4 +16,4 @@ export const template = `
`; `;
export const toHTML = (svgData: string): string => export const toHTML = (svgData: string): string =>
template.replace("<svginjection>", svgData); template.replace("<svginjection>", svgData);