@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-03-27T19:05:49Z
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.07 KB
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 { IID } from "@thi.ng/api";
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: UIEvent;
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 extends IID<string> {
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: getPos(events[0], bounds, opts.local, opts.scale),
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": "4.1.48",
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.5",
42
- "@thi.ng/checks": "^3.3.11",
43
- "@thi.ng/math": "^5.4.6",
44
- "@thi.ng/rstream": "^7.2.46",
45
- "@thi.ng/transducers": "^8.4.1"
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.14",
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.2"
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": "83b15b34326d480cbca0472b20390d4d3bbb792a\n"
98
+ "gitHead": "abcedd9e4e06a4b631f363610eec572f79b571c1\n"
99
99
  }