ani-cursor 0.0.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,12 +8,6 @@ I wrote a blog post about this library which you can find [here](https://jordane
8
8
 
9
9
  ## Install
10
10
 
11
- ```bash
12
- yarn add ani-cursor
13
- ```
14
-
15
- or
16
-
17
11
  ```bash
18
12
  npm install ani-cursor
19
13
  ```
@@ -39,4 +33,6 @@ h1.innerText = 'Pizza Time!';
39
33
  document.body.appendChild(h1);
40
34
 
41
35
  applyCursor("#pizza", "https://archive.org/cors/tucows_169906_Pizza_cursor/pizza.ani");
42
- ```
36
+ ```
37
+
38
+ Try the [Live Demo on CodeSandbox](https://codesandbox.io/s/jolly-thunder-9jkio?file=/src/index.js).
@@ -1,84 +1,36 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- var __importDefault = (this && this.__importDefault) || function (mod) {
39
- return (mod && mod.__esModule) ? mod : { "default": mod };
40
- };
41
- Object.defineProperty(exports, "__esModule", { value: true });
42
- var fs_1 = __importDefault(require("fs"));
43
- var path_1 = __importDefault(require("path"));
44
- var __1 = require("../");
45
- var LONG_BASE_64 = /([A-Za-z0-9+/=]{50})[A-Za-z0-9+/=]+/g;
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { convertAniBinaryToCSS } from "../index.js";
4
+ const LONG_BASE_64 = /([A-Za-z0-9+/=]{50})[A-Za-z0-9+/=]+/g;
46
5
  // Parse a `.ani` in our fixture directory and trim down the image data for use
47
6
  // in snapshot tests.
48
7
  function readPathCss(filePath) {
49
- var buffer = fs_1.default.readFileSync(path_1.default.join(__dirname, "./fixtures/", filePath));
50
- return __1.convertAniBinaryToCSS("#example", buffer).replace(LONG_BASE_64, "$1...");
8
+ const buffer = fs.readFileSync(path.join(__dirname, "./fixtures/", filePath));
9
+ return convertAniBinaryToCSS("#example", buffer).replace(LONG_BASE_64, "$1...");
51
10
  }
52
11
  // https://skins.webamp.org/skin/6e30f9e9b8f5719469809785ae5e4a1f/Super_Mario_Amp_2.wsz/
53
- describe("Super_Mario_Amp_2.wsz", function () {
54
- test("eqslid.cur", function () { return __awaiter(void 0, void 0, void 0, function () {
55
- return __generator(this, function (_a) {
56
- expect(readPathCss("Super_Mario_Amp_2/eqslid.cur")).toMatchSnapshot();
57
- return [2 /*return*/];
58
- });
59
- }); });
60
- test("close.cur", function () { return __awaiter(void 0, void 0, void 0, function () {
61
- return __generator(this, function (_a) {
62
- expect(readPathCss("Super_Mario_Amp_2/close.cur")).toMatchSnapshot();
63
- return [2 /*return*/];
64
- });
65
- }); });
12
+ describe("Super_Mario_Amp_2.wsz", () => {
13
+ test("eqslid.cur", async () => {
14
+ expect(readPathCss("Super_Mario_Amp_2/eqslid.cur")).toMatchSnapshot();
15
+ });
16
+ test("close.cur", async () => {
17
+ expect(readPathCss("Super_Mario_Amp_2/close.cur")).toMatchSnapshot();
18
+ });
66
19
  });
67
20
  // https://skins.webamp.org/skin/4308a2fc648033bf5fe7c4d56a5c8823/Green-Dimension-V2.wsz/
68
- describe("Green Dimension v2.wsz", function () {
69
- test("eqslid.cur", function () { return __awaiter(void 0, void 0, void 0, function () {
70
- return __generator(this, function (_a) {
71
- expect(readPathCss("Green Dimension v2/eqslid.cur")).toMatchSnapshot();
72
- return [2 /*return*/];
73
- });
74
- }); });
21
+ describe("Green Dimension v2.wsz", () => {
22
+ test("eqslid.cur", async () => {
23
+ expect(readPathCss("Green Dimension v2/eqslid.cur")).toMatchSnapshot();
24
+ });
75
25
  });
76
- describe("Edge cases", function () {
77
- test("piano.ani", function () { return __awaiter(void 0, void 0, void 0, function () {
78
- return __generator(this, function (_a) {
79
- expect(readPathCss("piano.ani")).toMatchSnapshot();
80
- return [2 /*return*/];
81
- });
82
- }); });
26
+ describe("AfterShock_Digital_2003.wsz", () => {
27
+ test("close.cur", async () => {
28
+ expect(readPathCss("AfterShock_Digital_2003/close.cur")).toMatchSnapshot();
29
+ });
30
+ });
31
+ describe("Edge cases", () => {
32
+ test("piano.ani", async () => {
33
+ expect(readPathCss("piano.ani")).toMatchSnapshot();
34
+ });
83
35
  });
84
36
  //# sourceMappingURL=parser.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../../src/__tests__/parser.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAoB;AACpB,8CAAwB;AACxB,yBAA4C;AAE5C,IAAM,YAAY,GAAG,sCAAsC,CAAC;AAE5D,+EAA+E;AAC/E,qBAAqB;AACrB,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAM,MAAM,GAAG,YAAE,CAAC,YAAY,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE9E,OAAO,yBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,OAAO,CACtD,YAAY,EACZ,OAAO,CACR,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,QAAQ,CAAC,uBAAuB,EAAE;IAChC,IAAI,CAAC,YAAY,EAAE;;YACjB,MAAM,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;;;SACvE,CAAC,CAAC;IACH,IAAI,CAAC,WAAW,EAAE;;YAChB,MAAM,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;;;SACtE,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,yFAAyF;AACzF,QAAQ,CAAC,wBAAwB,EAAE;IACjC,IAAI,CAAC,YAAY,EAAE;;YACjB,MAAM,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;;;SACxE,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,EAAE;IACrB,IAAI,CAAC,WAAW,EAAE;;YAChB,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;;;SACpD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../../src/__tests__/parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,YAAY,GAAG,sCAAsC,CAAC;AAE5D,+EAA+E;AAC/E,qBAAqB;AACrB,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE9E,OAAO,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,OAAO,CACtD,YAAY,EACZ,OAAO,CACR,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QAC5B,MAAM,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,yFAAyF;AACzF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QAC5B,MAAM,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export declare function convertAniBinaryToCSS(selector: string, aniBinary: Uint8Array): string;
2
+ export declare function base64FromDataArray(dataArray: Uint8Array): string;
package/dist/index.js CHANGED
@@ -1,39 +1,15 @@
1
- "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spread = (this && this.__spread) || function () {
19
- for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
20
- return ar;
21
- };
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.convertAniBinaryToCSS = void 0;
24
- var parser_1 = require("./parser");
25
- var JIFFIES_PER_MS = 1000 / 60;
1
+ import { parseAni } from "./parser.js";
2
+ const JIFFIES_PER_MS = 1000 / 60;
26
3
  // Generate CSS for an animated cursor.
27
4
  //
28
5
  // This function returns CSS containing a set of keyframes with embedded Data
29
6
  // URIs as well as a CSS rule to the given selector.
30
- function convertAniBinaryToCSS(selector, aniBinary) {
31
- var ani = readAni(aniBinary);
32
- var animationName = "ani-cursor-" + uniqueId();
33
- var keyframes = ani.frames.map(function (_a) {
34
- var url = _a.url, percents = _a.percents;
35
- var percent = percents.map(function (num) { return num + "%"; }).join(", ");
36
- return percent + " { cursor: url(" + url + "), auto; }";
7
+ export function convertAniBinaryToCSS(selector, aniBinary) {
8
+ const ani = readAni(aniBinary);
9
+ const animationName = `ani-cursor-${uniqueId()}`;
10
+ const keyframes = ani.frames.map(({ url, percents }) => {
11
+ const percent = percents.map((num) => `${num}%`).join(", ");
12
+ return `${percent} { cursor: url(${url}), auto; }`;
37
13
  });
38
14
  // CSS properties with a animation type of "discrete", like `cursor`, actually
39
15
  // switch half-way _between_ each keyframe percentage. Luckily this half-way
@@ -42,45 +18,53 @@ function convertAniBinaryToCSS(selector, aniBinary) {
42
18
  // `timing-function` of `step-end`.
43
19
  //
44
20
  // https://drafts.csswg.org/web-animations-1/#discrete
45
- var timingFunction = "step-end";
21
+ const timingFunction = "step-end";
46
22
  // Winamp (re)starts the animation cycle when your mouse enters an element. By
47
23
  // default this approach would cause the animation to run continuously, even
48
24
  // when the cursor is not visible. To match Winamp's behavior we add a
49
25
  // `:hover` pseudo selector so that the animation only runs when the cursor is
50
26
  // visible.
51
- var pseudoSelector = ":hover";
27
+ const pseudoSelector = ":hover";
52
28
  // prettier-ignore
53
- return "\n @keyframes " + animationName + " {\n " + keyframes.join("\n") + "\n }\n " + selector + pseudoSelector + " {\n animation: " + animationName + " " + ani.duration + "ms " + timingFunction + " infinite;\n }\n ";
29
+ return `
30
+ @keyframes ${animationName} {
31
+ ${keyframes.join("\n")}
32
+ }
33
+ ${selector}${pseudoSelector} {
34
+ animation: ${animationName} ${ani.duration}ms ${timingFunction} infinite;
35
+ }
36
+ `;
54
37
  }
55
- exports.convertAniBinaryToCSS = convertAniBinaryToCSS;
56
38
  function readAni(contents) {
57
39
  var _a;
58
- var ani = parser_1.parseAni(contents);
59
- var rate = (_a = ani.rate) !== null && _a !== void 0 ? _a : ani.images.map(function () { return ani.metadata.iDispRate; });
60
- var duration = sum(rate);
61
- var frames = ani.images.map(function (image) { return ({
40
+ const ani = parseAni(contents);
41
+ const rate = (_a = ani.rate) !== null && _a !== void 0 ? _a : ani.images.map(() => ani.metadata.iDispRate);
42
+ const duration = sum(rate);
43
+ const frames = ani.images.map((image) => ({
62
44
  url: curUrlFromByteArray(image),
63
45
  percents: [],
64
- }); });
65
- var elapsed = 0;
66
- rate.forEach(function (r, i) {
67
- var frameIdx = ani.seq ? ani.seq[i] : i;
46
+ }));
47
+ let elapsed = 0;
48
+ rate.forEach((r, i) => {
49
+ const frameIdx = ani.seq ? ani.seq[i] : i;
68
50
  frames[frameIdx].percents.push((elapsed / duration) * 100);
69
51
  elapsed += r;
70
52
  });
71
- return { duration: duration * JIFFIES_PER_MS, frames: frames };
53
+ return { duration: duration * JIFFIES_PER_MS, frames };
72
54
  }
73
55
  /* Utility Functions */
74
- var i = 0;
75
- var uniqueId = function () { return i++; };
76
- function base64FromDataArray(dataArray) {
77
- return window.btoa(String.fromCharCode.apply(String, __spread(dataArray)));
56
+ let i = 0;
57
+ const uniqueId = () => i++;
58
+ export function base64FromDataArray(dataArray) {
59
+ return window.btoa(Array.from(dataArray)
60
+ .map((byte) => String.fromCharCode(byte))
61
+ .join(""));
78
62
  }
79
63
  function curUrlFromByteArray(arr) {
80
- var base64 = base64FromDataArray(arr);
81
- return "data:image/x-win-bitmap;base64," + base64;
64
+ const base64 = base64FromDataArray(arr);
65
+ return `data:image/x-win-bitmap;base64,${base64}`;
82
66
  }
83
67
  function sum(values) {
84
- return values.reduce(function (total, value) { return total + value; }, 0);
68
+ return values.reduce((total, value) => total + value, 0);
85
69
  }
86
70
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/parser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare type AniMetadata = {
1
+ type AniMetadata = {
2
2
  cbSize: number;
3
3
  nFrames: number;
4
4
  nSteps: number;
@@ -9,7 +9,7 @@ declare type AniMetadata = {
9
9
  iDispRate: number;
10
10
  bfAttributes: number;
11
11
  };
12
- declare type ParsedAni = {
12
+ type ParsedAni = {
13
13
  rate: number[] | null;
14
14
  seq: number[] | null;
15
15
  images: Uint8Array[];
package/dist/parser.js CHANGED
@@ -1,23 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseAni = void 0;
4
- var riff_file_1 = require("riff-file");
5
- var byte_data_1 = require("byte-data");
6
- var DWORD = { bits: 32, be: false, signed: false, fp: false };
7
- function parseAni(arr) {
8
- var riff = new riff_file_1.RIFFFile();
1
+ import { RIFFFile } from "riff-file";
2
+ import { unpackArray, unpackString } from "byte-data";
3
+ const DWORD = { bits: 32, be: false, signed: false, fp: false };
4
+ export function parseAni(arr) {
5
+ const riff = new RIFFFile();
9
6
  riff.setSignature(arr);
10
- var signature = riff.signature;
7
+ const signature = riff.signature;
11
8
  if (signature.format !== "ACON") {
12
- throw new Error("Expected format. Expected \"ACON\", got \"" + signature.format + "\"");
9
+ throw new Error(`Expected format. Expected "ACON", got "${signature.format}"`);
13
10
  }
14
11
  // Helper function to get a chunk by chunkId and transform it if it's non-null.
15
12
  function mapChunk(chunkId, mapper) {
16
- var chunk = riff.findChunk(chunkId);
13
+ const chunk = riff.findChunk(chunkId);
17
14
  return chunk == null ? null : mapper(chunk);
18
15
  }
19
- var metadata = mapChunk("anih", function (c) {
20
- var words = byte_data_1.unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
16
+ function readImages(chunk, frameCount) {
17
+ return chunk.subChunks.slice(0, frameCount).map((c) => {
18
+ if (c.chunkId !== "icon") {
19
+ throw new Error(`Unexpected chunk type in fram: ${c.chunkId}`);
20
+ }
21
+ return arr.slice(c.chunkData.start, c.chunkData.end);
22
+ });
23
+ }
24
+ const metadata = mapChunk("anih", (c) => {
25
+ const words = unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
21
26
  return {
22
27
  cbSize: words[0],
23
28
  nFrames: words[1],
@@ -33,42 +38,42 @@ function parseAni(arr) {
33
38
  if (metadata == null) {
34
39
  throw new Error("Did not find anih");
35
40
  }
36
- var rate = mapChunk("rate", function (c) {
37
- return byte_data_1.unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
41
+ const rate = mapChunk("rate", (c) => {
42
+ return unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
38
43
  });
39
44
  // chunkIds are always four chars, hence the trailing space.
40
- var seq = mapChunk("seq ", function (c) {
41
- return byte_data_1.unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
45
+ const seq = mapChunk("seq ", (c) => {
46
+ return unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
42
47
  });
43
- var lists = riff.findChunk("LIST", true);
44
- var imageChunk = lists === null || lists === void 0 ? void 0 : lists.find(function (c) { return c.format === "fram"; });
48
+ const lists = riff.findChunk("LIST", true);
49
+ const imageChunk = lists === null || lists === void 0 ? void 0 : lists.find((c) => c.format === "fram");
45
50
  if (imageChunk == null) {
46
51
  throw new Error("Did not find fram LIST");
47
52
  }
48
- var images = imageChunk.subChunks.slice(0, metadata.nFrames).map(function (c) {
49
- if (c.chunkId !== "icon") {
50
- throw new Error("Unexpected chunk type in fram: " + c.chunkId);
51
- }
52
- return arr.slice(c.chunkData.start, c.chunkData.end);
53
- });
54
- var title = null;
55
- var artist = null;
56
- var infoChunk = lists === null || lists === void 0 ? void 0 : lists.find(function (c) { return c.format === "INFO"; });
53
+ let images = readImages(imageChunk, metadata.nFrames);
54
+ let title = null;
55
+ let artist = null;
56
+ const infoChunk = lists === null || lists === void 0 ? void 0 : lists.find((c) => c.format === "INFO");
57
57
  if (infoChunk != null) {
58
- infoChunk.subChunks.forEach(function (c) {
58
+ infoChunk.subChunks.forEach((c) => {
59
59
  switch (c.chunkId) {
60
60
  case "INAM":
61
- title = byte_data_1.unpackString(arr, c.chunkData.start, c.chunkData.end);
61
+ title = unpackString(arr, c.chunkData.start, c.chunkData.end);
62
62
  break;
63
63
  case "IART":
64
- artist = byte_data_1.unpackString(arr, c.chunkData.start, c.chunkData.end);
64
+ artist = unpackString(arr, c.chunkData.start, c.chunkData.end);
65
+ break;
66
+ case "LIST":
67
+ // Some cursors with an artist of "Created with Take ONE 3.5 (unregisterred version)" seem to have their frames here for some reason?
68
+ if (c.format === "fram") {
69
+ images = readImages(c, metadata.nFrames);
70
+ }
65
71
  break;
66
72
  default:
67
73
  // Unexpected subchunk
68
74
  }
69
75
  });
70
76
  }
71
- return { images: images, rate: rate, seq: seq, metadata: metadata, artist: artist, title: title };
77
+ return { images, rate, seq, metadata, artist, title };
72
78
  }
73
- exports.parseAni = parseAni;
74
79
  //# sourceMappingURL=parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,25 @@
1
1
  {
2
2
  "name": "ani-cursor",
3
- "version": "0.0.4",
3
+ "version": "2.3.0",
4
4
  "description": "Render .ani cursors as CSS animations in the browser",
5
+ "type": "module",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
- "files": ["dist/", "src/**/*.ts"],
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist/",
16
+ "src/**/*.ts"
17
+ ],
8
18
  "author": "Jordan Eldredge <jordan@jordaneldredge.com>",
9
19
  "license": "MIT",
20
+ "engines": {
21
+ "node": ">=22.0.0"
22
+ },
10
23
  "repository": {
11
24
  "type": "git",
12
25
  "url": "https://github.com/captbaritone/webamp.git",
@@ -18,23 +31,38 @@
18
31
  "homepage": "https://github.com/captbaritone/webamp/tree/master/packages/ani-cursor",
19
32
  "scripts": {
20
33
  "build": "tsc",
34
+ "type-check": "tsc --noEmit",
35
+ "lint": "eslint src --ext ts,js",
21
36
  "test": "jest",
22
37
  "prepublish": "tsc"
23
38
  },
24
39
  "devDependencies": {
25
- "@babel/core": "^7.12.9",
26
- "@babel/preset-env": "^7.12.7",
27
- "@babel/preset-typescript": "^7.12.7",
28
- "@types/jest": "^26.0.18",
29
- "babel-jest": "^26.6.3",
30
- "jest": "^26.6.3",
31
- "typescript": "^4.1.2"
40
+ "@babel/core": "^7.20.0",
41
+ "@babel/preset-env": "^7.20.2",
42
+ "@babel/preset-typescript": "^7.20.0",
43
+ "@swc/jest": "^0.2.24",
44
+ "@types/node": "^24.0.10",
45
+ "typescript": "^5.6.2"
32
46
  },
33
47
  "dependencies": {
34
48
  "byte-data": "18.1.1",
35
49
  "riff-file": "^1.0.3"
36
50
  },
37
51
  "jest": {
38
- "modulePathIgnorePatterns": ["dist"]
52
+ "modulePathIgnorePatterns": [
53
+ "dist"
54
+ ],
55
+ "testEnvironment": "jsdom",
56
+ "extensionsToTreatAsEsm": [
57
+ ".ts"
58
+ ],
59
+ "moduleNameMapper": {
60
+ "^(\\.{1,2}/.*)\\.js$": "$1"
61
+ },
62
+ "transform": {
63
+ "^.+\\.(t|j)sx?$": [
64
+ "@swc/jest"
65
+ ]
66
+ }
39
67
  }
40
68
  }
@@ -1,6 +1,6 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { convertAniBinaryToCSS } from "../";
3
+ import { convertAniBinaryToCSS } from "../index.js";
4
4
 
5
5
  const LONG_BASE_64 = /([A-Za-z0-9+/=]{50})[A-Za-z0-9+/=]+/g;
6
6
 
@@ -32,6 +32,12 @@ describe("Green Dimension v2.wsz", () => {
32
32
  });
33
33
  });
34
34
 
35
+ describe("AfterShock_Digital_2003.wsz", () => {
36
+ test("close.cur", async () => {
37
+ expect(readPathCss("AfterShock_Digital_2003/close.cur")).toMatchSnapshot();
38
+ });
39
+ });
40
+
35
41
  describe("Edge cases", () => {
36
42
  test("piano.ani", async () => {
37
43
  expect(readPathCss("piano.ani")).toMatchSnapshot();
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { parseAni } from "./parser";
1
+ import { parseAni } from "./parser.js";
2
2
 
3
3
  type AniCursorImage = {
4
4
  frames: {
@@ -79,8 +79,12 @@ function readAni(contents: Uint8Array): AniCursorImage {
79
79
  let i = 0;
80
80
  const uniqueId = () => i++;
81
81
 
82
- function base64FromDataArray(dataArray: Uint8Array): string {
83
- return window.btoa(String.fromCharCode(...dataArray));
82
+ export function base64FromDataArray(dataArray: Uint8Array): string {
83
+ return window.btoa(
84
+ Array.from(dataArray)
85
+ .map((byte) => String.fromCharCode(byte))
86
+ .join("")
87
+ );
84
88
  }
85
89
 
86
90
  function curUrlFromByteArray(arr: Uint8Array) {
package/src/parser.ts CHANGED
@@ -53,6 +53,15 @@ export function parseAni(arr: Uint8Array): ParsedAni {
53
53
  return chunk == null ? null : mapper(chunk);
54
54
  }
55
55
 
56
+ function readImages(chunk: Chunk, frameCount: number): Uint8Array[] {
57
+ return chunk.subChunks.slice(0, frameCount).map((c) => {
58
+ if (c.chunkId !== "icon") {
59
+ throw new Error(`Unexpected chunk type in fram: ${c.chunkId}`);
60
+ }
61
+ return arr.slice(c.chunkData.start, c.chunkData.end);
62
+ });
63
+ }
64
+
56
65
  const metadata = mapChunk("anih", (c) => {
57
66
  const words = unpackArray(arr, DWORD, c.chunkData.start, c.chunkData.end);
58
67
  return {
@@ -86,12 +95,7 @@ export function parseAni(arr: Uint8Array): ParsedAni {
86
95
  throw new Error("Did not find fram LIST");
87
96
  }
88
97
 
89
- const images = imageChunk.subChunks.slice(0, metadata.nFrames).map((c) => {
90
- if (c.chunkId !== "icon") {
91
- throw new Error(`Unexpected chunk type in fram: ${c.chunkId}`);
92
- }
93
- return arr.slice(c.chunkData.start, c.chunkData.end);
94
- });
98
+ let images = readImages(imageChunk, metadata.nFrames);
95
99
 
96
100
  let title = null;
97
101
  let artist = null;
@@ -106,6 +110,13 @@ export function parseAni(arr: Uint8Array): ParsedAni {
106
110
  case "IART":
107
111
  artist = unpackString(arr, c.chunkData.start, c.chunkData.end);
108
112
  break;
113
+ case "LIST":
114
+ // Some cursors with an artist of "Created with Take ONE 3.5 (unregisterred version)" seem to have their frames here for some reason?
115
+ if (c.format === "fram") {
116
+ images = readImages(c, metadata.nFrames);
117
+ }
118
+ break;
119
+
109
120
  default:
110
121
  // Unexpected subchunk
111
122
  }