📄 Reformat typescript with 2-Space

This commit is contained in:
ful1e5 2021-03-24 17:15:35 +05:30
parent 3beabbcbc0
commit 28614dfc25
17 changed files with 395 additions and 390 deletions

View file

@ -1,15 +1,15 @@
{ {
"name": "bibata-cursor", "name": "bibata-cursor",
"version": "1.1.0", "version": "1.1.0",
"description": "Material Based Cursors", "description": "Material Based Cursors",
"main": "index.js", "main": "index.js",
"author": "Kaiz Khatri", "author": "Kaiz Khatri",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
"render:bibata-modern": "yarn workspace bibata-modern render", "render:bibata-modern": "yarn workspace bibata-modern render",
"render:bibata-original": "yarn workspace bibata-original render", "render:bibata-original": "yarn workspace bibata-original render",
"render:bibata-rainbow": "yarn workspace bibata-rainbow render" "render:bibata-rainbow": "yarn workspace bibata-rainbow render"
}, },
"workspaces": ["packages/*"] "workspaces": ["packages/*"]
} }

View file

@ -1,22 +1,22 @@
{ {
"name": "bibata-core", "name": "bibata-core",
"version": "1.1.0", "version": "1.1.0",
"description": "Bibata bitmapper's core modules", "description": "Bibata bitmapper's core modules",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"author": "Kaiz Khatri", "author": "Kaiz Khatri",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"pixelmatch": "^5.2.1", "pixelmatch": "^5.2.1",
"pngjs": "^6.0.0", "pngjs": "^6.0.0",
"puppeteer": "^7.1.0" "puppeteer": "^7.1.0"
}, },
"devDependencies": { "devDependencies": {
"@types/pixelmatch": "^5.2.2", "@types/pixelmatch": "^5.2.2",
"@types/pngjs": "^6.0.0", "@types/pngjs": "^6.0.0",
"@types/puppeteer": "^5.4.3", "@types/puppeteer": "^5.4.3",
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"typescript": "^4.1.5" "typescript": "^4.1.5"
} }
} }

View file

