@dava96/osrs-icons 1.0.15 → 1.0.17
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/LICENSE +25 -0
- package/README.md +170 -5
- package/dist/cjs/animateCursor.d.ts +72 -0
- package/dist/cjs/animateCursor.d.ts.map +1 -0
- package/dist/cjs/animateCursor.js +94 -0
- package/dist/cjs/applyCursors.d.ts +64 -0
- package/dist/cjs/applyCursors.d.ts.map +1 -0
- package/dist/cjs/applyCursors.js +82 -0
- package/dist/cjs/flip.d.ts +55 -0
- package/dist/cjs/flip.d.ts.map +1 -0
- package/dist/cjs/flip.js +117 -0
- package/dist/cjs/generated/icons.d.ts +1 -0
- package/dist/cjs/generated/icons.d.ts.map +1 -0
- package/dist/cjs/generated/meta.d.ts +15 -0
- package/dist/cjs/generated/meta.d.ts.map +1 -0
- package/dist/cjs/generated/meta.js +14 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +20 -1
- package/dist/cjs/packs.d.ts +142 -0
- package/dist/cjs/packs.d.ts.map +1 -0
- package/dist/cjs/packs.js +192 -0
- package/dist/esm/animateCursor.d.ts +72 -0
- package/dist/esm/animateCursor.d.ts.map +1 -0
- package/dist/esm/animateCursor.js +91 -0
- package/dist/esm/applyCursors.d.ts +64 -0
- package/dist/esm/applyCursors.d.ts.map +1 -0
- package/dist/esm/applyCursors.js +79 -0
- package/dist/esm/flip.d.ts +55 -0
- package/dist/esm/flip.d.ts.map +1 -0
- package/dist/esm/flip.js +114 -0
- package/dist/esm/generated/icons.d.ts +1 -0
- package/dist/esm/generated/icons.d.ts.map +1 -0
- package/dist/esm/generated/meta.d.ts +15 -0
- package/dist/esm/generated/meta.d.ts.map +1 -0
- package/dist/esm/generated/meta.js +14 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +18 -1
- package/dist/esm/packs.d.ts +142 -0
- package/dist/esm/packs.d.ts.map +1 -0
- package/dist/esm/packs.js +189 -0
- package/package.json +2 -2
- package/dist/cjs/index_test.d.ts +0 -1
- package/dist/cjs/index_test.js +0 -110
- package/dist/esm/index_test.d.ts +0 -1
- package/dist/esm/index_test.js +0 -105
package/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Attribution — NonCommercial — ShareAlike 3.0 Unported
|
|
2
|
+
(CC BY-NC-SA 3.0)
|
|
3
|
+
|
|
4
|
+
Full licence text: https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
|
|
5
|
+
|
|
6
|
+
You are free to:
|
|
7
|
+
|
|
8
|
+
Share — copy and redistribute the material in any medium or format.
|
|
9
|
+
Adapt — remix, transform, and build upon the material.
|
|
10
|
+
|
|
11
|
+
Under the following terms:
|
|
12
|
+
|
|
13
|
+
Attribution — You must give appropriate credit, provide a link to
|
|
14
|
+
the licence, and indicate if changes were made.
|
|
15
|
+
|
|
16
|
+
NonCommercial — You may not use the material for commercial purposes.
|
|
17
|
+
|
|
18
|
+
ShareAlike — If you remix, transform, or build upon the material, you
|
|
19
|
+
must distribute your contributions under the same licence.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
This project is not affiliated with Jagex Ltd.
|
|
24
|
+
OSRS icons are sourced from the Old School RuneScape Wiki and are the
|
|
25
|
+
property of Jagex / the Wiki contributors.
|
package/README.md
CHANGED
|
@@ -8,12 +8,47 @@ Designed for easy integration with modern web apps, with full tree-shaking suppo
|
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
[](https://github.com/Dava96/osrs-icons)
|
|
10
10
|
|
|
11
|
+
📖 **[Browse icons & build packs →](https://dava96.github.io/osrs-icons/)**
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [Usage](#usage)
|
|
18
|
+
- [CSS Cursor](#css-cursor-tree-shaking-supported)
|
|
19
|
+
- [As an Image](#as-an-image)
|
|
20
|
+
- [Icon Discovery](#icon-discovery)
|
|
21
|
+
- [CDN (No Build Step)](#cdn-usage-no-build-step)
|
|
22
|
+
- [Cursor Packs](#cursor-packs)
|
|
23
|
+
- [Utilities](#utilities)
|
|
24
|
+
- [flipCursor](#flip-cursor)
|
|
25
|
+
- [applyCursors](#apply-cursors)
|
|
26
|
+
- [errorCursor](#error-cursor-)
|
|
27
|
+
- [API Reference](#api-reference)
|
|
28
|
+
- [Browser Compatibility](#browser-compatibility)
|
|
29
|
+
- [How It Works](#how-it-works)
|
|
30
|
+
- [Contributing](#contributing)
|
|
31
|
+
- [License](#license)
|
|
32
|
+
|
|
11
33
|
## Installation
|
|
12
34
|
|
|
13
35
|
```bash
|
|
14
36
|
npm install @dava96/osrs-icons
|
|
15
37
|
```
|
|
16
38
|
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { abyssalWhip } from '@dava96/osrs-icons';
|
|
43
|
+
|
|
44
|
+
// As a cursor
|
|
45
|
+
<div style={{ cursor: abyssalWhip }}>Hover me!</div>;
|
|
46
|
+
|
|
47
|
+
// As an image
|
|
48
|
+
import { toDataUrl } from '@dava96/osrs-icons';
|
|
49
|
+
<img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip" />;
|
|
50
|
+
```
|
|
51
|
+
|
|
17
52
|
## Usage
|
|
18
53
|
|
|
19
54
|
### CSS Cursor (Tree-Shaking Supported)
|
|
@@ -38,7 +73,7 @@ Use the `toDataUrl` helper to extract the raw data URL for use outside of CSS:
|
|
|
38
73
|
import { abyssalWhip, dragonScimitar, toDataUrl } from '@dava96/osrs-icons';
|
|
39
74
|
|
|
40
75
|
// Single icon
|
|
41
|
-
<img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip"
|
|
76
|
+
<img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip" />;
|
|
42
77
|
|
|
43
78
|
// Multiple icons at once
|
|
44
79
|
const urls = toDataUrl({
|
|
@@ -57,10 +92,12 @@ Browse all available icons programmatically with `iconNames`, or restrict values
|
|
|
57
92
|
import { iconNames, type IconName } from '@dava96/osrs-icons';
|
|
58
93
|
|
|
59
94
|
// Search / autocomplete
|
|
60
|
-
const results = iconNames.filter(name => name.includes('dragon'));
|
|
95
|
+
const results = iconNames.filter((name) => name.includes('dragon'));
|
|
61
96
|
|
|
62
97
|
// Type-safe icon references
|
|
63
|
-
function setCustomCursor(name: IconName) {
|
|
98
|
+
function setCustomCursor(name: IconName) {
|
|
99
|
+
/* ... */
|
|
100
|
+
}
|
|
64
101
|
```
|
|
65
102
|
|
|
66
103
|
### CDN Usage (No Build Step)
|
|
@@ -70,11 +107,129 @@ You can use the package directly in the browser via ESM.sh:
|
|
|
70
107
|
```html
|
|
71
108
|
<script type="module">
|
|
72
109
|
import { AbyssalWhip } from 'https://esm.sh/@dava96/osrs-icons';
|
|
73
|
-
|
|
110
|
+
|
|
74
111
|
document.body.style.cursor = AbyssalWhip;
|
|
75
112
|
</script>
|
|
76
113
|
```
|
|
77
114
|
|
|
115
|
+
## Cursor Packs
|
|
116
|
+
|
|
117
|
+
Pre-built thematic icon groups — each pack groups related icons by their in-game state:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { runePack, bucketPack, coinsPack } from '@dava96/osrs-icons';
|
|
121
|
+
|
|
122
|
+
// Rune pack — all 10 F2P runes
|
|
123
|
+
element.style.cursor = runePack.air;
|
|
124
|
+
|
|
125
|
+
// Bucket fill progression — great for loading states
|
|
126
|
+
const stages = bucketPack.stages; // [empty, 1/5, 2/5, 3/5, 4/5, full]
|
|
127
|
+
const index = Math.min(Math.floor((progress / 100) * stages.length), stages.length - 1);
|
|
128
|
+
element.style.cursor = stages[index];
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Available packs:**
|
|
132
|
+
|
|
133
|
+
| Pack | Keys |
|
|
134
|
+
| ------------ | ----------------------------------------------------------------------------------------------- |
|
|
135
|
+
| `coinsPack` | `_1` to `_10000` + `stages[]` |
|
|
136
|
+
| `bucketPack` | `empty` to `full` + `stages[]` |
|
|
137
|
+
| `runePack` | `air`, `fire`, `water`, `earth`, `chaos`, `mind`, `death`, `law`, `nature`, `body` + `stages[]` |
|
|
138
|
+
|
|
139
|
+
## Utilities
|
|
140
|
+
|
|
141
|
+
### Flip Cursor
|
|
142
|
+
|
|
143
|
+
Many OSRS icons face right, but cursors typically point left. Flip one icon, an array, or an entire pack:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { abyssalWhip, runePack, flipCursor } from '@dava96/osrs-icons';
|
|
147
|
+
|
|
148
|
+
// Single icon
|
|
149
|
+
const leftFacing = await flipCursor(abyssalWhip);
|
|
150
|
+
|
|
151
|
+
// Array of icons
|
|
152
|
+
const [flippedAir, flippedFire] = await flipCursor([runePack.air, runePack.fire]);
|
|
153
|
+
|
|
154
|
+
// Entire pack — flips all values and stages in one call
|
|
155
|
+
const flippedRunes = await flipCursor(runePack);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Results are cached internally — flipping the same icon twice returns instantly. Browser-only (uses Canvas API); returns the original value in Node.js/SSR.
|
|
159
|
+
|
|
160
|
+
### Apply Cursors
|
|
161
|
+
|
|
162
|
+
Map OSRS icons to standard CSS cursor states with a one-liner:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { abyssalWhip, dragonScimitar, bucketPack, applyCursors } from '@dava96/osrs-icons';
|
|
166
|
+
|
|
167
|
+
const cleanup = applyCursors({
|
|
168
|
+
default: abyssalWhip,
|
|
169
|
+
pointer: dragonScimitar,
|
|
170
|
+
wait: bucketPack.full,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Later, revert to browser defaults
|
|
174
|
+
cleanup();
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
You can also scope cursors to a specific element:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
applyCursors({ default: abyssalWhip }, document.getElementById('game-area')!);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Error Cursor 🐟
|
|
184
|
+
|
|
185
|
+
Use the iconic red herring as your error cursor:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { errorCursor } from '@dava96/osrs-icons';
|
|
189
|
+
|
|
190
|
+
// Also available via herringPack.error
|
|
191
|
+
element.style.cursor = errorCursor;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## API Reference
|
|
195
|
+
|
|
196
|
+
### Types
|
|
197
|
+
|
|
198
|
+
| Type | Description |
|
|
199
|
+
| --------------- | ------------------------------------------------------------------------------------------ |
|
|
200
|
+
| `IconName` | Union of all valid icon name strings (for type-safe references) |
|
|
201
|
+
| `CursorMapping` | `Partial<Record<CursorState, string>>` — maps CSS cursor states to icon values |
|
|
202
|
+
| `CursorState` | `'default' \| 'pointer' \| 'wait' \| 'text' \| 'move' \| ...` — standard CSS cursor states |
|
|
203
|
+
|
|
204
|
+
### Functions
|
|
205
|
+
|
|
206
|
+
| Function | Signature | Description |
|
|
207
|
+
| -------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
208
|
+
| `toDataUrl` | `(cursor: string) → string` | Extracts the raw `data:image/png;base64,...` URL from a CSS cursor value |
|
|
209
|
+
| `toDataUrl` | `(cursors: Record<K, string>) → Record<K, string>` | Batch version — extracts URLs from multiple cursor values |
|
|
210
|
+
| `flipCursor` | `(cursor: string) → Promise<string>` | Horizontally flips a cursor icon at runtime via Canvas API. Cached. Browser-only. |
|
|
211
|
+
| `applyCursors` | `(mapping: CursorMapping, target?: HTMLElement) → () => void` | Injects a `<style>` tag mapping cursor states to OSRS icons. Returns a cleanup function. |
|
|
212
|
+
|
|
213
|
+
### Constants
|
|
214
|
+
|
|
215
|
+
| Export | Type | Description |
|
|
216
|
+
| ------------- | ------------------------ | ---------------------------------------------------------- |
|
|
217
|
+
| `iconNames` | `readonly string[]` | Array of all available icon name strings |
|
|
218
|
+
| `errorCursor` | `string` | Semantic alias for `redHerring` |
|
|
219
|
+
| `*Pack` | `Record<string, string>` | Pre-built cursor packs (see [Cursor Packs](#cursor-packs)) |
|
|
220
|
+
|
|
221
|
+
## Browser Compatibility
|
|
222
|
+
|
|
223
|
+
| Feature | Browser | Node.js / SSR |
|
|
224
|
+
| -------------- | ---------------------- | ------------------------- |
|
|
225
|
+
| Icon imports | ✅ All | ✅ All |
|
|
226
|
+
| `toDataUrl` | ✅ All | ✅ All |
|
|
227
|
+
| `applyCursors` | ✅ All modern | ⚠️ Returns no-op cleanup |
|
|
228
|
+
| `flipCursor` | ✅ Canvas API required | ⚠️ Returns original value |
|
|
229
|
+
| Cursor packs | ✅ All | ✅ All |
|
|
230
|
+
|
|
231
|
+
All features are SSR-safe — browser-only features degrade gracefully in Node.js environments by returning safe fallback values.
|
|
232
|
+
|
|
78
233
|
## How It Works
|
|
79
234
|
|
|
80
235
|
The build script fetches every inventory sprite (~17,400 icons) from the
|
|
@@ -83,9 +238,19 @@ compresses them as palette PNGs, and generates a TypeScript file of named export
|
|
|
83
238
|
|
|
84
239
|
Each icon is a small ~32×32 pixel sprite, base64-encoded inline — no external assets to host.
|
|
85
240
|
|
|
241
|
+
### Package Output
|
|
242
|
+
|
|
243
|
+
| Format | Path | Use |
|
|
244
|
+
| ------ | --------------------- | ------------------------------------ |
|
|
245
|
+
| ESM | `dist/esm/index.js` | `import` (bundlers, modern browsers) |
|
|
246
|
+
| CJS | `dist/cjs/index.js` | `require()` (Node.js, legacy) |
|
|
247
|
+
| Types | `dist/cjs/index.d.ts` | TypeScript definitions |
|
|
248
|
+
|
|
249
|
+
The package has `"sideEffects": false` for optimal tree-shaking in Webpack, Rollup, Vite, and esbuild.
|
|
250
|
+
|
|
86
251
|
## Contributing
|
|
87
252
|
|
|
88
|
-
See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on updating icons and publishing new versions.
|
|
253
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on local development, updating icons, and publishing new versions.
|
|
89
254
|
|
|
90
255
|
## License
|
|
91
256
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link animateCursor}.
|
|
3
|
+
*/
|
|
4
|
+
export interface AnimateCursorOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Total duration of one full animation cycle in milliseconds.
|
|
7
|
+
* Each frame occupies `duration / frames.length` of the cycle.
|
|
8
|
+
*
|
|
9
|
+
* @default 1000
|
|
10
|
+
*/
|
|
11
|
+
duration?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Element to scope the animated cursor to.
|
|
14
|
+
* When omitted the cursor animates on the entire page (`*`).
|
|
15
|
+
*/
|
|
16
|
+
target?: HTMLElement;
|
|
17
|
+
/**
|
|
18
|
+
* How many times the cycle should repeat.
|
|
19
|
+
* Use `Infinity` (the default) for a continuous loop.
|
|
20
|
+
*
|
|
21
|
+
* @default Infinity
|
|
22
|
+
*/
|
|
23
|
+
iterations?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Animates a cursor by cycling through an ordered array of OSRS icon
|
|
27
|
+
* strings using a pure‑CSS `@keyframes` rule.
|
|
28
|
+
*
|
|
29
|
+
* Each frame is assigned an equal slice of the total `duration` and
|
|
30
|
+
* transitions are **discrete** (`step-end`), producing a clean
|
|
31
|
+
* frame‑by‑frame sprite animation — no JavaScript timers required.
|
|
32
|
+
*
|
|
33
|
+
* **Browser‑only** — in non‑browser environments (Node / SSR) this
|
|
34
|
+
* is a no‑op that returns an empty cleanup function.
|
|
35
|
+
*
|
|
36
|
+
* @param frames - An ordered array of CSS cursor strings (≥ 2).
|
|
37
|
+
* @param options - Optional configuration for duration, target, and iterations.
|
|
38
|
+
* @returns A cleanup function that removes the injected styles and
|
|
39
|
+
* stops the animation.
|
|
40
|
+
*
|
|
41
|
+
* @throws {Error} If fewer than 2 frames are provided.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* import {
|
|
46
|
+
* coins1, coins2, coins3, coins4, coins5,
|
|
47
|
+
* animateCursor,
|
|
48
|
+
* } from '@dava96/osrs-icons';
|
|
49
|
+
*
|
|
50
|
+
* // Animate a growing coin stack on the whole page
|
|
51
|
+
* const stop = animateCursor(
|
|
52
|
+
* [coins1, coins2, coins3, coins4, coins5],
|
|
53
|
+
* { duration: 1200 },
|
|
54
|
+
* );
|
|
55
|
+
*
|
|
56
|
+
* // Later, stop the animation and clean up
|
|
57
|
+
* stop();
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { lobsterRaw, lobsterCooked, lobsterBurnt, animateCursor } from '@dava96/osrs-icons';
|
|
63
|
+
*
|
|
64
|
+
* // Scope to a specific element, play 3 times
|
|
65
|
+
* const stop = animateCursor(
|
|
66
|
+
* [lobsterRaw, lobsterCooked, lobsterBurnt],
|
|
67
|
+
* { duration: 900, target: document.getElementById('cooking')!, iterations: 3 },
|
|
68
|
+
* );
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function animateCursor(frames: string[], options?: AnimateCursorOptions): () => void;
|
|
72
|
+
//# sourceMappingURL=animateCursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animateCursor.d.ts","sourceRoot":"","sources":["../../src/animateCursor.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,IAAI,CAiD9F"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.animateCursor = animateCursor;
|
|
4
|
+
/**
|
|
5
|
+
* Animates a cursor by cycling through an ordered array of OSRS icon
|
|
6
|
+
* strings using a pure‑CSS `@keyframes` rule.
|
|
7
|
+
*
|
|
8
|
+
* Each frame is assigned an equal slice of the total `duration` and
|
|
9
|
+
* transitions are **discrete** (`step-end`), producing a clean
|
|
10
|
+
* frame‑by‑frame sprite animation — no JavaScript timers required.
|
|
11
|
+
*
|
|
12
|
+
* **Browser‑only** — in non‑browser environments (Node / SSR) this
|
|
13
|
+
* is a no‑op that returns an empty cleanup function.
|
|
14
|
+
*
|
|
15
|
+
* @param frames - An ordered array of CSS cursor strings (≥ 2).
|
|
16
|
+
* @param options - Optional configuration for duration, target, and iterations.
|
|
17
|
+
* @returns A cleanup function that removes the injected styles and
|
|
18
|
+
* stops the animation.
|
|
19
|
+
*
|
|
20
|
+
* @throws {Error} If fewer than 2 frames are provided.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import {
|
|
25
|
+
* coins1, coins2, coins3, coins4, coins5,
|
|
26
|
+
* animateCursor,
|
|
27
|
+
* } from '@dava96/osrs-icons';
|
|
28
|
+
*
|
|
29
|
+
* // Animate a growing coin stack on the whole page
|
|
30
|
+
* const stop = animateCursor(
|
|
31
|
+
* [coins1, coins2, coins3, coins4, coins5],
|
|
32
|
+
* { duration: 1200 },
|
|
33
|
+
* );
|
|
34
|
+
*
|
|
35
|
+
* // Later, stop the animation and clean up
|
|
36
|
+
* stop();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { lobsterRaw, lobsterCooked, lobsterBurnt, animateCursor } from '@dava96/osrs-icons';
|
|
42
|
+
*
|
|
43
|
+
* // Scope to a specific element, play 3 times
|
|
44
|
+
* const stop = animateCursor(
|
|
45
|
+
* [lobsterRaw, lobsterCooked, lobsterBurnt],
|
|
46
|
+
* { duration: 900, target: document.getElementById('cooking')!, iterations: 3 },
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
function animateCursor(frames, options = {}) {
|
|
51
|
+
if (frames.length < 2) {
|
|
52
|
+
throw new Error(`animateCursor requires at least 2 frames, received ${frames.length}.`);
|
|
53
|
+
}
|
|
54
|
+
if (typeof document === 'undefined') {
|
|
55
|
+
return () => { };
|
|
56
|
+
}
|
|
57
|
+
const { duration = 1000, target, iterations = Infinity } = options;
|
|
58
|
+
const animationName = generateAnimationName();
|
|
59
|
+
const scopeId = `${animationName}-scope`;
|
|
60
|
+
const selector = target ? `[data-osrs-anim-id="${scopeId}"]` : '*';
|
|
61
|
+
if (target) {
|
|
62
|
+
target.setAttribute('data-osrs-anim-id', scopeId);
|
|
63
|
+
}
|
|
64
|
+
const keyframeSteps = frames
|
|
65
|
+
.map((cursorValue, index) => {
|
|
66
|
+
const percentage = ((index / frames.length) * 100).toFixed(2);
|
|
67
|
+
return ` ${percentage}% { cursor: ${cursorValue}; }`;
|
|
68
|
+
})
|
|
69
|
+
.join('\n');
|
|
70
|
+
const iterationCount = iterations === Infinity ? 'infinite' : String(iterations);
|
|
71
|
+
const css = [
|
|
72
|
+
`@keyframes ${animationName} {`,
|
|
73
|
+
keyframeSteps,
|
|
74
|
+
'}',
|
|
75
|
+
`${selector} {`,
|
|
76
|
+
` animation: ${animationName} ${duration}ms step-end ${iterationCount};`,
|
|
77
|
+
'}',
|
|
78
|
+
].join('\n');
|
|
79
|
+
const styleElement = document.createElement('style');
|
|
80
|
+
styleElement.textContent = css;
|
|
81
|
+
styleElement.setAttribute('data-osrs-animate', 'true');
|
|
82
|
+
document.head.appendChild(styleElement);
|
|
83
|
+
return () => {
|
|
84
|
+
styleElement.remove();
|
|
85
|
+
if (target) {
|
|
86
|
+
target.removeAttribute('data-osrs-anim-id');
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** Generates a short unique ID for animation scoping. */
|
|
91
|
+
let animCounter = 0;
|
|
92
|
+
function generateAnimationName() {
|
|
93
|
+
return `osrs-anim-${++animCounter}-${Date.now().toString(36)}`;
|
|
94
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard CSS cursor states that can be mapped to OSRS icons.
|
|
3
|
+
*
|
|
4
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
|
|
5
|
+
*/
|
|
6
|
+
export type CursorState = 'default' | 'pointer' | 'wait' | 'text' | 'move' | 'crosshair' | 'grab' | 'grabbing' | 'not-allowed' | 'help' | 'progress' | 'cell' | 'copy' | 'alias' | 'no-drop' | 'col-resize' | 'row-resize' | 'n-resize' | 'e-resize' | 's-resize' | 'w-resize' | 'zoom-in' | 'zoom-out';
|
|
7
|
+
/**
|
|
8
|
+
* A mapping of CSS cursor states to OSRS icon cursor strings.
|
|
9
|
+
*
|
|
10
|
+
* Only include the states you want to override — unlisted states
|
|
11
|
+
* keep their default browser cursor.
|
|
12
|
+
*/
|
|
13
|
+
export type CursorMapping = Partial<Record<CursorState, string>>;
|
|
14
|
+
/**
|
|
15
|
+
* Applies OSRS cursor icons to CSS cursor states on a target element
|
|
16
|
+
* or globally across the entire page.
|
|
17
|
+
*
|
|
18
|
+
* Injects a `<style>` tag with CSS rules that map each specified cursor
|
|
19
|
+
* state to the given OSRS icon. Returns a cleanup function that removes
|
|
20
|
+
* the injected styles and restores the previous cursors.
|
|
21
|
+
*
|
|
22
|
+
* **Browser-only** — in non-browser environments this is a no-op that
|
|
23
|
+
* returns an empty cleanup function.
|
|
24
|
+
*
|
|
25
|
+
* @param mapping - An object mapping CSS cursor states to OSRS cursor strings.
|
|
26
|
+
* @param target - Optional element to scope the cursors to. Defaults to the
|
|
27
|
+
* entire document (global).
|
|
28
|
+
* @returns A cleanup function that reverts all applied cursors.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { abyssalWhip, dragonScimitar, applyCursors } from '@dava96/osrs-icons';
|
|
33
|
+
*
|
|
34
|
+
* // Apply globally
|
|
35
|
+
* const remove = applyCursors({
|
|
36
|
+
* default: abyssalWhip,
|
|
37
|
+
* pointer: dragonScimitar,
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Later, revert to browser defaults
|
|
41
|
+
* remove();
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { bucketPack, applyCursors } from '@dava96/osrs-icons';
|
|
47
|
+
*
|
|
48
|
+
* // Scope to a specific element
|
|
49
|
+
* const cleanup = applyCursors(
|
|
50
|
+
* { wait: bucketPack.full },
|
|
51
|
+
* document.getElementById('loading-area')!,
|
|
52
|
+
* );
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { herringPack, applyCursors } from '@dava96/osrs-icons';
|
|
58
|
+
*
|
|
59
|
+
* // Use the red herring for error states!
|
|
60
|
+
* applyCursors({ not-allowed: herringPack.error });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function applyCursors(mapping: CursorMapping, target?: HTMLElement): () => void;
|
|
64
|
+
//# sourceMappingURL=applyCursors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyCursors.d.ts","sourceRoot":"","sources":["../../src/applyCursors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,SAAS,GACT,MAAM,GACN,MAAM,GACN,MAAM,GACN,WAAW,GACX,MAAM,GACN,UAAU,GACV,aAAa,GACb,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,UAAU,GACV,UAAU,GACV,UAAU,GACV,SAAS,GACT,UAAU,CAAC;AAEf;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI,CA6BrF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyCursors = applyCursors;
|
|
4
|
+
/**
|
|
5
|
+
* Applies OSRS cursor icons to CSS cursor states on a target element
|
|
6
|
+
* or globally across the entire page.
|
|
7
|
+
*
|
|
8
|
+
* Injects a `<style>` tag with CSS rules that map each specified cursor
|
|
9
|
+
* state to the given OSRS icon. Returns a cleanup function that removes
|
|
10
|
+
* the injected styles and restores the previous cursors.
|
|
11
|
+
*
|
|
12
|
+
* **Browser-only** — in non-browser environments this is a no-op that
|
|
13
|
+
* returns an empty cleanup function.
|
|
14
|
+
*
|
|
15
|
+
* @param mapping - An object mapping CSS cursor states to OSRS cursor strings.
|
|
16
|
+
* @param target - Optional element to scope the cursors to. Defaults to the
|
|
17
|
+
* entire document (global).
|
|
18
|
+
* @returns A cleanup function that reverts all applied cursors.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { abyssalWhip, dragonScimitar, applyCursors } from '@dava96/osrs-icons';
|
|
23
|
+
*
|
|
24
|
+
* // Apply globally
|
|
25
|
+
* const remove = applyCursors({
|
|
26
|
+
* default: abyssalWhip,
|
|
27
|
+
* pointer: dragonScimitar,
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Later, revert to browser defaults
|
|
31
|
+
* remove();
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { bucketPack, applyCursors } from '@dava96/osrs-icons';
|
|
37
|
+
*
|
|
38
|
+
* // Scope to a specific element
|
|
39
|
+
* const cleanup = applyCursors(
|
|
40
|
+
* { wait: bucketPack.full },
|
|
41
|
+
* document.getElementById('loading-area')!,
|
|
42
|
+
* );
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { herringPack, applyCursors } from '@dava96/osrs-icons';
|
|
48
|
+
*
|
|
49
|
+
* // Use the red herring for error states!
|
|
50
|
+
* applyCursors({ not-allowed: herringPack.error });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
function applyCursors(mapping, target) {
|
|
54
|
+
if (typeof document === 'undefined') {
|
|
55
|
+
return () => { };
|
|
56
|
+
}
|
|
57
|
+
const styleElement = document.createElement('style');
|
|
58
|
+
const selector = target ? `[data-osrs-cursor-id="${generateId()}"]` : '*';
|
|
59
|
+
if (target) {
|
|
60
|
+
target.setAttribute('data-osrs-cursor-id', selector.slice(22, -2));
|
|
61
|
+
}
|
|
62
|
+
const rules = Object.entries(mapping)
|
|
63
|
+
.map(([state, cursorValue]) => {
|
|
64
|
+
const fallback = state === 'default' ? 'auto' : state;
|
|
65
|
+
return `${selector} { cursor: ${cursorValue.replace(', auto', `, ${fallback}`)}; }`;
|
|
66
|
+
})
|
|
67
|
+
.join('\n');
|
|
68
|
+
styleElement.textContent = rules;
|
|
69
|
+
styleElement.setAttribute('data-osrs-cursors', 'true');
|
|
70
|
+
document.head.appendChild(styleElement);
|
|
71
|
+
return () => {
|
|
72
|
+
styleElement.remove();
|
|
73
|
+
if (target) {
|
|
74
|
+
target.removeAttribute('data-osrs-cursor-id');
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Generates a short unique ID for scoping cursor styles to elements. */
|
|
79
|
+
let idCounter = 0;
|
|
80
|
+
function generateId() {
|
|
81
|
+
return `osrs-${++idCounter}-${Date.now().toString(36)}`;
|
|
82
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horizontally flips CSS cursor icons so they point in the opposite direction.
|
|
3
|
+
*
|
|
4
|
+
* Many OSRS inventory icons face right, but cursor conventions typically
|
|
5
|
+
* expect left-facing images. This helper mirrors the embedded base64 PNG
|
|
6
|
+
* using the Canvas API and returns new, ready-to-use CSS cursor strings.
|
|
7
|
+
*
|
|
8
|
+
* Results are cached internally — flipping the same icon twice returns
|
|
9
|
+
* the cached value instantly.
|
|
10
|
+
*
|
|
11
|
+
* **Browser-only** — requires the Canvas API. In non-browser environments
|
|
12
|
+
* (Node.js, SSR) the original cursor strings are returned unchanged.
|
|
13
|
+
*
|
|
14
|
+
* Supports three input shapes:
|
|
15
|
+
* - **Single string** → returns a single flipped string.
|
|
16
|
+
* - **Array of strings** → returns an array of flipped strings (same order).
|
|
17
|
+
* - **Record of strings** → returns a record with the same keys, values flipped.
|
|
18
|
+
* Perfect for flipping an entire pack in one call.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { abyssalWhip, flipCursor } from '@dava96/osrs-icons';
|
|
23
|
+
*
|
|
24
|
+
* // Single icon
|
|
25
|
+
* const flipped = await flipCursor(abyssalWhip);
|
|
26
|
+
* document.body.style.cursor = flipped;
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { coinsPack, flipCursor } from '@dava96/osrs-icons';
|
|
32
|
+
*
|
|
33
|
+
* // Flip an entire pack
|
|
34
|
+
* const flippedPack = await flipCursor(coinsPack);
|
|
35
|
+
* // flippedPack._1, flippedPack._2, ... are all flipped
|
|
36
|
+
* // flippedPack.stages is a flipped array
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { airRune, fireRune, flipCursor } from '@dava96/osrs-icons';
|
|
42
|
+
*
|
|
43
|
+
* // Flip an array of cursors
|
|
44
|
+
* const [flippedAir, flippedFire] = await flipCursor([airRune, fireRune]);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
/** Flip a single CSS cursor string. */
|
|
48
|
+
export declare function flipCursor(cursorValue: string): Promise<string>;
|
|
49
|
+
/** Flip an array of CSS cursor strings, preserving order. */
|
|
50
|
+
export declare function flipCursor(cursorValues: readonly string[]): Promise<string[]>;
|
|
51
|
+
/** Flip every string value in a record (e.g. a pack object), preserving keys. */
|
|
52
|
+
export declare function flipCursor<T extends Record<string, unknown>>(pack: T): Promise<{
|
|
53
|
+
[K in keyof T]: T[K] extends string ? string : T[K] extends readonly string[] ? string[] : T[K];
|
|
54
|
+
}>;
|
|
55
|
+
//# sourceMappingURL=flip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flip.d.ts","sourceRoot":"","sources":["../../src/flip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAUH,uCAAuC;AACvC,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEvE,6DAA6D;AAC7D,wBAAsB,UAAU,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAErF,iFAAiF;AACjF,wBAAsB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,IAAI,EAAE,CAAC,GACN,OAAO,CAAC;KACR,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;CAChG,CAAC,CAAC"}
|