diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..9e754bd --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +patreon: KaizKhatri +custom: https://www.paypal.me/kaizkhatri diff --git a/.github/ISSUE_TEMPLATE/----bug-report.md b/.github/ISSUE_TEMPLATE/----bug-report.md new file mode 100644 index 0000000..db30f32 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/----bug-report.md @@ -0,0 +1,20 @@ +--- +name: " \U0001F41B Bug Report" +about: Did something not work? +title: '' +labels: bug +assignees: '' + +--- + +## Description of the problem + +## How has this issue affected you? What are you trying to accomplish? + +### Logs or Screenshots: (optional) + +### Your Environment + +| Software | Name/Version | +| ---------------- | ------------ | +| Operating System | | diff --git a/.github/ISSUE_TEMPLATE/---feature.md b/.github/ISSUE_TEMPLATE/---feature.md new file mode 100644 index 0000000..945a67e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/---feature.md @@ -0,0 +1,12 @@ +--- +name: "\U0001F308 Feature" +about: " What cool thing would you like to add?" +title: '' +labels: enhancement +assignees: '' + +--- + +# What is this feature? +# How the feature should work? +# You have examples or an idea of how it can be implemented? diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ec4bb38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..157b9fe --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,39 @@ + + +## What kind of change does this PR introduce? + + + +## What is the current behavior? + + + +## What is the new behavior? + + + +## What steps did you take to test this? This is required before I can merge, make sure to test the flow you've updated. + +1. Step A +2. Step B +3. Step C + +## Checklist + + + + + +- [ ] Documentation +- [ ] Testing +- [ ] Ready to be merged +- [ ] Added myself to contributors table + + + diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000..d9f6563 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..53e5725 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,95 @@ +name: build + +on: + push: + paths-ignore: + - "**.md" + - "**.bbcode" + - LICENSE + branches: [main, dev] + + pull_request: + paths-ignore: + - "**.md" + - "**.bbcode" + - LICENSE + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install build dependencies (apt) + run: | + sudo apt install libx11-dev libxcursor-dev libpng-dev + continue-on-error: false + + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v2 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - uses: actions/setup-node@v1 + with: + node-version: "12.x" + - run: yarn install + - run: yarn render + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.x" + + - name: Cache pip dependencies + uses: actions/cache@v2 + with: + # This path is specific to Ubuntu + path: ~/.cache/pip + # Look to see if there is a cache hit for the corresponding requirements file + key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + ${{ runner.os }}- + + - name: Install pip dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + continue-on-error: false + + - name: Generating `GoogleDot` Cursor Theme + run: python build.py + + - name: Compressing Artifacts + run: | + tar -cvzf logs.tar.gz build.log + tar -cvzf bitmaps.tar.gz bitmaps + tar -cvzf GoogleDot.tar.gz themes + + - name: Uploading `GoogleDot` Build Log artifact + uses: actions/upload-artifact@v2 + with: + name: logs + path: logs.tar.gz + + - name: Uploading `bitmaps` artifact + uses: actions/upload-artifact@v2 + with: + name: bitmaps + path: bitmaps.tar.gz + + - name: Uploading `GoogleDot` Theme artifact + uses: actions/upload-artifact@v2 + with: + name: GoogleDot + path: GoogleDot.tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md index b616e64..1a7652e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] + +## [v1.0.0] - 27 Oct 2020 + +### Added + +- Initial release 🎊 +- Logo and badges +- CI/CD Pipelines + +[unreleased]: https://github.com/ful1e5/Google_Cursor/compare/v1.0.0...main +[v1.0.0]: https://github.com/ful1e5/Google_Cursor/tree/v1.0.0 diff --git a/PLING.bbcode b/PLING.bbcode new file mode 100644 index 0000000..777f068 --- /dev/null +++ b/PLING.bbcode @@ -0,0 +1,40 @@ +[b]GoogleDot [/b] Cursor Theme with [b]HiDPi[/b] Display support. This Cursor is built with [b][url=https://github.com/ful1e5/clickgen]clickgen[/url][/b] and render with the [b][url=https://github.com/puppeteer/puppeteer/]puppeteer[/url][/b]. +[i]Available Sizes[/i] [b]22, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96 + +[/b][i]Get latest build[/i] @[b][url=https://github.com/ful1e5/Google_Cursor/actions]GitHub Actions[/url][/b] +[i]Release Notification[/i] at [b][url=https://twitter.com/ful1e5]Twitter[/url][/b](@ful1e5) + +[b]Linux/X11 installation[/b] +Get the latest stable Linux release from the [b][url=https://www.pling.com/p/1215613#files-panel]Pling[/url][/b]. Unpack [b].tar.gz[/b] file and follow these [b]commands[/b]. + +[b]Install[/b] +[b]For all user:[/b] +[code]sudo mv GoogleDot /usr/share/icons[/code] +[b]For local user:[/b] +[code]mv GoogleDot ~/.icons[/code] + +[b]Uninstall[/b] +[b]From all user:[/b] +[code]sudo rm -r /usr/share/icons/GoogleDot[/code] +[b]From local user:[/b] +[code]rm -r ~/.icons/GoogleDot[/code] + +[b]Window installation[/b] +[list=1] + [*]unzip [b]GoogleDot_Windows.zip[/b] file[/*] + [*]Open [b]GoogleDot_Windows/[/b] in Explorer, and [b]right-click[/b] on [b]install.inf[/b].[/*] + [*]Click 'Install' from the context menu, and authorise the modifications to your system.[/*] + [*]Open [i]Control Panel > Personalisation and Appearance > Change mouse pointers[/i], and select [b]GoogleDot Cursors[/b].[/*] + [*]Click '[b]Apply[/b]'.[/*] +[/list] + +[b]How I help the Creator?[/b] +[list=2] + [*]Give a [b]Star[/b] or [b]Follow[/b] on [b][url=https://github.com/ful1e5/Google_Cursor]GitHub[/url][/b] (issues & PullRequest are welcome).[/*] + [*]By giving a [b]Pling[/b] or [b][url=https://www.paypal.me/kaizkhatri]Donation[/url][/b].[/*] + [*][b]Download[/b] from[url=https://www.pling.com/p/1408466/] Pling.com[/url] Product page that helps to [b]increases[/b] my [b]monthly payout[/b].[/*] + [*][b][url=https://www.pling.com/support]Become Supporter of Pling.com[/url][/b], So we become [b]Full-Time [/b]Libre & FOSS content creator [b];)[/b][/*] +[/list] + +[b]License & Terms[/b] +'[b]GoogleDot[/b]' Cursor Theme is available under the terms of the [b]GPL-3.0[/b] license. \ No newline at end of file diff --git a/README.md b/README.md index e515309..6cba4ae 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,282 @@ -# Google_Cursor +