@ -8,149 +8,154 @@ import { matchImages } from "./util/matchImages";
import { toHTML } from "./util/toHTML"; import { toHTML } from "./util/toHTML";
class BitmapsGenerator { class BitmapsGenerator {
/** /**
* Generate Png files from svg code. * Generate Png files from svg code.
* @param themeName Give name, So all bitmaps files are organized in one directory. * @param themeName Give name, So all bitmaps files are organized in one directory.
* @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store. * @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store.
*/ */
constructor(private bitmapsDir: string) { constructor(private bitmapsDir: string) {
this.bitmapsDir = path.resolve(bitmapsDir); this.bitmapsDir = path.resolve(bitmapsDir);
this.createDir(this.bitmapsDir); this.createDir(this.bitmapsDir);
} }
/** /**
* Create directory if it doesn't exists. * Create directory if it doesn't exists.
* @param dirPath directory `absolute` path. * @param dirPath directory `absolute` path.
*/ */
private createDir(dirPath: string) { private createDir(dirPath: string) {
if (!fs.existsSync(dirPath)) { if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true }); fs.mkdirSync(dirPath, { recursive: true });
} }
} }
/** /**
* Prepare headless browser. * Prepare headless browser.
*/ */
public async getBrowser(): Promise<Browser> { public async getBrowser(): Promise<Browser> {
return await puppeteer.launch({ return await puppeteer.launch({
ignoreDefaultArgs: ["--no-sandbox"], ignoreDefaultArgs: ["--no-sandbox"],
headless: true, headless: true,
}); });
} }
private async getSvgElement( private async getSvgElement(
page: Page, page: Page,
content: string content: string
): Promise<ElementHandle<Element>> { ): Promise<ElementHandle<Element>> {
if (!content) { if (!content) {
throw new Error(`${content} File Read error`); throw new Error(`${content} File Read error`);
} }
const html = toHTML(content); const html = toHTML(content);
await page.setContent(html, { timeout: 0 }); await page.setContent(html, { timeout: 0 });
const svg = await page.$("#container svg"); const svg = await page.$("#container svg");
if (!svg) { if (!svg) {
throw new Error("svg element not found!"); throw new Error("svg element not found!");
} }
return svg; return svg;
} }
public async generateStatic(browser: Browser, content: string, key: string) { public async generateStatic(browser: Browser, content: string, key: string) {
const page = await browser.newPage(); const page = await browser.newPage();
const svg = await this.getSvgElement(page, content); const svg = await this.getSvgElement(page, content);
const out = path.resolve(this.bitmapsDir, `${key}.png`); const out = path.resolve(this.bitmapsDir, `${key}.png`);
await svg.screenshot({ omitBackground: true, path: out }); await svg.screenshot({ omitBackground: true, path: out });
await page.close(); await page.close();
} }
private async screenshot( private async screenshot(
element: ElementHandle<Element> element: ElementHandle<Element>
): Promise<Buffer | string> { ): Promise<Buffer | string> {
const buffer = await element.screenshot({ const buffer = await element.screenshot({
encoding: "binary", encoding: "binary",
omitBackground: true, omitBackground: true,
}); });
if (!buffer) { if (!buffer) {
throw new Error("SVG element screenshot not working"); throw new Error("SVG element screenshot not working");
} }
return buffer; return buffer;
} }
private async stopAnimation(page: Page) { private async stopAnimation(page: Page) {
const client = await page.target().createCDPSession(); const client = await page.target().createCDPSession();
await client.send("Animation.setPlaybackRate", { await client.send("Animation.setPlaybackRate", {
playbackRate: 0, playbackRate: 0,
}); });
} }
private async resumeAnimation(page: Page, playbackRate: number) { private async resumeAnimation(page: Page, playbackRate: number) {
const client = await page.target().createCDPSession(); const client = await page.target().createCDPSession();
await client.send("Animation.setPlaybackRate", { await client.send("Animation.setPlaybackRate", {
playbackRate, playbackRate,
}); });
} }
private async saveFrameImage(key: string, frame: Buffer | string) { private async saveFrameImage(key: string, frame: Buffer | string) {
const out_path = path.resolve(this.bitmapsDir, key); const out_path = path.resolve(this.bitmapsDir, key);
fs.writeFileSync(out_path, frame); fs.writeFileSync(out_path, frame);
} }
public async generateAnimated( public async generateAnimated(
browser: Browser, browser: Browser,
content: string, content: string,
key: string, key: string,
options?: { options?: {
playbackRate?: number; playbackRate?: number;
diff?: number; diff?: number;
frameLimit?: number; frameLimit?: number;
framePadding?: number; framePadding?: number;
} }
) { ) {
const opt = Object.assign( const opt = Object.assign(
{ playbackRate: 0.1, diff: 0, frameLimit: 300, framePadding: 4 }, {
options playbackRate: 0.1,
); diff: 0,
frameLimit: 300,
framePadding: 4,
},
options
);
const page = await browser.newPage(); const page = await browser.newPage();
const svg = await this.getSvgElement(page, content); const svg = await this.getSvgElement(page, content);
await this.stopAnimation(page); await this.stopAnimation(page);
let index = 1; let index = 1;
let breakRendering = false; let breakRendering = false;
let prevImg: Buffer | string; let prevImg: Buffer | string;
// Rendering frames till `imgN` matched to `imgN-1` (When Animation is done) // Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
while (!breakRendering) { while (!breakRendering) {
if (index > opt.frameLimit) { if (index > opt.frameLimit) {
throw new Error("Reached the frame limit."); throw new Error("Reached the frame limit.");
} }
await this.resumeAnimation(page, opt.playbackRate); await this.resumeAnimation(page, opt.playbackRate);
const img: string | Buffer = await this.screenshot(svg); const img: string | Buffer = await this.screenshot(svg);
await this.stopAnimation(page); await this.stopAnimation(page);
if (index > 1) { if (index > 1) {
// @ts-ignore // @ts-ignore
const diff = matchImages(prevImg, img); const diff = matchImages(prevImg, img);
if (diff <= opt.diff) { if (diff <= opt.diff) {
breakRendering = !breakRendering; breakRendering = !breakRendering;
} }
} }
const number = frameNumber(index, opt.framePadding); const number = frameNumber(index, opt.framePadding);
const frame = `${key}-${number}.png`; const frame = `${key}-${number}.png`;
this.saveFrameImage(frame, img); this.saveFrameImage(frame, img);
prevImg = img; prevImg = img;
++index; ++index;
} }
await page.close(); await page.close();
} }
} }
export { BitmapsGenerator }; export { BitmapsGenerator };
export { BitmapsGenerator }; export { BitmapsGenerator };

View file

