📄 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",
"version": "1.1.0",
"description": "Material Based Cursors",
"main": "index.js",
"author": "Kaiz Khatri",
"license": "GPL-3.0",
"private": true,
"scripts": {
"render:bibata-modern": "yarn workspace bibata-modern render",
"render:bibata-original": "yarn workspace bibata-original render",
"render:bibata-rainbow": "yarn workspace bibata-rainbow render"
},
"workspaces": ["packages/*"]
"name": "bibata-cursor",
"version": "1.1.0",
"description": "Material Based Cursors",
"main": "index.js",
"author": "Kaiz Khatri",
"license": "GPL-3.0",
"private": true,
"scripts": {
"render:bibata-modern": "yarn workspace bibata-modern render",
"render:bibata-original": "yarn workspace bibata-original render",
"render:bibata-rainbow": "yarn workspace bibata-rainbow render"
},
"workspaces": ["packages/*"]
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,10 +2,10 @@ 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);
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,
});
return Pixelmatch(img1Data, imgNData, null, width, height, {
threshold: 0.1,
});
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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