+ GoogleDot +

+

+ 🍭 Cursor theme inspired on Google +

+ + +

+ + + GitHub Action Build + + + + CodeFactor + + + +
+ + npm type definitions + + + + Puppeteer version + + + + Clickgen + + + +
+ + Google Cursor release (latest by date including pre-releases) + + + + License + + + +
+ + License + + + + License + + + + License + + + +
+ + Made By Kaiz + +

+ +--- + + + +# GoogleDot Cursor + +Cursor theme inspired on **google material design** for `Windows` and `Linux` with _HiDPi Support_ πŸŽ‰. + +#### Cursor Sizes + +22 +24 +28 +32 +40 +48 +56 +64 +72 +80 +88 +96 + +#### Colors + +![#4285F4](https://imgur.com/NXEup6E.png) +![#FFFFFF](https://imgur.com/cvFxSBb.png) + +#### Quick install + +

+ + + +

+ +#### Preview: + +> Detailed Cursors Informations inside [src/svgs/README.md](https://github.com/ful1e5/Google_Cursor/blob/main/src/svg/README.md) + + + +

+ +
+ GoogleDot Cursors 🍭 +

+ + +### Manual Install + +#### Linux/X11 + +```bash +# extract `GoogleDot.tar.gz` +tar -xvf GoogleDot.tar.gz + +# For local users +mv GoogleDot ~/.icons/ + +# For all users +sudo mv GoogleDot /usr/share/icons/ +``` + + +#### Windows + +1. unzip `GoogleDot_Windows.zip` file +2. Open `GoogleDot_Windows/` in Explorer, and **right click** on `install.inf`. +3. Click 'Install' from the context menu, and authorize the modifications to your system. +4. Open _Control Panel > Personalization and Appearance > Change mouse pointers_, and select **GoogleDot Cursors**. +5. Click '**Apply**'. + + + +# Dependencies + +## Runtime Dependencies + +- libxcursor-dev +- libx11-dev +- libpng-dev (<=1.6) + +#### Install Runtime Dependencies + +##### macOS + +```bash +brew cask install xquartz libpng +``` + +##### Debain/ubuntu + +```bash +sudo apt install libx11-dev libxcursor-dev libpng-dev +``` + +##### ArchLinux/Manjaro + +```bash +sudo pacman -S libx11 libxcursor libpng +``` + +##### Fedora/Fedora Silverblue/CentOS/RHEL + +```bash +sudo dnf install libx11-devel libxcursor-devel libpng-devel +``` + +## Build Dependencies + +- [nodejs](https://nodejs.org/en/) (<=12.x.x) +- [yarn](https://classic.yarnpkg.com/en/docs/install/) +- [python](https://www.python.org/downloads/) (<=3.6) +- [pip3](https://pip.pypa.io/en/stable/installing/) + +### Node Packages + +- [puppeteer](https://www.npmjs.com/package/puppeteer) +- [pngjs](https://www.npmjs.com/package/pngjs) +- [pixelmatch](https://www.npmjs.com/package/pixelmatch) + +### PyPi Packages + +- [clickgen](https://pypi.org/project/clickgen/s) +- [Pillow](https://pypi.org/project/Pillow/) + +## Build From Scratch + +### ⚑ Auto Build (using GitHub Actions) + +GitHub Actions is automatically runs on every `push`(on **main** and **dev** branches) and `pull request`(on **main** branch), You found theme resources in `artifact` section of **build**.GitHub **Actions** available inside [.github/workflows](https://github.com/ful1e5/Google_Cursor/tree/main/.github/workflows) directory. + +### Manual Build + +#### Setup python environment + +```bash +python3 -m pip install --upgrade pip # Update pip to latest +python3 -m pip3 install virtualenv # Install python virtual environment +virtualenv venv # Create new virtualenv named `venv` +source venv/bin/activate # Activate virtualenv + +# For Deactivate virtualenv +deactivate +``` + +#### Compile From Source + +> Make sure your [python environment](#setup-python-environment) setup and `virtualenv` is **active**. + +```bash +yarn install # Install all Node Packages +yarn py_install # Install all PyPi Packages +yarn compile # Compile the cursor theme +``` + +After build `bitmaps` and `themes` directory are generated at project **root**. + +### Install Build Theme + +All builded cursor themes are available inside `themes` directory. + +#### Linux + +```bash +cd ./themes +rm -rf ~/.icons/GoogleDot && cp GoogleDot ~/.icons/ # installing Theme to local user(recommend) +``` + +#### Windows + +1. unzip `GoogleDot_Windows.zip` file +2. Open the `settings` app. +3. **Goto** `Devices` -> `Mouse` -> `Additional Mouse Options`. +4. **Goto** the `pointers` tab. +5. Replace each cursor in the currently applied cursor set with the corresponding cursor in the `GoogleDot_Windows` folder. +6. Click "**save as**" and type in the desired name. +7. Click "**apply**" and "**ok**". + + + +# Bugs + +Bugs πŸ› should be reported [here](https://github.com/ful1e5/Google_Cursor/issues) on the Github issues page. + + + +# Getting Help + +You can create a **issue**, I will help you. πŸ™‚ + + + +# Contributing + +Check [CONTRIBUTING.md](CONTRIBUTING.md), any suggestions for features and contributions to the continuing code masterelopment can be made via the issue tracker or code contributions via a `Fork` & `Pull requests`. + + + +## Support + +Give a **β˜…** or Follow on [GitHub](https://github.com/ful1e5),That's work as **Steroid πŸ’‰** for me. πŸ˜‰ + +> For extra support + + + Buy Me A Coffee + + + + +