@ -2,76 +2,76 @@ import fs from "fs";
import path from "path"; import path from "path";
interface Svg { interface Svg {
key: string; key: string;
content: string; content: string;
} }
class SvgDirectoryParser { class SvgDirectoryParser {
/** /**
* Manage and Parse SVG file path in `absolute` fashion. * Manage and Parse SVG file path in `absolute` fashion.
* This Parser look svg files as below fashion: * This Parser look svg files as below fashion:
* ` * `
* <@svgDir>/static * <@svgDir>/static
* <@svgDir>/animated * <@svgDir>/animated
* ` * `
* @param svgDir is relative/absolute path, Where `SVG` files are stored. * @param svgDir is relative/absolute path, Where `SVG` files are stored.
*/ */
semiAnimated: boolean = false; semiAnimated: boolean = false;
constructor(private svgDir: string) { constructor(private svgDir: string) {
if (!fs.existsSync(this.svgDir)) { if (!fs.existsSync(this.svgDir)) {
throw new Error(`SVG files not found in ${this.svgDir}`); throw new Error(`SVG files not found in ${this.svgDir}`);
} }
} }
private readData(f: string): Svg { private readData(f: string): Svg {
const content = fs.readFileSync(f, "utf-8"); const content = fs.readFileSync(f, "utf-8");
const key = path.basename(f, ".svg"); const key = path.basename(f, ".svg");
return { content, key }; return { content, key };
} }
/** /**
* Return absolute paths array of SVG files data located inside '@svgDir/static' * Return absolute paths array of SVG files data located inside '@svgDir/static'
*/ */
public getStatic(): Svg[] { public getStatic(): Svg[] {
const staticDir = path.resolve(this.svgDir, "static"); const staticDir = path.resolve(this.svgDir, "static");
if (!fs.existsSync(staticDir)) { if (!fs.existsSync(staticDir)) {
console.log(`${this.svgDir} contains semi-animated .svg files`); console.log(`${this.svgDir} contains semi-animated .svg files`);
this.semiAnimated = true; this.semiAnimated = true;
return []; return [];
} else { } else {
const svgs = fs const svgs = fs
.readdirSync(staticDir) .readdirSync(staticDir)
.map((f) => this.readData(path.resolve(staticDir, f))); .map((f) => this.readData(path.resolve(staticDir, f)));
if (svgs.length == 0) { if (svgs.length == 0) {
throw new Error("Static Cursors directory is empty"); throw new Error("Static Cursors directory is empty");
} }
return svgs; return svgs;
} }
} }
/** /**
* Return absolute paths array of SVG files data located inside '@svgDir/animated' * Return absolute paths array of SVG files data located inside '@svgDir/animated'
*/ */
public getAnimated(): Svg[] { public getAnimated(): Svg[] {
const animatedDir = path.resolve(this.svgDir, "animated"); const animatedDir = path.resolve(this.svgDir, "animated");
if (!fs.existsSync(animatedDir)) { if (!fs.existsSync(animatedDir)) {
throw new Error("Animated Cursors directory not found"); throw new Error("Animated Cursors directory not found");
} }
const svgs = fs const svgs = fs
.readdirSync(animatedDir) .readdirSync(animatedDir)
.map((f) => this.readData(path.resolve(animatedDir, f))); .map((f) => this.readData(path.resolve(animatedDir, f)));
if (svgs.length == 0 && this.semiAnimated) { if (svgs.length == 0 && this.semiAnimated) {
throw new Error( throw new Error(
`Can't parse svg directory ${this.svgDir} as semi-animated theme` `Can't parse svg directory ${this.svgDir} as semi-animated theme`
); );
} }
return svgs; return svgs;
} }
} }
export { SvgDirectoryParser }; export { SvgDirectoryParser };

View file

