@thi.ng/rstream-gestures 4.1.48 → 5.0.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/CHANGELOG.md +15 -1
- package/README.md +36 -1
- package/api.d.ts +12 -6
- package/gesture-stream.js +31 -4
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-
|
|
3
|
+
- **Last updated**: 2023-04-08T11:09:50Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,20 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
# [5.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream-gestures@5.0.0) (2023-04-08)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- support zoom reset via subscription ([03b1621](https://github.com/thi-ng/umbrella/commit/03b1621))
|
|
17
|
+
- BREAKING CHANGE: Original DOM event **might** not anymore be present in all cases
|
|
18
|
+
- update GestureStreamOpts.zoom to accept subscription
|
|
19
|
+
- update gestureStream() to support resetting of zoom value via subscription
|
|
20
|
+
- update docs
|
|
21
|
+
|
|
22
|
+
#### ♻️ Refactoring
|
|
23
|
+
|
|
24
|
+
- update stream ID handling ([2c9fa02](https://github.com/thi-ng/umbrella/commit/2c9fa02))
|
|
25
|
+
|
|
12
26
|
## [4.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rstream-gestures@4.1.0) (2021-11-17)
|
|
13
27
|
|
|
14
28
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ This project is part of the
|
|
|
12
12
|
- [About](#about)
|
|
13
13
|
- [Status](#status)
|
|
14
14
|
- [Breaking changes](#breaking-changes)
|
|
15
|
+
- [v3.0.0](#v300)
|
|
16
|
+
- [v2.0.0](#v200)
|
|
15
17
|
- [Related packages](#related-packages)
|
|
16
18
|
- [Installation](#installation)
|
|
17
19
|
- [Dependencies](#dependencies)
|
|
@@ -21,6 +23,7 @@ This project is part of the
|
|
|
21
23
|
- [GestureEvent](#gestureevent)
|
|
22
24
|
- [GestureStreamOpts](#gesturestreamopts)
|
|
23
25
|
- [Basic usage](#basic-usage)
|
|
26
|
+
- [Resettable zoom](#resettable-zoom)
|
|
24
27
|
- [Authors](#authors)
|
|
25
28
|
- [License](#license)
|
|
26
29
|
|
|
@@ -36,6 +39,17 @@ Unified mouse, mouse wheel & multi-touch event stream abstraction. This is a sup
|
|
|
36
39
|
|
|
37
40
|
### Breaking changes
|
|
38
41
|
|
|
42
|
+
#### v3.0.0
|
|
43
|
+
|
|
44
|
+
The `gestureStream()` now supports external zoom control/resetting via providing
|
|
45
|
+
a subscription as `zoom` option. That itself isn't a breaking change, however a
|
|
46
|
+
result of this is that the `GestureEvent`s emitted by the stream do not *always*
|
|
47
|
+
contain the original [DOM
|
|
48
|
+
event](https://docs.thi.ng/umbrella/rstream-gestures/interfaces/GestureEvent.html#event)
|
|
49
|
+
anymore (i.e. not in the case when the zoom factor is being reset via attached
|
|
50
|
+
subscription).
|
|
51
|
+
|
|
52
|
+
#### v2.0.0
|
|
39
53
|
Multi-touch support has been added in v2.0.0, resulting in a complete
|
|
40
54
|
rewrite of `gestureStream()` and new event data formats.
|
|
41
55
|
|
|
@@ -64,7 +78,7 @@ For Node.js REPL:
|
|
|
64
78
|
const rstreamGestures = await import("@thi.ng/rstream-gestures");
|
|
65
79
|
```
|
|
66
80
|
|
|
67
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
81
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.20 KB
|
|
68
82
|
|
|
69
83
|
## Dependencies
|
|
70
84
|
|
|
@@ -97,6 +111,7 @@ A selection:
|
|
|
97
111
|
| | Basic rstream-gestures multi-touch demo | [Demo](https://demo.thi.ng/umbrella/multitouch/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/multitouch) |
|
|
98
112
|
| | Minimal rstream dataflow graph | [Demo](https://demo.thi.ng/umbrella/rstream-dataflow/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rstream-dataflow) |
|
|
99
113
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/shader-graph.jpg" width="240"/> | Minimal shader graph developed during livestream #2 | [Demo](https://demo.thi.ng/umbrella/shader-graph/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/shader-graph) |
|
|
114
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/trace-bitmap.jpg" width="240"/> | Multi-layer vectorization & dithering of bitmap images | [Demo](https://demo.thi.ng/umbrella/trace-bitmap/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/trace-bitmap) |
|
|
100
115
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/webgl-channel-mixer.jpg" width="240"/> | rdom & WebGL-based image channel editor | [Demo](https://demo.thi.ng/umbrella/webgl-channel-mixer/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/webgl-channel-mixer) |
|
|
101
116
|
|
|
102
117
|
## API
|
|
@@ -187,6 +202,26 @@ gestures.subscribe(
|
|
|
187
202
|
);
|
|
188
203
|
```
|
|
189
204
|
|
|
205
|
+
### Resettable zoom
|
|
206
|
+
|
|
207
|
+
For some applications (e.g. graphical editors), it can be helpful to reset the
|
|
208
|
+
zoom value. This can be done by supplying a stream/subscription as part of the
|
|
209
|
+
config options:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
// create stream for initial zoom value & for resetting
|
|
213
|
+
const zoomReset = reactive(1);
|
|
214
|
+
|
|
215
|
+
// create gesture stream w/ zoom subscription
|
|
216
|
+
const gestures = gestureStream(document.body, {
|
|
217
|
+
smooth: 0.01,
|
|
218
|
+
zoom: zoomReset
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// ... then to reset the zoom at some point (e.g to zoom=2)
|
|
222
|
+
zoomReset.next(2);
|
|
223
|
+
```
|
|
224
|
+
|
|
190
225
|
## Authors
|
|
191
226
|
|
|
192
227
|
- [Karsten Schmidt](https://thi.ng) (Main author)
|
package/api.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { StreamMerge } from "@thi.ng/rstream";
|
|
1
|
+
import type { ISubscription, StreamMerge } from "@thi.ng/rstream";
|
|
3
2
|
export type GestureStream = StreamMerge<UIEvent, GestureEvent>;
|
|
4
3
|
export type UIEvent = MouseEvent | TouchEvent | WheelEvent;
|
|
5
4
|
export type UIEventID = "mousedown" | "mousemove" | "mouseup" | "touchstart" | "touchmove" | "touchend" | "touchcancel" | "wheel";
|
|
@@ -35,9 +34,11 @@ export interface GestureEvent {
|
|
|
35
34
|
*/
|
|
36
35
|
type: GestureType;
|
|
37
36
|
/**
|
|
38
|
-
* Original DOM event.
|
|
37
|
+
* Original DOM event. This will **NOT** be present for `zoom` events
|
|
38
|
+
* originating from a value change of an attached
|
|
39
|
+
* {@link GestureStreamOpts.zoom} subscription.
|
|
39
40
|
*/
|
|
40
|
-
event
|
|
41
|
+
event?: UIEvent;
|
|
41
42
|
/**
|
|
42
43
|
* Event position (as per {@link GestureStreamOpts.local} &
|
|
43
44
|
* {@link GestureStreamOpts.scale})
|
|
@@ -65,7 +66,12 @@ export interface GestureEvent {
|
|
|
65
66
|
*/
|
|
66
67
|
isTouch: boolean;
|
|
67
68
|
}
|
|
68
|
-
export interface GestureStreamOpts
|
|
69
|
+
export interface GestureStreamOpts {
|
|
70
|
+
/**
|
|
71
|
+
* Stream ID associate with the gesture stream. If omitted, an autogenerated
|
|
72
|
+
* ID will be assigned.
|
|
73
|
+
*/
|
|
74
|
+
id: string;
|
|
69
75
|
/**
|
|
70
76
|
* Event listener options (see standard `addEventListener`).
|
|
71
77
|
* Default: false
|
|
@@ -93,7 +99,7 @@ export interface GestureStreamOpts extends IID<string> {
|
|
|
93
99
|
/**
|
|
94
100
|
* Initial zoom value. Default: 1
|
|
95
101
|
*/
|
|
96
|
-
zoom: number
|
|
102
|
+
zoom: number | ISubscription<any, number>;
|
|
97
103
|
/**
|
|
98
104
|
* If true, the produced `zoom` values are considered absolute and
|
|
99
105
|
* will be constrained to the `minZoom .. maxZoom` interval. If
|
package/gesture-stream.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isBoolean } from "@thi.ng/checks/is-boolean";
|
|
2
|
+
import { isNumber } from "@thi.ng/checks/is-number";
|
|
2
3
|
import { clamp } from "@thi.ng/math/interval";
|
|
3
4
|
import { fromDOMEvent } from "@thi.ng/rstream/event";
|
|
5
|
+
import { __nextID } from "@thi.ng/rstream/idgen";
|
|
4
6
|
import { merge } from "@thi.ng/rstream/merge";
|
|
5
7
|
import { map } from "@thi.ng/transducers/map";
|
|
6
8
|
const START_EVENTS = new Set([
|
|
@@ -48,7 +50,6 @@ const EVENT_GESTURETYPES = {
|
|
|
48
50
|
*/
|
|
49
51
|
export const gestureStream = (el, _opts) => {
|
|
50
52
|
const opts = {
|
|
51
|
-
id: "gestures",
|
|
52
53
|
zoom: 1,
|
|
53
54
|
absZoom: true,
|
|
54
55
|
minZoom: 0.25,
|
|
@@ -62,10 +63,12 @@ export const gestureStream = (el, _opts) => {
|
|
|
62
63
|
scale: false,
|
|
63
64
|
..._opts,
|
|
64
65
|
};
|
|
66
|
+
opts.id = opts.id || `gestures-${__nextID()}`;
|
|
65
67
|
const active = [];
|
|
66
|
-
let zoom = clamp(opts.zoom, opts.minZoom, opts.maxZoom);
|
|
68
|
+
let zoom = clamp(isNumber(opts.zoom) ? opts.zoom : opts.zoom.deref() || 1, opts.minZoom, opts.maxZoom);
|
|
67
69
|
let zoomDelta = 0;
|
|
68
70
|
let numTouches = 0;
|
|
71
|
+
let lastPos = [0, 0];
|
|
69
72
|
let tempStreams;
|
|
70
73
|
const isBody = el === document.body;
|
|
71
74
|
const tempEvents = [
|
|
@@ -131,10 +134,28 @@ export const gestureStream = (el, _opts) => {
|
|
|
131
134
|
zoomDelta = zdelta;
|
|
132
135
|
};
|
|
133
136
|
const stream = merge({
|
|
137
|
+
id: opts.id,
|
|
134
138
|
src: BASE_EVENTS.map((id) => eventSource(el, id, opts)),
|
|
135
139
|
xform: map((e) => {
|
|
136
|
-
opts.preventDefault && e.preventDefault();
|
|
137
140
|
const etype = e.type;
|
|
141
|
+
if (etype === "$zoom") {
|
|
142
|
+
zoomDelta = e.value - zoom;
|
|
143
|
+
if (opts.absZoom) {
|
|
144
|
+
zoom = clamp(zoom + zoomDelta, opts.minZoom, opts.maxZoom);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
zoom = zoomDelta;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
pos: lastPos.slice(),
|
|
151
|
+
buttons: 0,
|
|
152
|
+
type: "zoom",
|
|
153
|
+
active,
|
|
154
|
+
zoom,
|
|
155
|
+
zoomDelta,
|
|
156
|
+
isTouch: false,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
138
159
|
const type = classifyEventType(etype, !!tempStreams);
|
|
139
160
|
let isTouch = !!e.touches;
|
|
140
161
|
let events = isTouch
|
|
@@ -150,9 +171,11 @@ export const gestureStream = (el, _opts) => {
|
|
|
150
171
|
else if (type === "zoom") {
|
|
151
172
|
updateZoom(e);
|
|
152
173
|
}
|
|
174
|
+
lastPos = getPos(events[0], bounds, opts.local, opts.scale);
|
|
175
|
+
opts.preventDefault && e.preventDefault();
|
|
153
176
|
return {
|
|
154
177
|
event: e,
|
|
155
|
-
pos:
|
|
178
|
+
pos: lastPos,
|
|
156
179
|
buttons: isTouch ? active.length : e.buttons,
|
|
157
180
|
type,
|
|
158
181
|
active,
|
|
@@ -162,6 +185,10 @@ export const gestureStream = (el, _opts) => {
|
|
|
162
185
|
};
|
|
163
186
|
}),
|
|
164
187
|
});
|
|
188
|
+
// attach zoom reset
|
|
189
|
+
if (!isNumber(opts.zoom)) {
|
|
190
|
+
stream.add(opts.zoom.map((x) => ({ type: "$zoom", value: x })));
|
|
191
|
+
}
|
|
165
192
|
return stream;
|
|
166
193
|
};
|
|
167
194
|
const eventSource = (el, type, opts, suffix = "") => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/rstream-gestures",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Unified mouse, mouse wheel & multi-touch event stream abstraction",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
"test": "testament test"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@thi.ng/api": "^8.7.
|
|
42
|
-
"@thi.ng/checks": "^3.3.
|
|
43
|
-
"@thi.ng/math": "^5.4.
|
|
44
|
-
"@thi.ng/rstream": "^
|
|
45
|
-
"@thi.ng/transducers": "^8.4.
|
|
41
|
+
"@thi.ng/api": "^8.7.6",
|
|
42
|
+
"@thi.ng/checks": "^3.3.12",
|
|
43
|
+
"@thi.ng/math": "^5.4.7",
|
|
44
|
+
"@thi.ng/rstream": "^8.0.0",
|
|
45
|
+
"@thi.ng/transducers": "^8.4.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@microsoft/api-extractor": "^7.34.4",
|
|
49
|
-
"@thi.ng/testament": "^0.3.
|
|
49
|
+
"@thi.ng/testament": "^0.3.15",
|
|
50
50
|
"rimraf": "^4.4.1",
|
|
51
51
|
"tools": "^0.0.1",
|
|
52
52
|
"typedoc": "^0.23.28",
|
|
53
|
-
"typescript": "^5.0.
|
|
53
|
+
"typescript": "^5.0.4"
|
|
54
54
|
},
|
|
55
55
|
"keywords": [
|
|
56
56
|
"animation",
|
|
@@ -95,5 +95,5 @@
|
|
|
95
95
|
],
|
|
96
96
|
"year": 2018
|
|
97
97
|
},
|
|
98
|
-
"gitHead": "
|
|
98
|
+
"gitHead": "abcedd9e4e06a4b631f363610eec572f79b571c1\n"
|
|
99
99
|
}
|