+ ( `ω´ )ۢ▬ι═══════ﺀ +

+

+ I'm Using Katana +

\ No newline at end of file diff --git a/build.py b/build.py new file mode 100644 index 0000000..2382e1a --- /dev/null +++ b/build.py @@ -0,0 +1,16 @@ +import log +from clickgen import build_cursor_theme + +from config import name, sizes, delay, bitmaps_dir, temp_folder +from helper import init_build, pack_it + + +def build() -> None: + init_build() + build_cursor_theme(name, image_dir=bitmaps_dir, + cursor_sizes=sizes, out_path=temp_folder, hotspots=None, archive=False, delay=delay) + pack_it() + + +if __name__ == "__main__": + build() diff --git a/config.py b/config.py new file mode 100644 index 0000000..fe475cb --- /dev/null +++ b/config.py @@ -0,0 +1,46 @@ +import tempfile +import json + +# Build Config +delay = 50 +name = "GoogleDot" +sizes = [22, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96] + +bitmaps_dir = "./bitmaps" +package_dir = "./themes" +temp_folder = tempfile.mkdtemp() + +# Cleanup Configs +x11_out = name +win_out = name + "-Windows" + +# getting author name +with open("./package.json") as f: + data = json.loads(f.read()) + author = data["author"] + +# Windows Cursors Config +windows_cursors = { + "left_ptr_watch.ani": "AppStarting.ani", + "left_ptr.cur": "Arrow.cur", + "crosshair.cur": "Cross.cur", + "hand2.cur": "Hand.cur", + "pencil.cur": "Handwriting.cur", + "dnd-ask.cur": "Help.cur", + "xterm.cur": "IBeam.cur", + "circle.cur": "NO.cur", + "all-scroll.cur": "SizeAll.cur", + "bd_double_arrow.cur": "SizeNWSE.cur", + "sb_v_double_arrow.cur": "SizeNS.cur", + "fd_double_arrow.cur": "SizeNESW.cur", + "sb_h_double_arrow.cur": "SizeWE.cur", + "sb_up_arrow.cur": "UpArrow.cur", + "wait.ani": "Wait.ani", +} + +# Windows install.inf file content +with open("./scripts/windows.inf") as f: + data = f.read() + window_install_inf_content = data.replace( + "", name + " Cursors" + ).replace("", author) diff --git a/helper.py b/helper.py new file mode 100644 index 0000000..cc88968 --- /dev/null +++ b/helper.py @@ -0,0 +1,71 @@ +import shutil +import json +import sys + +from config import ( + name, + temp_folder, + bitmaps_dir, + win_out, + x11_out, + window_install_inf_content, + windows_cursors, + package_dir, +) +from os import path, listdir, rename, remove + + +x11_out_dir = path.join(package_dir, x11_out) +win_out_dir = path.join(package_dir, win_out) + + +def window_bundle() -> None: + # Remove & Rename cursors + # If Key found => Rename else Remove + for cursor in listdir(win_out_dir): + old_path = path.join(win_out_dir, cursor) + + try: + new_path = path.join(win_out_dir, windows_cursors[cursor]) + rename(old_path, new_path) + except KeyError: + remove(old_path) + + # creating install.inf file + install_inf_path = path.join(win_out_dir, "install.inf") + with open(install_inf_path, "w") as file: + file.write(window_install_inf_content) + + +def init_build() -> None: + """ + Print build version. + Remove previously built packages && Check Bitmaps. + """ + with open("./package.json", "r") as package_file: + data = json.loads(package_file.read()) + version = data["version"] + print("⚑ GoogleDot Builder v%s" % version) + + # cleanup old packages + if path.exists(package_dir): + shutil.rmtree(package_dir) + + # Checking Bitmaps directory + if not path.exists(bitmaps_dir): + print( + "⚠ BITMAPS NOT FOUND.\n\n`yarn install && yarn render` to Generates Bitmaps" + ) + sys.exit(1) + + +def pack_it() -> None: + """ + Create Crisp πŸ“¦ Packages for Windows & X11 Cursor Theme. + """ + # Rename directory + shutil.move(path.join(temp_folder, name, "x11"), x11_out_dir) + shutil.move(path.join(temp_folder, name, "win"), win_out_dir) + + # create install.inf file in Windows Theme + window_bundle() diff --git a/log.py b/log.py new file mode 100644 index 0000000..0e8767e --- /dev/null +++ b/log.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import logging + +logging.basicConfig( + filename="build.log", + filemode="w", + format="%(name)s - %(levelname)s - %(message)s", + level=logging.DEBUG, +) diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..cde9605 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,13 @@ +{ + "restartable": "rs", + "ignore": [".git", "node_modules/**/node_modules"], + "verbose": true, + "execMap": { + "ts": "node --require ts-node/register" + }, + "watch": ["src/"], + "env": { + "NODE_ENV": "development" + }, + "ext": "js,json,ts" +} diff --git a/package.json b/package.json index 14a33a3..a1e9bef 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,15 @@ "author": "Kaiz Khatri", "license": "GPL-3.0", "private": true, + "scripts": { + "clean": "rm -rf bitmaps themes", + "dev": "nodemon src/index.ts", + "watch": "nodemon --inspect src/index.ts", + "py_install": "pip install -r requirements.txt", + "render": "npx ts-node src/index.ts", + "build": "python build.py", + "compile": "yarn clean && yarn render && yarn build" + }, "devDependencies": { "@types/pixelmatch": "^5.2.2", "@types/pngjs": "^3.4.2", diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dbfa3c9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +clickgen==1.1.7 +Pillow<=8.0.1 diff --git a/scripts/windows.inf b/scripts/windows.inf new file mode 100644 index 0000000..0586241 --- /dev/null +++ b/scripts/windows.inf @@ -0,0 +1,52 @@ +[Version] +signature="$CHICAGO$" + By Kaiz Khatri +https://github.com/ful1e5/apple_cursor + +[DefaultInstall] +CopyFiles = Scheme.Cur +AddReg = Scheme.Reg + +[DestinationDirs] +Scheme.Cur = 10,"%CUR_DIR%" + +[Scheme.Reg] +HKCU,"Control Panel\Cursors\Schemes","%SCHEME_NAME%",,"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,%10%\%CUR_DIR%\%work%,%10%\%CUR_DIR%\%busy%,%10%\%CUR_DIR%\%Cross%,%10%\%CUR_DIR%\%Text%,%10%\%CUR_DIR%\%Hand%,%10%\%CUR_DIR%\%Unavailiable%,%10%\%CUR_DIR%\%Vert%,%10%\%CUR_DIR%\%Horz%,%10%\%CUR_DIR%\%Dgn1%,%10%\%CUR_DIR%\%Dgn2%,%10%\%CUR_DIR%\%move%,%10%\%CUR_DIR%\%alternate%,%10%\%CUR_DIR%\%link%" + +; -- Installed files + +[Scheme.Cur] +"Arrow.cur" +"Help.cur" +"AppStarting.ani" +"Wait.ani" +"Cross.cur" +"IBeam.cur" +"Handwriting.cur" +"NO.cur" +"SizeNS.cur" +"SizeWE.cur" +"SizeNWSE.cur" +"SizeNESW.cur" +"SizeAll.cur" +"UpArrow.cur" +"Hand.cur" + +[Strings] +CUR_DIR = "Cursors\" +SCHEME_NAME = "" +pointer = "Arrow.cur" +help = "Help.cur" +work = "AppStarting.ani" +busy = "Wait.ani" +cross = "Cross.cur" +text = "IBeam.cur" +hand = "Handwriting.cur" +unavailiable = "NO.cur" +vert = "SizeNS.cur" +horz = "SizeWE.cur" +dgn1 = "SizeNWSE.cur" +dgn2 = "SizeNESW.cur" +move = "SizeAll.cur" +alternate = "UpArrow.cur" +link = "Hand.cur" \ No newline at end of file diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..843b7b5 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,31 @@ +import { resolve } from "path"; +import { readdirSync, existsSync } from "fs"; + +// Source Directory +const svgsDir = resolve(__dirname, "svg"); +if (!existsSync(svgsDir)) { + console.log("Source .svg files not found"); +} + +const staticCursorsDir = resolve(svgsDir, "static"); +const animatedCursorsDir = resolve(svgsDir, "animated"); + +// Out Directory +const bitmapsDir = resolve(__dirname, "../", "bitmaps"); + +// Cursors +const staticCursors = readdirSync(staticCursorsDir).map((f) => + resolve(staticCursorsDir, f) +); +const animatedCursors = readdirSync(animatedCursorsDir).map((f) => + resolve(animatedCursorsDir, f) +); + +// Animated Config +const animatedClip = { + x: 4, + y: 4, + width: 200, + height: 200, +}; +export { staticCursors, animatedCursors, bitmapsDir, animatedClip }; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..5007114 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,124 @@ +import fs from "fs"; +import path from "path"; +import puppeteer from "puppeteer"; + +import { generateRenderTemplate } from "./utils/htmlTemplate"; +import { + staticCursors, + bitmapsDir, + animatedCursors, + animatedClip, +} from "./config"; +import { matchImages } from "./utils/matchImages"; +import { saveFrames, Frames } from "./utils/saveFrames"; +import { getFrameName } from "./utils/getFrameName"; + +const main = async () => { + const browser = await puppeteer.launch({ + ignoreDefaultArgs: [" --single-process ", "--no-sandbox"], + headless: true, + }); + + if (!fs.existsSync(bitmapsDir)) { + fs.mkdirSync(bitmapsDir); + } + + try { + console.log("πŸ“Έ Rendering Static Cursors..."); + + for (let svgPath of staticCursors) { + 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 = generateRenderTemplate(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..."); + + for (let svgPath of animatedCursors) { + const buffer = fs.readFileSync(svgPath, "utf8"); + if (!buffer) throw new Error(`${svgPath} File Read error`); + + // Generating HTML Template + const data = buffer.toString(); + const template = generateRenderTemplate(data); + + const page = await browser.newPage(); + await page.setContent(template, { waitUntil: "networkidle2" }); + + 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, + clip: animatedClip, + encoding: "binary", + }), + }; + + // Pushing frames until it match to 1st frame + index++; + while (!breakRendering) { + const newFrame = await svgElement.screenshot({ + omitBackground: true, + clip: animatedClip, + 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); + } +}; + +main(); diff --git a/src/svg/README.md b/src/svg/README.md new file mode 100644 index 0000000..e3d6153 --- /dev/null +++ b/src/svg/README.md @@ -0,0 +1,52 @@ +# Cursor Source Info + +## Symbolic Cursors + +| Preview | Source | Symbolic links | Windows Cursor name | +| :-------------------------------------------------------: | :---------------------: | :-------------------------------------------------------------: | :--------------------------: | +| | all_scroll.svg | `None` | `SizeAll.cur` | +| | bottom_left_corner.svg | `fd_double_arrow.svg` `top_right_corner.svg` | `SizeNESW.cur` | +| | bottom_right_corner.svg | `bd_double_arrow.svg` `top_left_corner.svg` | `SizeNWSE.cur` | +| | bottom_tee.svg | `None` | | +| | center_ptr.svg | `None` | | +| | circle.svg | `crossed_circle.svg` `dnd_no_drop.svg` | `NO.cur` | +| | context_menu.svg | `None` | | +| | copy.svg | `dnd_copy.svg` | | +| | cross.svg | `tcross.svg` | | +| | crosshair.svg | `None` | `Cross.cur` | +| | dotbox.svg | `None` | | +| | hand1.svg | `None` | | +| | hand2.svg | `None` | `Hand.cur` | +| | left_ptr.svg | `None` | `Arrow.cur` | +| | left_side.svg | `right_side.svg` | | +| | left_tee.svg | `None` | | +| | link.svg | `dnd_link.svg` | | +| | ll_angle.svg | `None` | | +| | lr_angle.svg | `None` | | +| | move.svg | `dnd_move.svg` `dnd_none.svg` `grabbing.svg` `pointer_move.svg` | | +| | pencil.svg | `None` | `Handwriting.cur` | +| | plus.svg | `None` | | +| | question_arrow.svg | `dnd_ask.svg` | `Help.cur` | +| | right_ptr.svg | `None` | | +| | right_tee.svg | `None` | | +| | sb_down_arrow.svg | `None` | | +| | sb_h_double_arrow.svg | `None` | `SizeWE.cur` | +| | sb_left_arrow.svg | `None` | | +| | sb_right_arrow.svg | `None` | | +| | sb_up_arrow.svg | `None` | `UpArrow.cur` | +| | sb_v_double_arrow.svg | `None` | `SizeNS.cur` | +| | top_side.svg | `bottom_side.svg` | | +| | top_tee.svg | `None` | | +| | ul_angle.svg | `None` | | +| | ur_angle.svg | `None` | | +| | vertical_text.svg | `None` | | +| | wait.svg | `left_ptr_watch.svg` | `AppStarting.ani` `Wait.ani` | +| | wayland_cursor.svg | `None` | | +| | x_cursor.svg | `None` | | +| | xterm.svg | `None` | `IBeam.cur` | +| | zoom_in.svg | `None` | | +| | zoom_out.svg | `None` | | + + + + diff --git a/src/svg/animated/left_ptr_watch.svg b/src/svg/animated/left_ptr_watch.svg new file mode 120000 index 0000000..89f76d4 --- /dev/null +++ b/src/svg/animated/left_ptr_watch.svg @@ -0,0 +1 @@ +wait.svg \ No newline at end of file diff --git a/src/svg/animated/wait.svg b/src/svg/animated/wait.svg new file mode 100644 index 0000000..fb03daa --- /dev/null +++ b/src/svg/animated/wait.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/svg/static/all_scroll.svg b/src/svg/static/all_scroll.svg new file mode 120000 index 0000000..37362fe --- /dev/null +++ b/src/svg/static/all_scroll.svg @@ -0,0 +1 @@ +move.svg \ No newline at end of file diff --git a/src/svg/static/bd_double_arrow.svg b/src/svg/static/bd_double_arrow.svg new file mode 120000 index 0000000..a3a3e2d --- /dev/null +++ b/src/svg/static/bd_double_arrow.svg @@ -0,0 +1 @@ +bottom_right_corner.svg \ No newline at end of file diff --git a/src/svg/static/bottom_left_corner.svg b/src/svg/static/bottom_left_corner.svg new file mode 100644 index 0000000..ecc4ea4 --- /dev/null +++ b/src/svg/static/bottom_left_corner.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/bottom_right_corner.svg b/src/svg/static/bottom_right_corner.svg new file mode 100644 index 0000000..47603fa --- /dev/null +++ b/src/svg/static/bottom_right_corner.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/bottom_side.svg b/src/svg/static/bottom_side.svg new file mode 120000 index 0000000..9c7bb92 --- /dev/null +++ b/src/svg/static/bottom_side.svg @@ -0,0 +1 @@ +top_side.svg \ No newline at end of file diff --git a/src/svg/static/bottom_tee.svg b/src/svg/static/bottom_tee.svg new file mode 100644 index 0000000..f6dc412 --- /dev/null +++ b/src/svg/static/bottom_tee.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/center_ptr.svg b/src/svg/static/center_ptr.svg new file mode 100644 index 0000000..304f6ef --- /dev/null +++ b/src/svg/static/center_ptr.svg @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/svg/static/circle.svg b/src/svg/static/circle.svg new file mode 100644 index 0000000..9392cf4 --- /dev/null +++ b/src/svg/static/circle.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/context_menu.svg b/src/svg/static/context_menu.svg new file mode 100644 index 0000000..43e14f9 --- /dev/null +++ b/src/svg/static/context_menu.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/copy.svg b/src/svg/static/copy.svg new file mode 100644 index 0000000..1387ec4 --- /dev/null +++ b/src/svg/static/copy.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/cross.svg b/src/svg/static/cross.svg new file mode 100644 index 0000000..d894d8d --- /dev/null +++ b/src/svg/static/cross.svg @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/src/svg/static/crossed_circle.svg b/src/svg/static/crossed_circle.svg new file mode 100644 index 0000000..8535691 --- /dev/null +++ b/src/svg/static/crossed_circle.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/svg/static/crosshair.svg b/src/svg/static/crosshair.svg new file mode 100644 index 0000000..09f696f --- /dev/null +++ b/src/svg/static/crosshair.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/svg/static/dnd_ask.svg b/src/svg/static/dnd_ask.svg new file mode 120000 index 0000000..14c57d2 --- /dev/null +++ b/src/svg/static/dnd_ask.svg @@ -0,0 +1 @@ +question_arrow.svg \ No newline at end of file diff --git a/src/svg/static/dnd_copy.svg b/src/svg/static/dnd_copy.svg new file mode 120000 index 0000000..4b1d7e7 --- /dev/null +++ b/src/svg/static/dnd_copy.svg @@ -0,0 +1 @@ +copy.svg \ No newline at end of file diff --git a/src/svg/static/dnd_link.svg b/src/svg/static/dnd_link.svg new file mode 120000 index 0000000..4abb12d --- /dev/null +++ b/src/svg/static/dnd_link.svg @@ -0,0 +1 @@ +link.svg \ No newline at end of file diff --git a/src/svg/static/dnd_move.svg b/src/svg/static/dnd_move.svg new file mode 120000 index 0000000..37362fe --- /dev/null +++ b/src/svg/static/dnd_move.svg @@ -0,0 +1 @@ +move.svg \ No newline at end of file diff --git a/src/svg/static/dnd_no_drop.svg b/src/svg/static/dnd_no_drop.svg new file mode 100644 index 0000000..f636fbe --- /dev/null +++ b/src/svg/static/dnd_no_drop.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/dnd_none.svg b/src/svg/static/dnd_none.svg new file mode 120000 index 0000000..37362fe --- /dev/null +++ b/src/svg/static/dnd_none.svg @@ -0,0 +1 @@ +move.svg \ No newline at end of file diff --git a/src/svg/static/dotbox.svg b/src/svg/static/dotbox.svg new file mode 100644 index 0000000..32e58c9 --- /dev/null +++ b/src/svg/static/dotbox.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/fd_double_arrow.svg b/src/svg/static/fd_double_arrow.svg new file mode 120000 index 0000000..acc15d0 --- /dev/null +++ b/src/svg/static/fd_double_arrow.svg @@ -0,0 +1 @@ +bottom_left_corner.svg \ No newline at end of file diff --git a/src/svg/static/grabbing.svg b/src/svg/static/grabbing.svg new file mode 120000 index 0000000..37362fe --- /dev/null +++ b/src/svg/static/grabbing.svg @@ -0,0 +1 @@ +move.svg \ No newline at end of file diff --git a/src/svg/static/hand1.svg b/src/svg/static/hand1.svg new file mode 100644 index 0000000..1b65ca7 --- /dev/null +++ b/src/svg/static/hand1.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/hand2.svg b/src/svg/static/hand2.svg new file mode 100644 index 0000000..172f354 --- /dev/null +++ b/src/svg/static/hand2.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/left_ptr.svg b/src/svg/static/left_ptr.svg new file mode 100644 index 0000000..bf8f500 --- /dev/null +++ b/src/svg/static/left_ptr.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/left_side.svg b/src/svg/static/left_side.svg new file mode 100644 index 0000000..0982847 --- /dev/null +++ b/src/svg/static/left_side.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/svg/static/left_tee.svg b/src/svg/static/left_tee.svg new file mode 100644 index 0000000..c14a78d --- /dev/null +++ b/src/svg/static/left_tee.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/link.svg b/src/svg/static/link.svg new file mode 100644 index 0000000..cb2e097 --- /dev/null +++ b/src/svg/static/link.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/ll_angle.svg b/src/svg/static/ll_angle.svg new file mode 100644 index 0000000..78fc6a3 --- /dev/null +++ b/src/svg/static/ll_angle.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/lr_angle.svg b/src/svg/static/lr_angle.svg new file mode 100644 index 0000000..7184991 --- /dev/null +++ b/src/svg/static/lr_angle.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/move.svg b/src/svg/static/move.svg new file mode 100644 index 0000000..2cff4c2 --- /dev/null +++ b/src/svg/static/move.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/pencil.svg b/src/svg/static/pencil.svg new file mode 100644 index 0000000..baa6c99 --- /dev/null +++ b/src/svg/static/pencil.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/plus.svg b/src/svg/static/plus.svg new file mode 100644 index 0000000..10d4426 --- /dev/null +++ b/src/svg/static/plus.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/pointer_move.svg b/src/svg/static/pointer_move.svg new file mode 120000 index 0000000..37362fe --- /dev/null +++ b/src/svg/static/pointer_move.svg @@ -0,0 +1 @@ +move.svg \ No newline at end of file diff --git a/src/svg/static/question_arrow.svg b/src/svg/static/question_arrow.svg new file mode 100644 index 0000000..272e764 --- /dev/null +++ b/src/svg/static/question_arrow.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/right_ptr.svg b/src/svg/static/right_ptr.svg new file mode 100644 index 0000000..8dcbe1e --- /dev/null +++ b/src/svg/static/right_ptr.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/svg/static/right_side.svg b/src/svg/static/right_side.svg new file mode 120000 index 0000000..36e195a --- /dev/null +++ b/src/svg/static/right_side.svg @@ -0,0 +1 @@ +left_side.svg \ No newline at end of file diff --git a/src/svg/static/right_tee.svg b/src/svg/static/right_tee.svg new file mode 100644 index 0000000..8ba22f7 --- /dev/null +++ b/src/svg/static/right_tee.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_down_arrow.svg b/src/svg/static/sb_down_arrow.svg new file mode 100644 index 0000000..8f96717 --- /dev/null +++ b/src/svg/static/sb_down_arrow.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_h_double_arrow.svg b/src/svg/static/sb_h_double_arrow.svg new file mode 100644 index 0000000..1a2f351 --- /dev/null +++ b/src/svg/static/sb_h_double_arrow.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_left_arrow.svg b/src/svg/static/sb_left_arrow.svg new file mode 100644 index 0000000..6491106 --- /dev/null +++ b/src/svg/static/sb_left_arrow.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_right_arrow.svg b/src/svg/static/sb_right_arrow.svg new file mode 100644 index 0000000..47f3f56 --- /dev/null +++ b/src/svg/static/sb_right_arrow.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_up_arrow.svg b/src/svg/static/sb_up_arrow.svg new file mode 100644 index 0000000..627e252 --- /dev/null +++ b/src/svg/static/sb_up_arrow.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/sb_v_double_arrow.svg b/src/svg/static/sb_v_double_arrow.svg new file mode 100644 index 0000000..0b3757f --- /dev/null +++ b/src/svg/static/sb_v_double_arrow.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/tcross.svg b/src/svg/static/tcross.svg new file mode 120000 index 0000000..e0b26b0 --- /dev/null +++ b/src/svg/static/tcross.svg @@ -0,0 +1 @@ +cross.svg \ No newline at end of file diff --git a/src/svg/static/top_left_corner.svg b/src/svg/static/top_left_corner.svg new file mode 120000 index 0000000..a3a3e2d --- /dev/null +++ b/src/svg/static/top_left_corner.svg @@ -0,0 +1 @@ +bottom_right_corner.svg \ No newline at end of file diff --git a/src/svg/static/top_right_corner.svg b/src/svg/static/top_right_corner.svg new file mode 120000 index 0000000..acc15d0 --- /dev/null +++ b/src/svg/static/top_right_corner.svg @@ -0,0 +1 @@ +bottom_left_corner.svg \ No newline at end of file diff --git a/src/svg/static/top_side.svg b/src/svg/static/top_side.svg new file mode 100644 index 0000000..b8666bc --- /dev/null +++ b/src/svg/static/top_side.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/svg/static/top_tee.svg b/src/svg/static/top_tee.svg new file mode 100644 index 0000000..ffd9248 --- /dev/null +++ b/src/svg/static/top_tee.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/ul_angle.svg b/src/svg/static/ul_angle.svg new file mode 100644 index 0000000..60b1912 --- /dev/null +++ b/src/svg/static/ul_angle.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/ur_angle.svg b/src/svg/static/ur_angle.svg new file mode 100644 index 0000000..fdb9b82 --- /dev/null +++ b/src/svg/static/ur_angle.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/vertical_text.svg b/src/svg/static/vertical_text.svg new file mode 100644 index 0000000..afc487f --- /dev/null +++ b/src/svg/static/vertical_text.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/svg/static/wayland_cursor.svg b/src/svg/static/wayland_cursor.svg new file mode 100644 index 0000000..3114d5d --- /dev/null +++ b/src/svg/static/wayland_cursor.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/svg/static/x_cursor.svg b/src/svg/static/x_cursor.svg new file mode 100644 index 0000000..45fa0a6 --- /dev/null +++ b/src/svg/static/x_cursor.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/svg/static/xterm.svg b/src/svg/static/xterm.svg new file mode 100644 index 0000000..73d7b47 --- /dev/null +++ b/src/svg/static/xterm.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/svg/static/zoom_in.svg b/src/svg/static/zoom_in.svg new file mode 100644 index 0000000..6a37c6d --- /dev/null +++ b/src/svg/static/zoom_in.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/svg/static/zoom_out.svg b/src/svg/static/zoom_out.svg new file mode 100644 index 0000000..da679da --- /dev/null +++ b/src/svg/static/zoom_out.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/getFrameName.ts b/src/utils/getFrameName.ts new file mode 100644 index 0000000..5b3dfff --- /dev/null +++ b/src/utils/getFrameName.ts @@ -0,0 +1,14 @@ +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) => { + const frame = frameNumber(index, 2); + return `${path.basename(fileName, ".svg")}-${frame}.png`; +}; diff --git a/src/utils/htmlTemplate.ts b/src/utils/htmlTemplate.ts new file mode 100644 index 0000000..05ea0cb --- /dev/null +++ b/src/utils/htmlTemplate.ts @@ -0,0 +1,19 @@ +export const template = ` + + + + + + Eggy Render Template + + + +
+ +
+ + +`; + +export const generateRenderTemplate = (svg: string) => + template.replace("", svg); diff --git a/src/utils/matchImages.ts b/src/utils/matchImages.ts new file mode 100644 index 0000000..aceffa8 --- /dev/null +++ b/src/utils/matchImages.ts @@ -0,0 +1,19 @@ +import { PNG } from "pngjs"; +import pixelmatch from "pixelmatch"; + +interface MatchImagesArgs { + img1Buff: Buffer; + img2Buff: Buffer; +} + +export const matchImages = ({ img1Buff, img2Buff }: MatchImagesArgs) => { + const img1 = PNG.sync.read(img1Buff); + const img2 = PNG.sync.read(img2Buff); + const { width, height } = img1; + + const diff = new PNG({ width, height }); + + return pixelmatch(img1.data, img2.data, diff.data, width, height, { + threshold: 0.25, + }); +}; diff --git a/src/utils/saveFrames.ts b/src/utils/saveFrames.ts new file mode 100644 index 0000000..f3be527 --- /dev/null +++ b/src/utils/saveFrames.ts @@ -0,0 +1,16 @@ +import fs from "fs"; +import path from "path"; +import { bitmapsDir } from "../config"; + +export interface Frames { + [fileName: string]: { + buffer: Buffer; + }; +} + +export const saveFrames = (frames: Frames) => { + for (let [fileName, { buffer }] of Object.entries(frames)) { + const out_path = path.resolve(bitmapsDir, fileName); + fs.writeFileSync(out_path, buffer, { encoding: "binary" }); + } +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a26a563 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "lib": ["es2015", "dom"], + "outDir": "dist", + "typeRoots": ["node_modules/@types"], + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "resolveJsonModule": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true + }, + "include": ["src/**/*", "node_modules/@types/puppeteer/index.d.ts"], + "exclude": ["node_modules", "**/*.test.ts"] +}