@ -7,11 +7,11 @@ import { Colors } from "../types";
* watch.background="#FF0000" (Red) * watch.background="#FF0000" (Red)
* */ * */
const defaultKeyColors: Colors = { const defaultKeyColors: Colors = {
base: "#00FF00", base: "#00FF00",
outline: "#0000FF", outline: "#0000FF",
watch: { watch: {
background: "#FF0000", background: "#FF0000",
}, },
}; };
/** /**
@ -22,31 +22,31 @@ const defaultKeyColors: Colors = {
* @returns {string} SVG code with colors. * @returns {string} SVG code with colors.
*/ */
const colorSvg = ( const colorSvg = (
content: string, content: string,
colors: Colors, colors: Colors,
keys: Colors = defaultKeyColors keys: Colors = defaultKeyColors
): string => { ): string => {
content = content content = content
.replace(new RegExp(keys.base, "ig"), colors.base) .replace(new RegExp(keys.base, "ig"), colors.base)
.replace(new RegExp(keys.outline, "ig"), colors.outline); .replace(new RegExp(keys.outline, "ig"), colors.outline);
try { try {
// === trying to replace `watch` color === // === trying to replace `watch` color ===
if (!colors.watch?.background) { if (!colors.watch?.background) {
throw new Error(""); throw new Error("");
} }
const { background: b } = colors.watch; const { background: b } = colors.watch;
content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background
} catch (error) { } catch (error) {
// === on error => replace `watch` color as `base` === // === on error => replace `watch` color as `base` ===
content = content.replace( content = content.replace(
new RegExp(keys.watch!.background, "ig"), new RegExp(keys.watch!.background, "ig"),
colors.base colors.base
); );
} }
return content; return content;
}; };
export { colorSvg }; export { colorSvg };

View file

@ -10,11 +10,11 @@ type HexColor = string;
* @default background is `base` color. * @default background is `base` color.
*/ */
type Colors = { type Colors = {
base: HexColor; base: HexColor;
outline: HexColor; outline: HexColor;
watch?: { watch?: {
background: HexColor; background: HexColor;
}; };
}; };
export { Colors }; export { Colors };

View file

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

View file

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

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);

View file

@ -1,12 +1,12 @@
{ {
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"sourceMap": true, "sourceMap": true,
"composite": true, "composite": true,
"outDir": "dist", "outDir": "dist",
"rootDir": "src" "rootDir": "src"
}, },
"include": ["src"] "include": ["src"]
} }

View file

@ -1,17 +1,17 @@
{ {
"name": "bibata-modern", "name": "bibata-modern",
"version": "1.1.0", "version": "1.1.0",
"description": "Rounded edges bibata cursors", "description": "Rounded edges bibata cursors",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "npx tsc --build", "build": "npx tsc --build",
"render": "yarn build && node dist/index.js" "render": "yarn build && node dist/index.js"
}, },
"author": "Kaiz Khatri", "author": "Kaiz Khatri",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"typescript": "^4.1.5" "typescript": "^4.1.5"
} }
} }

View file

@ -1,8 +1,8 @@
import { Colors } from "bibata-core/src/types"; import { Colors } from "bibata-core/src/types";
interface Config { interface Config {
themeName: string; themeName: string;
color: Colors; color: Colors;
} }
const black = "#000000"; const black = "#000000";
@ -11,30 +11,30 @@ const amber = "#FF8300";
const richBlack = "#001524"; const richBlack = "#001524";
const config: Config[] = [ const config: Config[] = [
{ {
themeName: "Bibata-Modern-Amber", themeName: "Bibata-Modern-Amber",
color: { color: {
base: amber, base: amber,
outline: white, outline: white,
watch: { watch: {
background: richBlack, background: richBlack,
}, },
}, },
}, },
{ {
themeName: "Bibata-Modern-Classic", themeName: "Bibata-Modern-Classic",
color: { color: {
base: black, base: black,
outline: white, outline: white,
}, },
}, },
{ {
themeName: "Bibata-Modern-Ice", themeName: "Bibata-Modern-Ice",
color: { color: {
base: white, base: white,
outline: black, outline: black,
}, },
}, },
]; ];
export { config }; export { config };

View file

@ -7,31 +7,31 @@ const root = path.resolve(__dirname, "../../../../");
const svgDir = path.resolve(root, "svg", "modern"); const svgDir = path.resolve(root, "svg", "modern");
const main = async () => { const main = async () => {
for (const { themeName, color } of config) { for (const { themeName, color } of config) {
console.log("=>", themeName); console.log("=>", themeName);
const bitmapsDir = path.resolve(root, "bitmaps", themeName); const bitmapsDir = path.resolve(root, "bitmaps", themeName);
const svg = new SVGHandler.SvgDirectoryParser(svgDir); const svg = new SVGHandler.SvgDirectoryParser(svgDir);
const png = new BitmapsGenerator(bitmapsDir); const png = new BitmapsGenerator(bitmapsDir);
const browser = await png.getBrowser(); const browser = await png.getBrowser();
for (let { key, content } of svg.getStatic()) { for (let { key, content } of svg.getStatic()) {
console.log(" -> Saving", key, "..."); console.log(" -> Saving", key, "...");
content = SVGHandler.colorSvg(content, color); content = SVGHandler.colorSvg(content, color);
await png.generateStatic(browser, content, key); await png.generateStatic(browser, content, key);
} }
for (let { key, content } of svg.getAnimated()) { for (let { key, content } of svg.getAnimated()) {
console.log(" -> Saving", key, "..."); console.log(" -> Saving", key, "...");
content = SVGHandler.colorSvg(content, color); content = SVGHandler.colorSvg(content, color);
await png.generateAnimated(browser, content, key); await png.generateAnimated(browser, content, key);
} }
await browser.close(); await browser.close();
} }
}; };
main(); main();

