zoooom 1.0.0 → 1.0.1
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 +91 -164
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,212 +4,139 @@
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
*"Enhance."*
|
|
8
|
-
|
|
9
7
|
</div>
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
You know the scene. Someone squints at a blurry surveillance photo, says "enhance," and suddenly it's crystal clear at 4000x zoom. Every cop show. Every sci-fi movie. Every time, you think: that's not how images work.
|
|
9
|
+
Zero-dependency pan/zoom image viewer. 25KB.
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
`zoooom` is a zero-dependency pan/zoom engine for images. Mouse, touch, trackpad, keyboard, and — because why not — a virtual joystick. Drop it on any image and let people *enhance* to their heart's content.
|
|
18
|
-
|
|
19
|
-
## Install
|
|
11
|
+
I built this because I wanted to host high-resolution images without compression destroying them, and couldn't find a viewer that zoomed toward the cursor instead of the center.
|
|
20
12
|
|
|
21
13
|
```bash
|
|
22
14
|
npm install zoooom
|
|
23
15
|
```
|
|
24
16
|
|
|
25
|
-
## Quick Start
|
|
26
|
-
|
|
27
17
|
```js
|
|
28
18
|
import Zoooom from 'zoooom';
|
|
29
|
-
|
|
30
|
-
const viewer = new Zoooom('#photo', { src: 'evidence.jpg' });
|
|
31
|
-
viewer.enhance(); // you know you want to
|
|
19
|
+
new Zoooom('#container', { src: 'image.jpg' });
|
|
32
20
|
```
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
- Mouse drag to pan
|
|
36
|
-
- Scroll wheel / trackpad pinch to zoom (toward your cursor, not the center like an animal)
|
|
37
|
-
- Touch: single-finger pan, two-finger pinch
|
|
38
|
-
- Keyboard: arrows to pan, `+`/`-` to zoom, `R` to reset
|
|
39
|
-
- A loading spinner that fades out when the image is ready
|
|
40
|
-
- Momentum on release (that satisfying drift)
|
|
41
|
-
- Auto-calculated max zoom from the image's actual resolution
|
|
42
|
-
|
|
43
|
-
## Script Tag
|
|
44
|
-
|
|
45
|
-
No bundler? No problem.
|
|
46
|
-
|
|
47
|
-
```html
|
|
48
|
-
<div id="viewer" style="width: 100%; height: 100vh;"></div>
|
|
49
|
-
<script src="https://unpkg.com/zoooom/dist/zoooom.iife.global.js"></script>
|
|
50
|
-
<script>
|
|
51
|
-
new Zoooom('#viewer', { src: 'satellite.jpg' });
|
|
52
|
-
</script>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## What Makes This Different
|
|
22
|
+
---
|
|
56
23
|
|
|
57
|
-
|
|
58
|
-
1. jQuery plugins from 2014 that zoom to center (not cursor position)
|
|
59
|
-
2. React/Vue wrappers that bring 200KB of framework along
|
|
60
|
-
3. Overkill map engines that want tile servers
|
|
24
|
+
## What's different
|
|
61
25
|
|
|
62
|
-
|
|
26
|
+
- Zoom targets the cursor, not the image center
|
|
27
|
+
- Trackpad vs mouse wheel detection (continuous vs discrete zoom)
|
|
28
|
+
- Pinch center tracking updates each frame
|
|
29
|
+
- Max zoom auto-calculated from the image's native resolution
|
|
30
|
+
- Momentum on pan release
|
|
31
|
+
- No framework, no build step required
|
|
63
32
|
|
|
64
|
-
|
|
33
|
+
---
|
|
65
34
|
|
|
66
|
-
|
|
35
|
+
## Input
|
|
36
|
+
|
|
37
|
+
| Method | Action |
|
|
38
|
+
|--------|--------|
|
|
39
|
+
| Mouse drag | Pan |
|
|
40
|
+
| Scroll wheel | Zoom toward cursor |
|
|
41
|
+
| Trackpad | Continuous zoom toward cursor |
|
|
42
|
+
| Ctrl+wheel | Pinch gesture (Windows/Linux) |
|
|
43
|
+
| Safari gestures | Native gesture zoom |
|
|
44
|
+
| Single touch | Pan |
|
|
45
|
+
| Two-finger pinch | Zoom with center tracking |
|
|
46
|
+
| Arrow keys | Pan with momentum |
|
|
47
|
+
| +/- keys | Zoom |
|
|
48
|
+
| R key | Reset |
|
|
49
|
+
| Joystick (plugin) | 8-direction pan + zoom |
|
|
67
50
|
|
|
68
|
-
##
|
|
51
|
+
## API
|
|
69
52
|
|
|
70
53
|
```js
|
|
71
|
-
new Zoooom(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
54
|
+
const viewer = new Zoooom(container, options);
|
|
55
|
+
|
|
56
|
+
viewer.zoomIn()
|
|
57
|
+
viewer.zoomOut()
|
|
58
|
+
viewer.enhance() // alias: zoomIn
|
|
59
|
+
viewer.zoomTo(scale)
|
|
60
|
+
viewer.zoomToPoint(scale, x, y)
|
|
61
|
+
viewer.panTo(x, y)
|
|
62
|
+
viewer.panBy(dx, dy)
|
|
63
|
+
viewer.center()
|
|
64
|
+
viewer.reset()
|
|
65
|
+
viewer.load(src, alt?)
|
|
66
|
+
viewer.destroy()
|
|
67
|
+
|
|
68
|
+
viewer.scale // current zoom
|
|
69
|
+
viewer.translateX // current X
|
|
70
|
+
viewer.translateY // current Y
|
|
71
|
+
viewer.isLoaded
|
|
72
|
+
|
|
73
|
+
viewer.on('load' | 'error' | 'zoom' | 'pan' | 'reset' | 'destroy', fn)
|
|
74
|
+
viewer.off(event, fn)
|
|
90
75
|
```
|
|
91
76
|
|
|
92
|
-
##
|
|
77
|
+
## Options
|
|
93
78
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
viewer.isLoaded; // whether image is ready
|
|
114
|
-
|
|
115
|
-
// Events
|
|
116
|
-
viewer.on('load', () => {});
|
|
117
|
-
viewer.on('zoom', (scale) => {});
|
|
118
|
-
viewer.on('pan', (x, y) => {});
|
|
119
|
-
viewer.on('reset', () => {});
|
|
120
|
-
viewer.on('destroy', () => {});
|
|
121
|
-
viewer.off('zoom', handler);
|
|
122
|
-
```
|
|
79
|
+
| Option | Default | |
|
|
80
|
+
|--------|---------|---|
|
|
81
|
+
| `src` | — | Image URL |
|
|
82
|
+
| `alt` | `'Image'` | Alt text |
|
|
83
|
+
| `minScale` | `0.8` | Min zoom |
|
|
84
|
+
| `maxScale` | `'auto'` | From native dimensions |
|
|
85
|
+
| `zoomFactor` | `1.5` | Per-step multiplier |
|
|
86
|
+
| `velocityDamping` | `0.85` | Momentum friction |
|
|
87
|
+
| `trackpadSensitivity` | `0.002` | Continuous zoom tuning |
|
|
88
|
+
| `mouse` | `true` | |
|
|
89
|
+
| `touch` | `true` | |
|
|
90
|
+
| `wheel` | `true` | |
|
|
91
|
+
| `keyboard` | `true` | |
|
|
92
|
+
| `loading` | `true` | Loading spinner |
|
|
93
|
+
| `injectStyles` | `true` | Auto-inject CSS |
|
|
94
|
+
| `respectReducedMotion` | `true` | Honor motion preference |
|
|
95
|
+
| `onLoad` | — | |
|
|
96
|
+
| `onZoom` | — | |
|
|
97
|
+
| `onPan` | — | |
|
|
123
98
|
|
|
124
99
|
## Joystick Plugin
|
|
125
100
|
|
|
126
|
-
For when arrow keys aren't enough and you want that drone-camera-operator feeling:
|
|
127
|
-
|
|
128
101
|
```js
|
|
129
|
-
import Zoooom from 'zoooom';
|
|
130
102
|
import { ZoooomJoystick } from 'zoooom/joystick';
|
|
131
|
-
|
|
132
|
-
const viewer = new Zoooom('#container', { src: 'map.jpg' });
|
|
133
|
-
const joystick = new ZoooomJoystick(viewer);
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
The joystick gives you:
|
|
137
|
-
- A virtual disc for 8-directional panning (hover or drag)
|
|
138
|
-
- Split-circle center for zoom in/out
|
|
139
|
-
- Dwell-to-activate (hover 100ms, then move to pan)
|
|
140
|
-
- Direction arrows showing which way you're going
|
|
141
|
-
- Screen reader ARIA support (announces direction + speed)
|
|
142
|
-
- Compass toggle button to show/hide
|
|
143
|
-
|
|
144
|
-
```js
|
|
145
|
-
// Joystick options
|
|
146
|
-
new ZoooomJoystick(viewer, {
|
|
147
|
-
radius: 60, // panning zone radius (px)
|
|
148
|
-
deadzone: 0.1, // center deadzone (fraction)
|
|
149
|
-
maxSpeed: 10, // max pan speed (px/frame)
|
|
150
|
-
showToggle: true, // show the toggle button
|
|
151
|
-
dwellTimeout: 100, // ms before dwell activates
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
joystick.show(); // show programmatically
|
|
155
|
-
joystick.hide(); // hide
|
|
156
|
-
joystick.destroy(); // remove from DOM
|
|
103
|
+
new ZoooomJoystick(viewer, { radius: 60, deadzone: 0.1, maxSpeed: 10 });
|
|
157
104
|
```
|
|
158
105
|
|
|
159
|
-
|
|
106
|
+
Full bundle: `unpkg.com/zoooom/dist/zoooom-full.iife.global.js`
|
|
160
107
|
|
|
161
|
-
|
|
162
|
-
<script src="https://unpkg.com/zoooom/dist/zoooom-full.iife.global.js"></script>
|
|
163
|
-
<script>
|
|
164
|
-
const viewer = new Zoooom('#container', { src: 'photo.jpg' });
|
|
165
|
-
const joystick = new ZoooomJoystick(viewer);
|
|
166
|
-
</script>
|
|
167
|
-
```
|
|
108
|
+
## Accessibility
|
|
168
109
|
|
|
169
|
-
|
|
110
|
+
- `prefers-reduced-motion` honored (no transitions, no momentum)
|
|
111
|
+
- Full keyboard navigation
|
|
112
|
+
- ARIA on all controls
|
|
113
|
+
- 44px touch targets
|
|
114
|
+
- Joystick announces direction + speed to screen readers
|
|
170
115
|
|
|
171
|
-
|
|
116
|
+
## CSS Variables
|
|
172
117
|
|
|
173
118
|
```css
|
|
174
119
|
[data-zoooom] {
|
|
175
|
-
--zoooom-bg: #
|
|
176
|
-
--zoooom-spinner-color: #
|
|
177
|
-
--zoooom-spinner-track: rgba(255, 255, 255, 0.
|
|
178
|
-
--zoooom-spinner-size:
|
|
179
|
-
--zoooom-loading-bg: rgba(0, 0, 0, 0.
|
|
180
|
-
--zoooom-
|
|
181
|
-
--zoooom-cursor:
|
|
182
|
-
--zoooom-cursor-active: move;
|
|
120
|
+
--zoooom-bg: #000;
|
|
121
|
+
--zoooom-spinner-color: #2196f3;
|
|
122
|
+
--zoooom-spinner-track: rgba(255, 255, 255, 0.3);
|
|
123
|
+
--zoooom-spinner-size: 40px;
|
|
124
|
+
--zoooom-loading-bg: rgba(0, 0, 0, 0.85);
|
|
125
|
+
--zoooom-cursor: grab;
|
|
126
|
+
--zoooom-cursor-active: grabbing;
|
|
183
127
|
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Or disable auto-injection and bring your own:
|
|
187
128
|
|
|
188
|
-
|
|
189
|
-
new Zoooom('#el', { src: 'img.jpg', injectStyles: false });
|
|
129
|
+
/* Or: injectStyles: false + your own stylesheet */
|
|
190
130
|
```
|
|
191
131
|
|
|
132
|
+
## Script Tag
|
|
133
|
+
|
|
192
134
|
```html
|
|
193
|
-
<
|
|
135
|
+
<div id="v" style="width:100%;height:100vh"></div>
|
|
136
|
+
<script src="https://unpkg.com/zoooom/dist/zoooom.iife.global.js"></script>
|
|
137
|
+
<script>new Zoooom('#v', { src: 'photo.jpg' });</script>
|
|
194
138
|
```
|
|
195
139
|
|
|
196
|
-
## Accessibility
|
|
197
|
-
|
|
198
|
-
- Full keyboard navigation (arrows, +/-, R, Tab)
|
|
199
|
-
- `prefers-reduced-motion` respected — no transitions, no momentum, instant show
|
|
200
|
-
- ARIA labels on all interactive elements
|
|
201
|
-
- Joystick announces direction and speed to screen readers
|
|
202
|
-
- Container is focusable and has `role="application"` with usage hints
|
|
203
|
-
- Minimum 44px touch targets
|
|
204
|
-
|
|
205
|
-
## Browser Support
|
|
206
|
-
|
|
207
|
-
ES2020+: Chrome 80+, Firefox 74+, Safari 14+, Edge 80+.
|
|
208
|
-
|
|
209
|
-
## The Name
|
|
210
|
-
|
|
211
|
-
Four o's because three felt restrained and five was too many.
|
|
212
|
-
|
|
213
140
|
## License
|
|
214
141
|
|
|
215
142
|
MIT
|