anime-cursor 0.1.0 → 0.1.2
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 +68 -42
- package/dist/anime-cursor.esm.js +6 -3
- package/dist/anime-cursor.umd.js +6 -3
- package/dist/anime-cursor.umd.min.js +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# AnimeCursor
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
-
<img src="title.gif" width="60%" alt="AnimeCursor"/>
|
|
4
|
+
<img src="https://cdn.jsdelivr.net/gh/shuninyu/anime-cursor@main/title.gif" width="60%" alt="AnimeCursor"/>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
[[简体中文]](#
|
|
7
|
+
[[简体中文]](#animecursorsc)
|
|
8
8
|
|
|
9
9
|
AnimeCursor is a lightweight animated cursor JS library that enables dynamic mouse pointers for websites.
|
|
10
10
|
|
|
@@ -21,18 +21,30 @@ AnimeCursor has no dependencies on any frameworks, making it suitable for person
|
|
|
21
21
|
* Prepare PNG sprite sheets in the correct format, and AnimeCursor will automatically generate cursor animations based on your settings
|
|
22
22
|
* Built with native JavaScript, no third-party dependencies
|
|
23
23
|
|
|
24
|
-
---
|
|
25
|
-
|
|
26
24
|
## 📦 Installation
|
|
27
25
|
|
|
26
|
+
### CDN
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<script src="https://cdn.jsdelivr.net/npm/anime-cursor/dist/anime-cursor.umd.min.js"></script>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### npm
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm i anime-cursor
|
|
36
|
+
```
|
|
37
|
+
```js
|
|
38
|
+
import AnimeCursor from 'anime-cursor';
|
|
39
|
+
new AnimeCursor({...});
|
|
40
|
+
```
|
|
41
|
+
|
|
28
42
|
### Local storage
|
|
29
43
|
|
|
30
44
|
```html
|
|
31
45
|
<script src="anime-cursor.umd.min.js"></script>
|
|
32
46
|
```
|
|
33
47
|
|
|
34
|
-
---
|
|
35
|
-
|
|
36
48
|
## 🚀 Basic Usage
|
|
37
49
|
|
|
38
50
|
Here is an example of how to use AnimeCursor:
|
|
@@ -41,28 +53,33 @@ Here is an example of how to use AnimeCursor:
|
|
|
41
53
|
<script>
|
|
42
54
|
new AnimeCursor({
|
|
43
55
|
cursors: {
|
|
56
|
+
// each type of cursor needs tags, size and image
|
|
44
57
|
default: {
|
|
45
|
-
tags: ['body'],
|
|
58
|
+
tags: ['body'], // default cursor recommended setting
|
|
46
59
|
size: [64,64],
|
|
47
|
-
image: './cursor_default.png'
|
|
48
|
-
frames: 1
|
|
60
|
+
image: './cursor_default.png' // static cursor only needs image
|
|
49
61
|
},
|
|
62
|
+
// png sprite animated cursor needs frames and duration
|
|
50
63
|
pointer: {
|
|
51
64
|
tags: ['a', 'button'],
|
|
52
65
|
size: [64,64],
|
|
53
66
|
image: './cursor_pointer.png',
|
|
54
67
|
frames: 3,
|
|
55
68
|
duration: 0.3,
|
|
56
|
-
pingpong: true,
|
|
57
|
-
offset: [10, 4]
|
|
69
|
+
pingpong: true, // enable pingpong loop
|
|
70
|
+
offset: [10, 4] // if the pointing spot is not at the top left of the image, set offset
|
|
71
|
+
},
|
|
72
|
+
// gif cursor doesn't needs frames and duration
|
|
73
|
+
text: {
|
|
74
|
+
tags: ['p', 'h1', 'h2', 'span'],
|
|
75
|
+
size: [32, 64],
|
|
76
|
+
image: './cursor_text.gif'
|
|
58
77
|
}
|
|
59
78
|
}
|
|
60
79
|
});
|
|
61
80
|
</script>
|
|
62
81
|
```
|
|
63
82
|
|
|
64
|
-
---
|
|
65
|
-
|
|
66
83
|
## ⚙️ Configuration Options
|
|
67
84
|
|
|
68
85
|
### `cursors` (Required)
|
|
@@ -79,11 +96,11 @@ For each key, the following parameters can be set. Missing required parameters w
|
|
|
79
96
|
|-|-|-|-|
|
|
80
97
|
| `tags` | `string[]` | ✅ | HTML tags that should use this cursor |
|
|
81
98
|
| `size` | `number` | ✅ | Cursor dimensions [width, height] in pixels |
|
|
82
|
-
| `offset` | `[number, number]` | | Cursor alignment offset [ x , y ] |
|
|
83
99
|
| `image` | `string` | ✅ | Image path (PNG / GIF) |
|
|
84
|
-
| `frames` | `number`
|
|
100
|
+
| `frames` | `number` || Number of frames for PNG sprites (set to `1` for static images) |
|
|
85
101
|
| `duration` | `number` | | Animation loop duration (seconds) ⚠️ PNG sprite animations *only* work when this parameter is set |
|
|
86
102
|
| `pingpong` | `boolean` | | Enable ping-pong (back-and-forth) looping (for PNG sprite animations only) |
|
|
103
|
+
| `offset` | `[number, number]` | | Cursor alignment offset [ x , y ] ⚠️ This parameter is not affected by `scale`|
|
|
87
104
|
| `scale` | `[number, number]` | | Cursor scale factor based on `size` [ x , y ] ⚠️ Only supported for GIF cursors. Do not set for PNG sprite cursors, as it will break the animation. |
|
|
88
105
|
| `pixel` | `boolean` | | Enable pixelated rendering |
|
|
89
106
|
| `zIndex` | `number` | | Cursor z-index layer (not recommended to modify) |
|
|
@@ -101,13 +118,11 @@ Enables animated cursors on mobile touch devices.
|
|
|
101
118
|
AnimeCursor automatically detects mobile touch devices (e.g., phones, tablets) and disables animated cursors on them by default.
|
|
102
119
|
If you want animated cursors to be displayed on these devices, add `enableTouch: true`.
|
|
103
120
|
|
|
104
|
-
---
|
|
105
|
-
|
|
106
121
|
## 📝 Notes
|
|
107
122
|
|
|
108
123
|
### 📁 Files
|
|
109
124
|
|
|
110
|
-
* For any PNG sprite animation cursor, its PNG sprite sheet should be arranged in a single horizontal row
|
|
125
|
+
* **For any PNG sprite animation cursor, its PNG sprite sheet should be arranged in a single horizontal row.** AnimeCursor will automatically generate the PNG sprite animation.
|
|
111
126
|
For example, if you set the `size` (width, height) for a `pointer` cursor to `[64px , 64px]` and `frames` to `3`, the prepared sprite sheet dimensions (width, height) should be: `[192px , 64px]`.
|
|
112
127
|
|
|
113
128
|
* For pixel art with a large number of frames, you can use the original image (whether GIF or PNG-sprite-sheet) to save storage space or bandwidth. Then, use the `scale` parameter in the configuration to resize the cursor and set `pixel` to `true` to avoid blurry scaling.
|
|
@@ -135,7 +150,7 @@ Therefore, to assign a specific animated cursor to a particular element, simply
|
|
|
135
150
|
Animation is generated **only when all of the following conditions are met**:
|
|
136
151
|
|
|
137
152
|
* The image is a PNG
|
|
138
|
-
* `frames > 1`
|
|
153
|
+
* `frames` is set and `frames > 1`
|
|
139
154
|
* `duration` is set
|
|
140
155
|
|
|
141
156
|
If `duration` is not set, the cursor will be treated as a **static cursor**, even if `frames > 1`.
|
|
@@ -145,8 +160,6 @@ If `duration` is not set, the cursor will be treated as a **static cursor**, eve
|
|
|
145
160
|
* GIFs do not use `frames`, `duration`, or `pingpong`
|
|
146
161
|
* Animation is controlled by the GIF file itself
|
|
147
162
|
|
|
148
|
-
---
|
|
149
|
-
|
|
150
163
|
## ❌ Error Handling
|
|
151
164
|
|
|
152
165
|
* Missing required configuration parameters will directly terminate initialization.
|
|
@@ -154,10 +167,10 @@ If `duration` is not set, the cursor will be treated as a **static cursor**, eve
|
|
|
154
167
|
* All errors are prefixed with `[AnimeCursor]` when logged to the console.
|
|
155
168
|
|
|
156
169
|
---
|
|
157
|
-
|
|
170
|
+
# AnimeCursor(SC)
|
|
158
171
|
|
|
159
172
|
<div align="center">
|
|
160
|
-
<img src="title.gif" width="60%" alt="AnimeCursor"/>
|
|
173
|
+
<img src="https://cdn.jsdelivr.net/gh/shuninyu/anime-cursor@main/title.gif" width="60%" alt="AnimeCursor"/>
|
|
161
174
|
</div>
|
|
162
175
|
|
|
163
176
|
AnimeCursor 是一个轻量级动画光标JS,能够让网站拥有动态的鼠标指针。
|
|
@@ -175,9 +188,23 @@ AnimeCursor 无需依赖任何框架,适合个人网站、创意作品集以
|
|
|
175
188
|
* 按照格式准备好 PNG 精灵图表,AnimeCursor 将基于你的设置自动生成光标动画
|
|
176
189
|
* 基于原生JavaScript,无任何第三方依赖
|
|
177
190
|
|
|
178
|
-
|
|
191
|
+
## 📦 部署方法
|
|
192
|
+
|
|
193
|
+
### CDN
|
|
179
194
|
|
|
180
|
-
|
|
195
|
+
```html
|
|
196
|
+
<script src="https://cdn.jsdelivr.net/npm/anime-cursor/dist/anime-cursor.umd.min.js"></script>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### npm
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm i anime-cursor
|
|
203
|
+
```
|
|
204
|
+
```js
|
|
205
|
+
import AnimeCursor from 'anime-cursor';
|
|
206
|
+
new AnimeCursor({...});
|
|
207
|
+
```
|
|
181
208
|
|
|
182
209
|
### 本地部署
|
|
183
210
|
|
|
@@ -185,8 +212,6 @@ AnimeCursor 无需依赖任何框架,适合个人网站、创意作品集以
|
|
|
185
212
|
<script src="anime-cursor.umd.min.js"></script>
|
|
186
213
|
```
|
|
187
214
|
|
|
188
|
-
---
|
|
189
|
-
|
|
190
215
|
## 🚀 基础用法
|
|
191
216
|
|
|
192
217
|
下面是一个 AnimeCursor 使用示例:
|
|
@@ -194,28 +219,33 @@ AnimeCursor 无需依赖任何框架,适合个人网站、创意作品集以
|
|
|
194
219
|
<script>
|
|
195
220
|
new AnimeCursor({
|
|
196
221
|
cursors: {
|
|
222
|
+
// 每种光标都需要 tags size 和 image
|
|
197
223
|
default: {
|
|
198
|
-
tags: ['body'],
|
|
224
|
+
tags: ['body'], // 默认光标推荐照此设置
|
|
199
225
|
size: [64,64],
|
|
200
|
-
image: './cursor_default.png'
|
|
201
|
-
frames: 1
|
|
226
|
+
image: './cursor_default.png' // 静态光标只需要图片链接
|
|
202
227
|
},
|
|
228
|
+
// png 精灵图动画光标还需要 frames 和 duration
|
|
203
229
|
pointer: {
|
|
204
230
|
tags: ['a', 'button'],
|
|
205
231
|
size: [64,64],
|
|
206
232
|
image: './cursor_pointer.png',
|
|
207
233
|
frames: 3,
|
|
208
234
|
duration: 0.3,
|
|
209
|
-
pingpong: true,
|
|
210
|
-
offset: [10, 4]
|
|
235
|
+
pingpong: true, // enable pingpong loop
|
|
236
|
+
offset: [10, 4] // if the pointing spot is not at the top left of the image, set offset
|
|
237
|
+
},
|
|
238
|
+
// gif 光标不需要 frames 或 duration
|
|
239
|
+
text: {
|
|
240
|
+
tags: ['p', 'h1', 'h2', 'span'],
|
|
241
|
+
size: [32, 64],
|
|
242
|
+
image: './cursor_text.gif'
|
|
211
243
|
}
|
|
212
244
|
}
|
|
213
245
|
});
|
|
214
246
|
</script>
|
|
215
247
|
```
|
|
216
248
|
|
|
217
|
-
---
|
|
218
|
-
|
|
219
249
|
## ⚙️ 配置项说明
|
|
220
250
|
|
|
221
251
|
### `cursors`(必填)
|
|
@@ -232,11 +262,11 @@ new AnimeCursor({
|
|
|
232
262
|
|-|-|-|-|
|
|
233
263
|
|`tags`|`string[]`|✅|使用该光标的 HTML 标签|
|
|
234
264
|
|`size`|`number`|✅|光标尺寸(宽高,像素)|
|
|
235
|
-
|`offset`|`[number, number]`||光标对齐偏移量 [ x , y ]|
|
|
236
265
|
|`image`|`string`|✅|图片路径(PNG / GIF)|
|
|
237
|
-
|`frames`|`number
|
|
266
|
+
|`frames`|`number`||PNG 帧数(静态图片请设置为 `1` )|
|
|
238
267
|
|`duration`|`number`||动画循环时长(秒)⚠️PNG精灵图动画只有设置该参数才会生效|
|
|
239
268
|
|`pingpong`|`boolean`||是否启用乒乓循环(仅PNG精灵图动画)|
|
|
269
|
+
|`offset`|`[number, number]`||光标对齐偏移量 [ x , y ]⚠️此参数不受 `scale` 影响|
|
|
240
270
|
|`scale`|`[number, number]`||基于size的光标缩放 [ x , y ]⚠️仅支持GIF光标,PNG精灵图动画光标请勿设置,否则会使动画失效|
|
|
241
271
|
|`pixel`|`boolean`||是否启用像素化渲染|
|
|
242
272
|
|`zIndex`|`number`||光标层级(不建议添加此项设置)|
|
|
@@ -254,13 +284,11 @@ debug覆盖会显示鼠标的真实位置以及当前光标类型,以帮助纠
|
|
|
254
284
|
AnimeCursor 会自动识别移动触屏设备(比如手机、平板电脑)并默认屏蔽这些设备上的动画光标。
|
|
255
285
|
如果你想在这些设备上显示动画光标,可以添加 `enableTouch: true` 。
|
|
256
286
|
|
|
257
|
-
---
|
|
258
|
-
|
|
259
287
|
## 📝 注意事项
|
|
260
288
|
|
|
261
289
|
### 📁 文件
|
|
262
290
|
|
|
263
|
-
*
|
|
291
|
+
* **对于任何 PNG 精灵图动画光标,它的 PNG 精灵图表都应该为单行横向布局,** AnimeCursor 会自动生成 PNG 精灵图动画。
|
|
264
292
|
例如,你为 `pointer` 光标设置的`size`(长,宽)为 `[64px , 64px]` ,帧数为 `3` ,那么你准备的精灵图表尺寸(长,宽)应该为: `[192px , 64px]` 。
|
|
265
293
|
|
|
266
294
|
* 对于帧数特别多的像素图,你可以使用原尺寸图片(无论是gif还是png精灵图表)以节省存储空间或带宽,并在参数中设置 `scale` 来缩放光标,并将 `pixel` 设置为 `true` 来避免缩放模糊。
|
|
@@ -288,7 +316,7 @@ AnimeCursor 会根据配置自动为页面元素添加 `data-cursor`:
|
|
|
288
316
|
只有在 **同时满足以下条件** 时,才会生成动画:
|
|
289
317
|
|
|
290
318
|
* 图片为 PNG
|
|
291
|
-
* `frames > 1`
|
|
319
|
+
* 设置了 `frames` 且 `frames > 1`
|
|
292
320
|
* 设置了 `duration`
|
|
293
321
|
|
|
294
322
|
如果未设置 `duration`,即使帧数大于 1,也会被视为**静态光标**。
|
|
@@ -298,8 +326,6 @@ AnimeCursor 会根据配置自动为页面元素添加 `data-cursor`:
|
|
|
298
326
|
* GIF 不使用 `frames`、`duration` 或 `pingpong`
|
|
299
327
|
* 动画由 GIF 自身控制
|
|
300
328
|
|
|
301
|
-
---
|
|
302
|
-
|
|
303
329
|
## ❌ 错误处理
|
|
304
330
|
|
|
305
331
|
* 缺少必填配置会直接终止初始化
|
package/dist/anime-cursor.esm.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// AnimeCursor by github@ShuninYu
|
|
2
|
+
// v0.1.2
|
|
3
|
+
|
|
1
4
|
class AnimeCursor {
|
|
2
5
|
|
|
3
6
|
constructor(options = {}) {
|
|
@@ -46,7 +49,7 @@ class AnimeCursor {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
for (const [name, cfg] of Object.entries(this.options.cursors)) {
|
|
49
|
-
const required = ['tags', 'size', 'image'
|
|
52
|
+
const required = ['tags', 'size', 'image'];
|
|
50
53
|
required.forEach(key => {
|
|
51
54
|
if (cfg[key] === undefined) {
|
|
52
55
|
console.error(`[AnimeCursor] 光标 "${name}" 缺少必填项:${key}`);
|
|
@@ -87,13 +90,13 @@ class AnimeCursor {
|
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
// ----------------------------
|
|
90
|
-
//
|
|
93
|
+
// 插入样式 CSS
|
|
91
94
|
// ----------------------------
|
|
92
95
|
_injectCSS() {
|
|
93
96
|
const style = document.createElement('style');
|
|
94
97
|
let css = '';
|
|
95
98
|
|
|
96
|
-
/*
|
|
99
|
+
/* 通用样式 */
|
|
97
100
|
css += `
|
|
98
101
|
* {
|
|
99
102
|
cursor: none !important;
|
package/dist/anime-cursor.umd.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.AnimeCursor = factory());
|
|
5
5
|
})(this, (function () { 'use strict';
|
|
6
6
|
|
|
7
|
+
// AnimeCursor by github@ShuninYu
|
|
8
|
+
// v0.1.2
|
|
9
|
+
|
|
7
10
|
class AnimeCursor {
|
|
8
11
|
|
|
9
12
|
constructor(options = {}) {
|
|
@@ -52,7 +55,7 @@
|
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
for (const [name, cfg] of Object.entries(this.options.cursors)) {
|
|
55
|
-
const required = ['tags', 'size', 'image'
|
|
58
|
+
const required = ['tags', 'size', 'image'];
|
|
56
59
|
required.forEach(key => {
|
|
57
60
|
if (cfg[key] === undefined) {
|
|
58
61
|
console.error(`[AnimeCursor] 光标 "${name}" 缺少必填项:${key}`);
|
|
@@ -93,13 +96,13 @@
|
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
// ----------------------------
|
|
96
|
-
//
|
|
99
|
+
// 插入样式 CSS
|
|
97
100
|
// ----------------------------
|
|
98
101
|
_injectCSS() {
|
|
99
102
|
const style = document.createElement('style');
|
|
100
103
|
let css = '';
|
|
101
104
|
|
|
102
|
-
/*
|
|
105
|
+
/* 通用样式 */
|
|
103
106
|
css += `
|
|
104
107
|
* {
|
|
105
108
|
cursor: none !important;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).AnimeCursor=n()}(this,function(){"use strict";return class{constructor(e={}){if(this.options={enableTouch:!1,debug:!1,...e},this.disabled=!1,!this.options.enableTouch&&!this.isMouseLikeDevice())return this.disabled=!0,void(this.options.debug&&console.warn("[AnimeCursor] Touch device detected, cursor disabled."));this.cursorEl=null,this.lastCursorType=null,this.debugEl=null,this._validateOptions(),this._injectHTML(),this._injectCSS(),this._bindElements(),this._bindMouse()}isMouseLikeDevice(){return window.matchMedia("(pointer: fine)").matches}destroy(){this.disabled}_validateOptions(){if(!this.options||!this.options.cursors)throw console.error("[AnimeCursor] 缺少 cursors 配置"),new Error("AnimeCursor init failed");for(const[e,n]of Object.entries(this.options.cursors)){if(["tags","size","image"
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).AnimeCursor=n()}(this,function(){"use strict";return class{constructor(e={}){if(this.options={enableTouch:!1,debug:!1,...e},this.disabled=!1,!this.options.enableTouch&&!this.isMouseLikeDevice())return this.disabled=!0,void(this.options.debug&&console.warn("[AnimeCursor] Touch device detected, cursor disabled."));this.cursorEl=null,this.lastCursorType=null,this.debugEl=null,this._validateOptions(),this._injectHTML(),this._injectCSS(),this._bindElements(),this._bindMouse()}isMouseLikeDevice(){return window.matchMedia("(pointer: fine)").matches}destroy(){this.disabled}_validateOptions(){if(!this.options||!this.options.cursors)throw console.error("[AnimeCursor] 缺少 cursors 配置"),new Error("AnimeCursor init failed");for(const[e,n]of Object.entries(this.options.cursors)){if(["tags","size","image"].forEach(t=>{if(void 0===n[t])throw console.error(`[AnimeCursor] 光标 "${e}" 缺少必填项:${t}`),new Error("AnimeCursor init failed")}),!Array.isArray(n.tags))throw console.error(`[AnimeCursor] 光标 "${e}" 的 tags 必须是数组`),new Error("AnimeCursor init failed");if(void 0!==n.duration&&"number"!=typeof n.duration)throw console.error(`[AnimeCursor] 光标 "${e}" 的 duration 必须是数字(秒)`),new Error("AnimeCursor init failed")}}_injectHTML(){const e=document.createElement("div");if(e.id="anime-cursor",this.options.debug){e.className="cursor-default cursor-debugmode";const n=document.createElement("div");n.className="anime-cursor-debug",document.body.appendChild(n),this.debugEl=n}else e.className="cursor-default";document.body.appendChild(e),this.cursorEl=e}_injectCSS(){const e=document.createElement("style");let n="";n+=`\n* {\ncursor: none !important;\n}\n#anime-cursor {\nposition: fixed;\ntop: 0;\nleft: 0;\npointer-events: none;\nbackground-repeat: no-repeat;\ntransform-origin: 0 0;\ntransform-style: preserve-3d;\nz-index: ${this._getMaxZIndex()};\n}\n.cursor-debugmode {\n border: 1px solid green;\n}\n.anime-cursor-debug {\n position: fixed;\n top: 0;\n left: 0;\n width: fit-content;\n height: fit-content;\n padding: 5px;\n font-size: 16px;\n text-wrap: nowrap;\n color: red;\n pointer-events: none;\n overflow: visible;\n z-index: 2147483647;\n}\n.anime-cursor-debug::before {\n position: absolute;\n content: "";\n top: 0;\n left: 0;\n width: 100vw;\n height: 1px;\n background-color: red;\n}\n.anime-cursor-debug::after {\n position: absolute;\n content: "";\n top: 0;\n left: 0;\n width: 1px;\n height: 100vh;\n background-color: red;\n}\n`;for(const[e,o]of Object.entries(this.options.cursors)){const r=`.cursor-${e}`,s=o.size,i=o.frames,d=o.image,u=o.offset,a=o.zIndex,c=o.scale,l=d.toLowerCase().endsWith(".gif");var t;t=o.pixel?"pixelated":"auto",n+=`\n${r} {\nwidth: ${s[0]}px;\nheight: ${s[1]}px;\nbackground-image: url("${d}");\nimage-rendering: ${t};\n${c||u?`transform: ${[c&&`scale(${c[0]}, ${c[1]})`,u&&`translate(-${u[0]}px, -${u[1]}px)`].filter(Boolean).join(" ")};`:""}\n \n${void 0!==a?`z-index:${a};`:""}\n}`;const p=o.duration;if(!l&&i>1&&"number"==typeof p){const t=`animecursor_${e}`;n+=`\n${r} {\nanimation: ${t} steps(${i}) ${p}s infinite ${o.pingpong?"alternate":""};\n}\n\n@keyframes ${t} {\nfrom { background-position: 0 0; }\nto { background-position: -${s[0]*i}px 0; }\n}\n`}}e.textContent=n,document.head.appendChild(e)}_bindElements(){for(const[e,n]of Object.entries(this.options.cursors))n.tags.forEach(n=>{const t=n.toUpperCase();document.querySelectorAll(t).forEach(n=>{n.dataset.cursor||(n.dataset.cursor=e)})})}_bindMouse(){document.addEventListener("mousemove",e=>{const n=e.clientX,t=e.clientY;this.cursorEl.style.left=n+"px",this.cursorEl.style.top=t+"px",this.debugEl&&(this.debugEl.style.left=n+"px",this.debugEl.style.top=t+"px");const o=document.elementFromPoint(n,t);if(!o)return;const r=o.dataset.cursor||"default";this.debugEl&&(this.debugEl.textContent=`(${n}px , ${t}px) ${r}`),r!==this.lastCursorType&&(this.debugEl?this.cursorEl.className=`cursor-${r} cursor-debugmode`:this.cursorEl.className=`cursor-${r}`,this.lastCursorType=r)})}_getMaxZIndex(){return 2147483646}}});
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anime-cursor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A lightweight JS for website animated cursors",
|
|
5
5
|
"main": "dist/anime-cursor.umd.js",
|
|
6
6
|
"module": "dist/anime-cursor.esm.js",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"cursor",
|
|
12
|
+
"animation",
|
|
13
|
+
"ui",
|
|
14
|
+
"javascript"
|
|
15
|
+
],
|
|
11
16
|
"scripts": {
|
|
12
17
|
"build": "rollup -c"
|
|
13
18
|
},
|