View file

@ -1,9 +1,9 @@
{ {
"references": [{ "path": "../core" }], "references": [{ "path": "../core" }],
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"rootDir": "src", "rootDir": "src",
"outDir": "dist" "outDir": "dist"
}, },
"include": ["src"] "include": ["src"]
} }

View file

@ -1,17 +1,17 @@
{ {
"name": "bibata-original", "name": "bibata-original",
"version": "1.1.0", "version": "1.1.0",
"description": "Sharp edges bibata cursors", "description": "Sharp edges bibata cursors",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "npx tsc --build", "build": "npx tsc --build",
"render": "yarn build && node dist/index.js" "render": "yarn build && node dist/index.js"
}, },
"author": "Kaiz Khatri", "author": "Kaiz Khatri",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"typescript": "^4.1.5" "typescript": "^4.1.5"
} }
} }

View file

@ -1,8 +1,8 @@
import { Colors } from "bibata-core/src/types"; import { Colors } from "bibata-core/src/types";
interface Config { interface Config {
themeName: string; themeName: string;
color: Colors; color: Colors;
} }
const black = "#000000"; const black = "#000000";
@ -11,30 +11,30 @@ const amber = "#FF8300";
const richBlack = "#001524"; const richBlack = "#001524";
const config: Config[] = [ const config: Config[] = [
{ {
themeName: "Bibata-Original-Amber", themeName: "Bibata-Original-Amber",
color: { color: {
base: amber, base: amber,
outline: white, outline: white,
watch: { watch: {
background: richBlack, background: richBlack,
}, },
}, },
}, },
{ {
themeName: "Bibata-Original-Classic", themeName: "Bibata-Original-Classic",
color: { color: {
base: black, base: black,
outline: white, outline: white,
}, },
}, },
{ {
themeName: "Bibata-Original-Ice", themeName: "Bibata-Original-Ice",
color: { color: {
base: white, base: white,
outline: black, outline: black,
}, },
}, },
]; ];
export { config }; export { config };

View file

@ -7,31 +7,31 @@ const root = path.resolve(__dirname, "../../../../");
const svgDir = path.resolve(root, "svg", "original"); const svgDir = path.resolve(root, "svg", "original");
const main = async () => { const main = async () => {
for (const { themeName, color } of config) { for (const { themeName, color } of config) {
console.log("=>", themeName); console.log("=>", themeName);
const bitmapsDir = path.resolve(root, "bitmaps", themeName); const bitmapsDir = path.resolve(root, "bitmaps", themeName);
const svg = new SVGHandler.SvgDirectoryParser(svgDir); const svg = new SVGHandler.SvgDirectoryParser(svgDir);
const png = new BitmapsGenerator(bitmapsDir); const png = new BitmapsGenerator(bitmapsDir);
const browser = await png.getBrowser(); const browser = await png.getBrowser();
for (let { key, content } of svg.getStatic()) { for (let { key, content } of svg.getStatic()) {
console.log(" -> Saving", key, "..."); console.log(" -> Saving", key, "...");
content = SVGHandler.colorSvg(content, color); content = SVGHandler.colorSvg(content, color);
await png.generateStatic(browser, content, key); await png.generateStatic(browser, content, key);
} }
for (let { key, content } of svg.getAnimated()) { for (let { key, content } of svg.getAnimated()) {
console.log(" -> Saving", key, "..."); console.log(" -> Saving", key, "...");
content = SVGHandler.colorSvg(content, color); content = SVGHandler.colorSvg(content, color);
await png.generateAnimated(browser, content, key); await png.generateAnimated(browser, content, key);
} }
await browser.close(); await browser.close();
} }
}; };
main(); main();