@rcarls/rc-virtual-canvas 0.5.0 → 0.7.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 +27 -0
- package/README.md +54 -47
- package/dist/custom-elements.json +50 -20
- package/dist/{rc-virtual-canvas-BSpF0tcY.js → rc-virtual-canvas-DIy-ABTk.js} +72 -130
- package/dist/rc-virtual-canvas-DIy-ABTk.js.map +1 -0
- package/dist/rc-virtual-canvas-define.js +1 -1
- package/dist/rc-virtual-canvas-define.js.map +1 -1
- package/dist/rc-virtual-canvas.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/rc-virtual-canvas.d.ts +28 -25
- package/package.json +1 -1
- package/dist/rc-virtual-canvas-BSpF0tcY.js.map +0 -1
- package/dist/types/rc-virtual-canvas.test.d.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @rcarls/rc-virtual-canvas
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
|
|
8
|
+
and light-DOM structural styles through Lightning CSS, removing comments and
|
|
9
|
+
whitespace while keeping source maps that resolve to each template. Rendered
|
|
10
|
+
styles are unchanged.
|
|
11
|
+
|
|
12
|
+
`@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
|
|
13
|
+
string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
|
|
14
|
+
depend on `@rcarls/rc-common` for it.
|
|
15
|
+
|
|
16
|
+
- 1740c28: Map browser client coordinates to content CSS pixels independently of the canvas
|
|
17
|
+
backing-store resolution. Pointer coordinates no longer double under a 2x
|
|
18
|
+
backing store, and CSS zoom no longer changes the meaning of content positions.
|
|
19
|
+
`canvasScaleX` and `canvasScaleY` now report backing-store pixels per local CSS
|
|
20
|
+
pixel, so they remain accurate when an ancestor applies CSS zoom.
|
|
21
|
+
|
|
22
|
+
## 0.6.0
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- 57370e4: Align component metadata, aggregate framework typings, development-time native-child
|
|
27
|
+
validation, controlled menu state, package declarations, and public documentation before the
|
|
28
|
+
next release.
|
|
29
|
+
|
|
3
30
|
## 0.5.0
|
|
4
31
|
|
|
5
32
|
## 0.4.2
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# `@rcarls/rc-virtual-canvas`
|
|
2
2
|
|
|
3
|
+
<!-- markdownlint-disable MD013 -->
|
|
4
|
+
|
|
3
5
|
Scrollable virtual canvas for rendering large coordinate-space content.
|
|
4
6
|
|
|
5
7
|
Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas](https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas).
|
|
@@ -19,8 +21,8 @@ npm install @rcarls/rc-virtual-canvas
|
|
|
19
21
|
## Import
|
|
20
22
|
|
|
21
23
|
```js
|
|
22
|
-
import '@rcarls/rc-virtual-canvas';
|
|
23
|
-
import { RCVirtualCanvas } from '@rcarls/rc-virtual-canvas';
|
|
24
|
+
import '@rcarls/rc-virtual-canvas'; // side-effect: registers <rc-virtual-canvas>
|
|
25
|
+
import { RCVirtualCanvas } from '@rcarls/rc-virtual-canvas'; // named class export
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
---
|
|
@@ -56,7 +58,7 @@ total size of your virtual content. On each `rc-virtual-canvas-render` event, us
|
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
The canvas element should match the component's rendered size (set via CSS). The virtual
|
|
59
|
-
content is larger
|
|
61
|
+
content is larger; scrolling is handled by an absolutely positioned transparent `<div>`
|
|
60
62
|
that triggers native scroll events.
|
|
61
63
|
|
|
62
64
|
---
|
|
@@ -65,65 +67,65 @@ that triggers native scroll events.
|
|
|
65
67
|
|
|
66
68
|
### Properties / attributes
|
|
67
69
|
|
|
68
|
-
| Property
|
|
69
|
-
|
|
70
|
-
| `contentWidth`
|
|
71
|
-
| `contentHeight`
|
|
72
|
-
| `autoResizeCanvas` | `auto-resize-canvas` | `boolean`
|
|
73
|
-
| `renderMode`
|
|
74
|
-
| `imageRendering`
|
|
70
|
+
| Property | Attribute | Type | Default | Description |
|
|
71
|
+
| ------------------ | -------------------- | ----------------------------------------------- | -------------- | ----------------------------------------------------------------------- |
|
|
72
|
+
| `contentWidth` | `content-width` | `number` | `0` | Total pixel width of the virtual content |
|
|
73
|
+
| `contentHeight` | `content-height` | `number` | `0` | Total pixel height of the virtual content |
|
|
74
|
+
| `autoResizeCanvas` | `auto-resize-canvas` | `boolean` | `true` | Keeps the slotted canvas backing store aligned to the measured viewport |
|
|
75
|
+
| `renderMode` | `render-mode` | `'continuous' \| 'viewport-change' \| 'manual'` | `'continuous'` | Controls when render events are dispatched |
|
|
76
|
+
| `imageRendering` | `image-rendering` | `'auto' \| 'crisp-edges' \| 'pixelated'` | `'auto'` | Convenience value applied to the slotted canvas via `image-rendering` |
|
|
75
77
|
|
|
76
78
|
### Read-only properties
|
|
77
79
|
|
|
78
|
-
| Property
|
|
79
|
-
|
|
80
|
-
| `canvasScaleX` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the x-axis
|
|
81
|
-
| `canvasScaleY` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the y-axis
|
|
80
|
+
| Property | Type | Description |
|
|
81
|
+
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
82
|
+
| `canvasScaleX` | `number` | Ratio of canvas backing-store pixels to local CSS pixels along the x-axis; CSS zoom can make it differ from `devicePixelRatio` |
|
|
83
|
+
| `canvasScaleY` | `number` | Ratio of canvas backing-store pixels to CSS pixels along the y-axis |
|
|
82
84
|
|
|
83
85
|
### Methods
|
|
84
86
|
|
|
85
|
-
| Method
|
|
86
|
-
|
|
87
|
-
| `getViewRect()`
|
|
88
|
-
| `scrollToContent(x, y, options?)`
|
|
89
|
-
| `centerOnContent(x, y, options?)`
|
|
90
|
-
| `clientToContent(clientX, clientY)` | Converts browser client coordinates to content coordinates
|
|
91
|
-
| `contentToClient(x, y)`
|
|
92
|
-
| `requestRender(reason?)`
|
|
87
|
+
| Method | Description |
|
|
88
|
+
| ----------------------------------- | ------------------------------------------------------------------------ |
|
|
89
|
+
| `getViewRect()` | Returns an immutable snapshot of the current viewport rectangle |
|
|
90
|
+
| `scrollToContent(x, y, options?)` | Scrolls so the content coordinate is at the viewport origin |
|
|
91
|
+
| `centerOnContent(x, y, options?)` | Scrolls so the content coordinate is centered in the viewport |
|
|
92
|
+
| `clientToContent(clientX, clientY)` | Converts browser client coordinates to content coordinates in CSS pixels |
|
|
93
|
+
| `contentToClient(x, y)` | Converts content coordinates back to browser client coordinates |
|
|
94
|
+
| `requestRender(reason?)` | Queues a render event; required when `renderMode` is `'manual'` |
|
|
93
95
|
|
|
94
96
|
### CSS custom properties
|
|
95
97
|
|
|
96
|
-
| Property
|
|
97
|
-
|
|
98
|
-
| `--rc-virtual-canvas-image-rendering` | `auto`
|
|
98
|
+
| Property | Default | Description |
|
|
99
|
+
| ------------------------------------- | ------- | -------------------------------------------------------------------- |
|
|
100
|
+
| `--rc-virtual-canvas-image-rendering` | `auto` | Fallback styling hook for the slotted canvas `image-rendering` value |
|
|
99
101
|
|
|
100
102
|
### CSS parts
|
|
101
103
|
|
|
102
|
-
| Part
|
|
103
|
-
|
|
104
|
-
| `scroller` | Internal scroll container that owns the virtual content scroll range
|
|
105
|
-
| `overlay`
|
|
104
|
+
| Part | Description |
|
|
105
|
+
| ---------- | -------------------------------------------------------------------------- |
|
|
106
|
+
| `scroller` | Internal scroll container that owns the virtual content scroll range |
|
|
107
|
+
| `overlay` | Viewport-positioned overlay container rendered inside the scroll container |
|
|
106
108
|
|
|
107
109
|
### Slots
|
|
108
110
|
|
|
109
|
-
| Slot
|
|
110
|
-
|
|
111
|
-
|
|
|
112
|
-
| `overlay`
|
|
111
|
+
| Slot | Description |
|
|
112
|
+
| ----------- | --------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| _(default)_ | A single `<canvas>` element. Non-canvas slotted elements are ignored by the component but rendered. |
|
|
114
|
+
| `overlay` | Optional viewport-positioned content rendered over the canvas inside the scroll container. |
|
|
113
115
|
|
|
114
116
|
### Events
|
|
115
117
|
|
|
116
|
-
| Event
|
|
117
|
-
|
|
118
|
-
| `rc-virtual-canvas-render` | Yes (composed) | No
|
|
118
|
+
| Event | Bubbles | Cancelable | Detail | When |
|
|
119
|
+
| -------------------------- | -------------- | ---------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
|
|
120
|
+
| `rc-virtual-canvas-render` | Yes (composed) | No | `{ time: DOMHighResTimeStamp, reason: RenderReason, viewRect: ViewRect, contentRect: ViewRect }` | When the active render mode schedules a frame and a canvas is slotted |
|
|
119
121
|
|
|
120
122
|
**`ViewRect` shape:**
|
|
121
123
|
|
|
122
124
|
```ts
|
|
123
125
|
type ViewRect = {
|
|
124
|
-
x: number;
|
|
125
|
-
y: number;
|
|
126
|
-
width: number;
|
|
126
|
+
x: number; // Scroll offset; the x origin of the visible window in content space
|
|
127
|
+
y: number; // Scroll offset; the y origin of the visible window in content space
|
|
128
|
+
width: number; // Visible width in device pixels (from ResizeObserver devicePixelContentBoxSize)
|
|
127
129
|
height: number; // Visible height in device pixels
|
|
128
130
|
};
|
|
129
131
|
```
|
|
@@ -134,11 +136,11 @@ type ViewRect = {
|
|
|
134
136
|
|
|
135
137
|
**Render modes:**
|
|
136
138
|
|
|
137
|
-
| Mode
|
|
138
|
-
|
|
139
|
-
| `'continuous'`
|
|
139
|
+
| Mode | Behavior |
|
|
140
|
+
| ------------------- | ----------------------------------------------------------------------------- |
|
|
141
|
+
| `'continuous'` | Dispatches on every animation frame while connected and a canvas is slotted |
|
|
140
142
|
| `'viewport-change'` | Dispatches after scroll, resize, content-size changes, and canvas replacement |
|
|
141
|
-
| `'manual'`
|
|
143
|
+
| `'manual'` | Dispatches only after `requestRender()` |
|
|
142
144
|
|
|
143
145
|
---
|
|
144
146
|
|
|
@@ -150,9 +152,14 @@ The component maps scroll position directly to content coordinates:
|
|
|
150
152
|
- `viewRect.y` = `scrollTop` of the internal scroll container
|
|
151
153
|
- `viewRect.width` / `viewRect.height` = canvas dimensions in device pixels (high-DPI aware)
|
|
152
154
|
|
|
155
|
+
`clientToContent()` and `contentToClient()` use CSS-pixel content coordinates. The
|
|
156
|
+
canvas backing-store resolution does not change pointer coordinates. Use
|
|
157
|
+
`canvasScaleX` and `canvasScaleY` only when scaling the drawing context.
|
|
158
|
+
|
|
153
159
|
When drawing, offset your scene by `viewRect.x` and `viewRect.y` to align the visible portion with the canvas origin:
|
|
154
160
|
|
|
155
161
|
```js
|
|
162
|
+
ctx.setTransform(vc.canvasScaleX, 0, 0, vc.canvasScaleY, 0, 0);
|
|
156
163
|
ctx.translate(-viewRect.x, -viewRect.y);
|
|
157
164
|
drawEntireScene(ctx);
|
|
158
165
|
ctx.resetTransform();
|
|
@@ -172,7 +179,7 @@ vc.addEventListener('pointerdown', (event) => {
|
|
|
172
179
|
|
|
173
180
|
## Accessibility
|
|
174
181
|
|
|
175
|
-
`rc-virtual-canvas` is a rendering surface. A `<canvas>` element has no inherent semantics
|
|
182
|
+
`rc-virtual-canvas` is a rendering surface. A `<canvas>` element has no inherent semantics; it is a bitmap, not a document. If your canvas renders interactive or informational content, you are responsible for providing supplemental accessibility:
|
|
176
183
|
|
|
177
184
|
- Add an accessible `<div>` or `<table>` alternative outside the canvas with the same information (hidden visually with `clip-path` or similar, not `display: none`).
|
|
178
185
|
- Use `aria-label` or `aria-labelledby` on the `<canvas>` to describe what it shows.
|
|
@@ -182,7 +189,7 @@ vc.addEventListener('pointerdown', (event) => {
|
|
|
182
189
|
|
|
183
190
|
## Browser support
|
|
184
191
|
|
|
185
|
-
| Feature
|
|
186
|
-
|
|
187
|
-
| Core
|
|
192
|
+
| Feature | Requirement |
|
|
193
|
+
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
|
194
|
+
| Core | Chrome 67+, Firefox 63+, Safari 12.1+ (Web Components) |
|
|
188
195
|
| Device-pixel-accurate sizing | Chrome 84+, Firefox 93+, Safari 15.4+ (ResizeObserver `devicePixelContentBoxSize`) |
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"name": "*",
|
|
36
36
|
"declaration": {
|
|
37
37
|
"name": "*",
|
|
38
|
-
"module": "src/rc-virtual-canvas"
|
|
38
|
+
"module": "src/rc-virtual-canvas.js"
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
]
|
|
@@ -300,14 +300,14 @@
|
|
|
300
300
|
"type": {
|
|
301
301
|
"text": "number"
|
|
302
302
|
},
|
|
303
|
-
"description": "
|
|
303
|
+
"description": "content x coordinate in CSS pixels"
|
|
304
304
|
},
|
|
305
305
|
{
|
|
306
306
|
"name": "y",
|
|
307
307
|
"type": {
|
|
308
308
|
"text": "number"
|
|
309
309
|
},
|
|
310
|
-
"description": "
|
|
310
|
+
"description": "content y coordinate in CSS pixels"
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"name": "options",
|
|
@@ -315,7 +315,7 @@
|
|
|
315
315
|
"type": {
|
|
316
316
|
"text": "ScrollOptions"
|
|
317
317
|
},
|
|
318
|
-
"description": "
|
|
318
|
+
"description": "native scroll options passed to scrollTo"
|
|
319
319
|
}
|
|
320
320
|
],
|
|
321
321
|
"description": "Scrolls so the content coordinate is at the viewport origin."
|
|
@@ -329,14 +329,14 @@
|
|
|
329
329
|
"type": {
|
|
330
330
|
"text": "number"
|
|
331
331
|
},
|
|
332
|
-
"description": "
|
|
332
|
+
"description": "content x coordinate in CSS pixels"
|
|
333
333
|
},
|
|
334
334
|
{
|
|
335
335
|
"name": "y",
|
|
336
336
|
"type": {
|
|
337
337
|
"text": "number"
|
|
338
338
|
},
|
|
339
|
-
"description": "
|
|
339
|
+
"description": "content y coordinate in CSS pixels"
|
|
340
340
|
},
|
|
341
341
|
{
|
|
342
342
|
"name": "options",
|
|
@@ -344,7 +344,7 @@
|
|
|
344
344
|
"type": {
|
|
345
345
|
"text": "ScrollOptions"
|
|
346
346
|
},
|
|
347
|
-
"description": "
|
|
347
|
+
"description": "native scroll options passed to scrollTo"
|
|
348
348
|
}
|
|
349
349
|
],
|
|
350
350
|
"description": "Scrolls so the content coordinate is centered in the viewport."
|
|
@@ -358,17 +358,17 @@
|
|
|
358
358
|
"type": {
|
|
359
359
|
"text": "number"
|
|
360
360
|
},
|
|
361
|
-
"description": "
|
|
361
|
+
"description": "browser client x coordinate (e.g. from a pointer event)"
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
"name": "clientY",
|
|
365
365
|
"type": {
|
|
366
366
|
"text": "number"
|
|
367
367
|
},
|
|
368
|
-
"description": "
|
|
368
|
+
"description": "browser client y coordinate"
|
|
369
369
|
}
|
|
370
370
|
],
|
|
371
|
-
"description": "Converts browser client coordinates to content coordinates
|
|
371
|
+
"description": "Converts browser client coordinates to CSS-pixel content coordinates.\nCanvas backing-store resolution does not change content coordinates."
|
|
372
372
|
},
|
|
373
373
|
{
|
|
374
374
|
"kind": "method",
|
|
@@ -379,14 +379,14 @@
|
|
|
379
379
|
"type": {
|
|
380
380
|
"text": "number"
|
|
381
381
|
},
|
|
382
|
-
"description": "
|
|
382
|
+
"description": "content x coordinate in CSS pixels"
|
|
383
383
|
},
|
|
384
384
|
{
|
|
385
385
|
"name": "y",
|
|
386
386
|
"type": {
|
|
387
387
|
"text": "number"
|
|
388
388
|
},
|
|
389
|
-
"description": "
|
|
389
|
+
"description": "content y coordinate in CSS pixels"
|
|
390
390
|
}
|
|
391
391
|
],
|
|
392
392
|
"description": "Converts content coordinates back to browser client coordinates."
|
|
@@ -401,7 +401,7 @@
|
|
|
401
401
|
"type": {
|
|
402
402
|
"text": "RCVirtualCanvasRenderReason"
|
|
403
403
|
},
|
|
404
|
-
"description": "
|
|
404
|
+
"description": "render reason reported in the event detail"
|
|
405
405
|
}
|
|
406
406
|
],
|
|
407
407
|
"description": "Queues a render event on the next animation frame.\n\nRequired when `renderMode` is `'manual'`. In other modes the component\nschedules renders automatically; calling this with reason `'animation-frame'`\nis a no-op when `renderMode` is `'viewport-change'`."
|
|
@@ -412,7 +412,7 @@
|
|
|
412
412
|
"type": {
|
|
413
413
|
"text": "number"
|
|
414
414
|
},
|
|
415
|
-
"description": "Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n\
|
|
415
|
+
"description": "Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n\nUse as the x-scale factor in `ctx.scale()` to draw at CSS pixel resolution.\nWhen `autoResizeCanvas` is true, CSS zoom changes this ratio along with\nthe backing-store resolution.",
|
|
416
416
|
"readonly": true
|
|
417
417
|
},
|
|
418
418
|
{
|
|
@@ -421,7 +421,7 @@
|
|
|
421
421
|
"type": {
|
|
422
422
|
"text": "number"
|
|
423
423
|
},
|
|
424
|
-
"description": "Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n\
|
|
424
|
+
"description": "Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n\nUse as the y-scale factor in `ctx.scale()` to draw at CSS pixel resolution.\nCSS zoom can make this ratio differ from `devicePixelRatio`.",
|
|
425
425
|
"readonly": true
|
|
426
426
|
},
|
|
427
427
|
{
|
|
@@ -466,7 +466,7 @@
|
|
|
466
466
|
"type": {
|
|
467
467
|
"text": "DOMHighResTimeStamp"
|
|
468
468
|
},
|
|
469
|
-
"description": "
|
|
469
|
+
"description": "high-resolution timestamp from `requestAnimationFrame`"
|
|
470
470
|
}
|
|
471
471
|
],
|
|
472
472
|
"description": "RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode."
|
|
@@ -522,11 +522,36 @@
|
|
|
522
522
|
},
|
|
523
523
|
{
|
|
524
524
|
"kind": "method",
|
|
525
|
-
"name": "
|
|
525
|
+
"name": "_getCanvasCssWidth",
|
|
526
526
|
"privacy": "protected",
|
|
527
|
+
"return": {
|
|
528
|
+
"type": {
|
|
529
|
+
"text": "number"
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"kind": "method",
|
|
535
|
+
"name": "_getCanvasCssHeight",
|
|
536
|
+
"privacy": "protected",
|
|
537
|
+
"return": {
|
|
538
|
+
"type": {
|
|
539
|
+
"text": "number"
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"kind": "method",
|
|
545
|
+
"name": "_getClientToContentScaleX",
|
|
546
|
+
"privacy": "protected",
|
|
547
|
+
"return": {
|
|
548
|
+
"type": {
|
|
549
|
+
"text": "number"
|
|
550
|
+
}
|
|
551
|
+
},
|
|
527
552
|
"parameters": [
|
|
528
553
|
{
|
|
529
|
-
"name": "
|
|
554
|
+
"name": "canvasViewportRect",
|
|
530
555
|
"type": {
|
|
531
556
|
"text": "DOMRect"
|
|
532
557
|
}
|
|
@@ -535,11 +560,16 @@
|
|
|
535
560
|
},
|
|
536
561
|
{
|
|
537
562
|
"kind": "method",
|
|
538
|
-
"name": "
|
|
563
|
+
"name": "_getClientToContentScaleY",
|
|
539
564
|
"privacy": "protected",
|
|
565
|
+
"return": {
|
|
566
|
+
"type": {
|
|
567
|
+
"text": "number"
|
|
568
|
+
}
|
|
569
|
+
},
|
|
540
570
|
"parameters": [
|
|
541
571
|
{
|
|
542
|
-
"name": "
|
|
572
|
+
"name": "canvasViewportRect",
|
|
543
573
|
"type": {
|
|
544
574
|
"text": "DOMRect"
|
|
545
575
|
}
|
|
@@ -1,79 +1,11 @@
|
|
|
1
|
-
import { css as _, LitElement as
|
|
1
|
+
import { css as _, LitElement as g, html as p } from "lit";
|
|
2
2
|
import { property as h, query as u, state as d } from "lit/decorators.js";
|
|
3
3
|
import { styleMap as b } from "lit/directives/style-map.js";
|
|
4
|
-
const w = _
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
:host {
|
|
12
|
-
position: relative;
|
|
13
|
-
display: block;
|
|
14
|
-
width: max-content;
|
|
15
|
-
line-height: 0; /* remove extra space under slotted <canvas> element(s) */
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
:host([hidden]) {
|
|
19
|
-
display: none;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#root {
|
|
23
|
-
position: absolute;
|
|
24
|
-
top: 0;
|
|
25
|
-
left: 0;
|
|
26
|
-
width: 100%;
|
|
27
|
-
height: 100%;
|
|
28
|
-
|
|
29
|
-
overflow: auto;
|
|
30
|
-
scrollbar-width: var(--rc-virtual-canvas-scrollbar-width, thin);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#root::-webkit-scrollbar {
|
|
34
|
-
width: var(--rc-virtual-canvas-scrollbar-size, auto);
|
|
35
|
-
height: var(--rc-virtual-canvas-scrollbar-size, auto);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
#root::-webkit-scrollbar-thumb {
|
|
39
|
-
background: var(--rc-virtual-canvas-scrollbar-thumb-background, ButtonFace);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
#root::-webkit-scrollbar-button {
|
|
43
|
-
background: var(--rc-virtual-canvas-scrollbar-button-background, ButtonFace);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
#root::-webkit-scrollbar-track {
|
|
47
|
-
background: var(--rc-virtual-canvas-scrollbar-track-background, Canvas);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
#placeholder {
|
|
51
|
-
pointer-events: none;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
#overlay {
|
|
55
|
-
position: sticky;
|
|
56
|
-
left: 0;
|
|
57
|
-
top: 0;
|
|
58
|
-
z-index: 1;
|
|
59
|
-
display: block;
|
|
60
|
-
width: 100%;
|
|
61
|
-
height: 0;
|
|
62
|
-
pointer-events: none;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
::slotted([slot='overlay']) {
|
|
66
|
-
pointer-events: auto;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
::slotted(canvas) {
|
|
70
|
-
image-rendering: var(--rc-virtual-canvas-image-rendering, auto);
|
|
71
|
-
}
|
|
72
|
-
`;
|
|
73
|
-
var R = Object.defineProperty, m = Object.getOwnPropertyDescriptor, o = (r, t, e, i) => {
|
|
74
|
-
for (var s = i > 1 ? void 0 : i ? m(t, e) : t, a = r.length - 1, l; a >= 0; a--)
|
|
75
|
-
(l = r[a]) && (s = (i ? l(t, e, s) : l(s)) || s);
|
|
76
|
-
return i && s && R(t, e, s), s;
|
|
4
|
+
const w = _`*,:before,:after{box-sizing:border-box}:host{width:max-content;line-height:0;display:block;position:relative}:host([hidden]){display:none}#root{scrollbar-width:var(--rc-virtual-canvas-scrollbar-width,thin);width:100%;height:100%;position:absolute;top:0;left:0;overflow:auto}#root::-webkit-scrollbar{width:var(--rc-virtual-canvas-scrollbar-size,auto);height:var(--rc-virtual-canvas-scrollbar-size,auto)}#root::-webkit-scrollbar-thumb{background:var(--rc-virtual-canvas-scrollbar-thumb-background,ButtonFace)}#root::-webkit-scrollbar-button{background:var(--rc-virtual-canvas-scrollbar-button-background,ButtonFace)}#root::-webkit-scrollbar-track{background:var(--rc-virtual-canvas-scrollbar-track-background,Canvas)}#placeholder{pointer-events:none}#overlay{z-index:1;pointer-events:none;width:100%;height:0;display:block;position:sticky;top:0;left:0}::slotted([slot=overlay]){pointer-events:auto}::slotted(canvas){image-rendering:var(--rc-virtual-canvas-image-rendering,auto)}`;
|
|
5
|
+
var C = Object.defineProperty, f = Object.getOwnPropertyDescriptor, o = (r, t, e, n) => {
|
|
6
|
+
for (var s = n > 1 ? void 0 : n ? f(t, e) : t, a = r.length - 1, l; a >= 0; a--)
|
|
7
|
+
(l = r[a]) && (s = (n ? l(t, e, s) : l(s)) || s);
|
|
8
|
+
return n && s && C(t, e, s), s;
|
|
77
9
|
};
|
|
78
10
|
function c(r) {
|
|
79
11
|
return Object.freeze({
|
|
@@ -83,7 +15,7 @@ function c(r) {
|
|
|
83
15
|
height: r.height
|
|
84
16
|
});
|
|
85
17
|
}
|
|
86
|
-
const v = class v extends
|
|
18
|
+
const v = class v extends g {
|
|
87
19
|
constructor() {
|
|
88
20
|
super(...arguments), this._rafHandle = 0, this._handledPointerEvents = /* @__PURE__ */ new WeakSet(), this._boundUpdate = (t) => this._update(t), this._boundPointerEvent = (t) => this._onPointerEvent(t), this._contentWidth = 0, this._contentHeight = 0, this.autoResizeCanvas = !0, this.renderMode = "continuous", this.imageRendering = "auto", this._$canvas = null, this._viewRect = {
|
|
89
21
|
x: 0,
|
|
@@ -97,15 +29,17 @@ const v = class v extends p {
|
|
|
97
29
|
height: 0
|
|
98
30
|
}, this._resizeObserver = new ResizeObserver((t) => {
|
|
99
31
|
for (const e of t) {
|
|
100
|
-
const
|
|
32
|
+
const n = Array.isArray(e.devicePixelContentBoxSize) ? e.devicePixelContentBoxSize[0] : e.devicePixelContentBoxSize;
|
|
101
33
|
this._viewRect.width = this._getMeasuredCanvasWidth(
|
|
102
|
-
|
|
34
|
+
n?.inlineSize ?? Math.round(e.contentRect.width * window.devicePixelRatio)
|
|
103
35
|
), this._viewRect.height = this._getMeasuredCanvasHeight(
|
|
104
|
-
|
|
36
|
+
n?.blockSize ?? Math.round(e.contentRect.height * window.devicePixelRatio)
|
|
105
37
|
), this._syncCanvasBackingStore(), this._scheduleRender("viewport-change");
|
|
106
38
|
}
|
|
107
39
|
});
|
|
108
40
|
}
|
|
41
|
+
firstUpdated() {
|
|
42
|
+
}
|
|
109
43
|
set contentWidth(t) {
|
|
110
44
|
const e = this._contentWidth;
|
|
111
45
|
this._contentWidth = t, this._contentRect.width = this._contentWidth, this.requestUpdate("contentWidth", e), this._scheduleRender("viewport-change");
|
|
@@ -157,13 +91,13 @@ const v = class v extends p {
|
|
|
157
91
|
/**
|
|
158
92
|
* Scrolls so the content coordinate is at the viewport origin.
|
|
159
93
|
*
|
|
160
|
-
* @param x -
|
|
161
|
-
* @param y -
|
|
162
|
-
* @param options -
|
|
94
|
+
* @param x - content x coordinate in CSS pixels
|
|
95
|
+
* @param y - content y coordinate in CSS pixels
|
|
96
|
+
* @param options - native scroll options passed to scrollTo
|
|
163
97
|
*/
|
|
164
|
-
scrollToContent(t, e,
|
|
98
|
+
scrollToContent(t, e, n = {}) {
|
|
165
99
|
this._$root.scrollTo({
|
|
166
|
-
...
|
|
100
|
+
...n,
|
|
167
101
|
left: t,
|
|
168
102
|
top: e
|
|
169
103
|
}), this._viewRect.x = this._$root.scrollLeft, this._viewRect.y = this._$root.scrollTop, this._scheduleRender("viewport-change");
|
|
@@ -171,23 +105,23 @@ const v = class v extends p {
|
|
|
171
105
|
/**
|
|
172
106
|
* Scrolls so the content coordinate is centered in the viewport.
|
|
173
107
|
*
|
|
174
|
-
* @param x -
|
|
175
|
-
* @param y -
|
|
176
|
-
* @param options -
|
|
108
|
+
* @param x - content x coordinate in CSS pixels
|
|
109
|
+
* @param y - content y coordinate in CSS pixels
|
|
110
|
+
* @param options - native scroll options passed to scrollTo
|
|
177
111
|
*/
|
|
178
|
-
centerOnContent(t, e,
|
|
112
|
+
centerOnContent(t, e, n = {}) {
|
|
179
113
|
this.scrollToContent(
|
|
180
114
|
t - this._$root.clientWidth * 0.5,
|
|
181
115
|
e - this._$root.clientHeight * 0.5,
|
|
182
|
-
|
|
116
|
+
n
|
|
183
117
|
);
|
|
184
118
|
}
|
|
185
119
|
/**
|
|
186
|
-
* Converts browser client coordinates to content coordinates
|
|
187
|
-
* backing-store
|
|
120
|
+
* Converts browser client coordinates to CSS-pixel content coordinates.
|
|
121
|
+
* Canvas backing-store resolution does not change content coordinates.
|
|
188
122
|
*
|
|
189
|
-
* @param clientX -
|
|
190
|
-
* @param clientY -
|
|
123
|
+
* @param clientX - browser client x coordinate (e.g. from a pointer event)
|
|
124
|
+
* @param clientY - browser client y coordinate
|
|
191
125
|
*
|
|
192
126
|
* @example
|
|
193
127
|
* vc.addEventListener('pointerdown', (e) => {
|
|
@@ -196,28 +130,27 @@ const v = class v extends p {
|
|
|
196
130
|
* });
|
|
197
131
|
*/
|
|
198
132
|
clientToContent(t, e) {
|
|
199
|
-
const
|
|
133
|
+
const n = this._getCanvasClientRect(), s = this._getClientToContentScaleX(n), a = this._getClientToContentScaleY(n);
|
|
200
134
|
return Object.freeze({
|
|
201
|
-
x: this._viewRect.x + (t -
|
|
202
|
-
y: this._viewRect.y + (e -
|
|
135
|
+
x: this._viewRect.x + (t - n.left) * s,
|
|
136
|
+
y: this._viewRect.y + (e - n.top) * a
|
|
203
137
|
});
|
|
204
138
|
}
|
|
205
139
|
/**
|
|
206
140
|
* Converts content coordinates back to browser client coordinates.
|
|
207
141
|
*
|
|
208
|
-
* @param x -
|
|
209
|
-
* @param y -
|
|
142
|
+
* @param x - content x coordinate in CSS pixels
|
|
143
|
+
* @param y - content y coordinate in CSS pixels
|
|
210
144
|
*
|
|
211
145
|
* @example
|
|
212
146
|
* const { x, y } = vc.contentToClient(contentX, contentY);
|
|
213
|
-
*
|
|
214
|
-
* tooltip.style.top = `${y}px`;
|
|
147
|
+
* const elementAtPoint = document.elementFromPoint(x, y);
|
|
215
148
|
*/
|
|
216
149
|
contentToClient(t, e) {
|
|
217
|
-
const
|
|
150
|
+
const n = this._getCanvasClientRect(), s = this._getClientToContentScaleX(n), a = this._getClientToContentScaleY(n);
|
|
218
151
|
return Object.freeze({
|
|
219
|
-
x:
|
|
220
|
-
y:
|
|
152
|
+
x: n.left + (t - this._viewRect.x) / s,
|
|
153
|
+
y: n.top + (e - this._viewRect.y) / a
|
|
221
154
|
});
|
|
222
155
|
}
|
|
223
156
|
/**
|
|
@@ -227,7 +160,7 @@ const v = class v extends p {
|
|
|
227
160
|
* schedules renders automatically; calling this with reason `'animation-frame'`
|
|
228
161
|
* is a no-op when `renderMode` is `'viewport-change'`.
|
|
229
162
|
*
|
|
230
|
-
* @param reason -
|
|
163
|
+
* @param reason - render reason reported in the event detail
|
|
231
164
|
*/
|
|
232
165
|
requestRender(t = "manual") {
|
|
233
166
|
this._scheduleRender(t);
|
|
@@ -235,8 +168,9 @@ const v = class v extends p {
|
|
|
235
168
|
/**
|
|
236
169
|
* Ratio of canvas backing-store pixels to CSS pixels along the x-axis.
|
|
237
170
|
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
171
|
+
* Use as the x-scale factor in `ctx.scale()` to draw at CSS pixel resolution.
|
|
172
|
+
* When `autoResizeCanvas` is true, CSS zoom changes this ratio along with
|
|
173
|
+
* the backing-store resolution.
|
|
240
174
|
*
|
|
241
175
|
* @example
|
|
242
176
|
* vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {
|
|
@@ -247,18 +181,18 @@ const v = class v extends p {
|
|
|
247
181
|
* });
|
|
248
182
|
*/
|
|
249
183
|
get canvasScaleX() {
|
|
250
|
-
const t = this.
|
|
251
|
-
return this.
|
|
184
|
+
const t = this._getCanvasCssWidth();
|
|
185
|
+
return t > 0 ? this._viewRect.width / t : 1;
|
|
252
186
|
}
|
|
253
187
|
/**
|
|
254
188
|
* Ratio of canvas backing-store pixels to CSS pixels along the y-axis.
|
|
255
189
|
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
190
|
+
* Use as the y-scale factor in `ctx.scale()` to draw at CSS pixel resolution.
|
|
191
|
+
* CSS zoom can make this ratio differ from `devicePixelRatio`.
|
|
258
192
|
*/
|
|
259
193
|
get canvasScaleY() {
|
|
260
|
-
const t = this.
|
|
261
|
-
return this.
|
|
194
|
+
const t = this._getCanvasCssHeight();
|
|
195
|
+
return t > 0 ? this._viewRect.height / t : 1;
|
|
262
196
|
}
|
|
263
197
|
/** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */
|
|
264
198
|
_onPointerEvent(t) {
|
|
@@ -295,7 +229,7 @@ const v = class v extends p {
|
|
|
295
229
|
/**
|
|
296
230
|
* RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.
|
|
297
231
|
*
|
|
298
|
-
* @param time -
|
|
232
|
+
* @param time - high-resolution timestamp from `requestAnimationFrame`
|
|
299
233
|
*/
|
|
300
234
|
_update(t) {
|
|
301
235
|
if (this._rafHandle = 0, !this.isConnected || this._$canvas == null)
|
|
@@ -344,14 +278,22 @@ const v = class v extends p {
|
|
|
344
278
|
_getMeasuredCanvasHeight(t) {
|
|
345
279
|
return !this.autoResizeCanvas && this._$canvas && this._$canvas.height > 0 ? this._$canvas.height : t;
|
|
346
280
|
}
|
|
347
|
-
|
|
348
|
-
return
|
|
281
|
+
_getCanvasCssWidth() {
|
|
282
|
+
return this._$canvas?.clientWidth ?? this.clientWidth;
|
|
283
|
+
}
|
|
284
|
+
_getCanvasCssHeight() {
|
|
285
|
+
return this._$canvas?.clientHeight ?? this.clientHeight;
|
|
286
|
+
}
|
|
287
|
+
_getClientToContentScaleX(t) {
|
|
288
|
+
const e = this._getCanvasCssWidth();
|
|
289
|
+
return t.width > 0 && e > 0 ? e / t.width : 1;
|
|
349
290
|
}
|
|
350
|
-
|
|
351
|
-
|
|
291
|
+
_getClientToContentScaleY(t) {
|
|
292
|
+
const e = this._getCanvasCssHeight();
|
|
293
|
+
return t.height > 0 && e > 0 ? e / t.height : 1;
|
|
352
294
|
}
|
|
353
295
|
render() {
|
|
354
|
-
return
|
|
296
|
+
return p`
|
|
355
297
|
<div
|
|
356
298
|
id="root"
|
|
357
299
|
part="scroller"
|
|
@@ -381,38 +323,38 @@ const v = class v extends p {
|
|
|
381
323
|
}
|
|
382
324
|
};
|
|
383
325
|
v.styles = [w];
|
|
384
|
-
let
|
|
326
|
+
let i = v;
|
|
385
327
|
o([
|
|
386
328
|
h({ type: Number, attribute: "content-width" })
|
|
387
|
-
],
|
|
329
|
+
], i.prototype, "contentWidth", 1);
|
|
388
330
|
o([
|
|
389
331
|
h({ type: Number, attribute: "content-height" })
|
|
390
|
-
],
|
|
332
|
+
], i.prototype, "contentHeight", 1);
|
|
391
333
|
o([
|
|
392
334
|
h({ attribute: "auto-resize-canvas", type: Boolean })
|
|
393
|
-
],
|
|
335
|
+
], i.prototype, "autoResizeCanvas", 2);
|
|
394
336
|
o([
|
|
395
337
|
h({ attribute: "render-mode" })
|
|
396
|
-
],
|
|
338
|
+
], i.prototype, "renderMode", 2);
|
|
397
339
|
o([
|
|
398
340
|
h({ attribute: "image-rendering" })
|
|
399
|
-
],
|
|
341
|
+
], i.prototype, "imageRendering", 2);
|
|
400
342
|
o([
|
|
401
343
|
u("#root", !0)
|
|
402
|
-
],
|
|
344
|
+
], i.prototype, "_$root", 2);
|
|
403
345
|
o([
|
|
404
346
|
u("#placeholder", !0)
|
|
405
|
-
],
|
|
347
|
+
], i.prototype, "_$placeholder", 2);
|
|
406
348
|
o([
|
|
407
349
|
d()
|
|
408
|
-
],
|
|
350
|
+
], i.prototype, "_$canvas", 2);
|
|
409
351
|
o([
|
|
410
352
|
d()
|
|
411
|
-
],
|
|
353
|
+
], i.prototype, "_viewRect", 2);
|
|
412
354
|
o([
|
|
413
355
|
d()
|
|
414
|
-
],
|
|
356
|
+
], i.prototype, "_contentRect", 2);
|
|
415
357
|
export {
|
|
416
|
-
|
|
358
|
+
i as R
|
|
417
359
|
};
|
|
418
|
-
//# sourceMappingURL=rc-virtual-canvas-
|
|
360
|
+
//# sourceMappingURL=rc-virtual-canvas-DIy-ABTk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-virtual-canvas-DIy-ABTk.js","sources":["../src/rc-virtual-canvas.styles.ts","../src/rc-virtual-canvas.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const virtualCanvasStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n position: relative;\n display: block;\n width: max-content;\n line-height: 0; /* remove extra space under slotted <canvas> element(s) */\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n overflow: auto;\n scrollbar-width: var(--rc-virtual-canvas-scrollbar-width, thin);\n }\n\n #root::-webkit-scrollbar {\n width: var(--rc-virtual-canvas-scrollbar-size, auto);\n height: var(--rc-virtual-canvas-scrollbar-size, auto);\n }\n\n #root::-webkit-scrollbar-thumb {\n background: var(--rc-virtual-canvas-scrollbar-thumb-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-button {\n background: var(--rc-virtual-canvas-scrollbar-button-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-track {\n background: var(--rc-virtual-canvas-scrollbar-track-background, Canvas);\n }\n\n #placeholder {\n pointer-events: none;\n }\n\n #overlay {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 1;\n display: block;\n width: 100%;\n height: 0;\n pointer-events: none;\n }\n\n ::slotted([slot='overlay']) {\n pointer-events: auto;\n }\n\n ::slotted(canvas) {\n image-rendering: var(--rc-virtual-canvas-image-rendering, auto);\n }\n`;\n\nexport default virtualCanvasStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport virtualCanvasStyles from './rc-virtual-canvas.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-virtual-canvas': RCVirtualCanvas;\n }\n\n interface HTMLElementEventMap {\n 'rc-virtual-canvas-render': CustomEvent<RCVirtualCanvasRenderInit>;\n 'rc-virtual-canvas-pointer': CustomEvent<RCVirtualCanvasPointerInit>;\n }\n}\n\n/**\n * Scrollable virtual canvas for rendering large coordinate-space content.\n *\n * `x` and `y` are scroll offsets in CSS pixels; `width` and `height` are the canvas\n * backing-store dimensions in device pixels (DPR-accurate when `autoResizeCanvas` is `true`).\n */\nexport type RCVirtualCanvasViewRect = Readonly<{\n /** Scroll offset x in content space (CSS px) */\n x: number;\n\n /** Scroll offset y in content space (CSS px) */\n y: number;\n\n /** Visible width in device pixels */\n width: number;\n\n /** Visible height in device pixels */\n height: number;\n}>;\n\n/** Controls when `rc-virtual-canvas-render` events are dispatched */\nexport type RCVirtualCanvasRenderMode = 'continuous' | 'viewport-change' | 'manual';\n\n/** Identifies what triggered a render event */\nexport type RCVirtualCanvasRenderReason = 'animation-frame' | 'viewport-change' | 'manual';\n\n/** Content-space coordinate pair returned by coordinate-conversion methods */\nexport type RCVirtualCanvasPoint = Readonly<{\n /** Content space x coordinate in CSS pixels */\n x: number;\n\n /** Content space y coordinate in CSS pixels */\n y: number;\n}>;\n\n/**\n * Detail shape for `rc-virtual-canvas-pointer` events.\n *\n * Carries the source event's coordinates in both browser-client and content space,\n * along with all modifier key state.\n */\nexport type RCVirtualCanvasPointerInit = {\n /** DOM event type (e.g. `'pointerdown'`, `'click'`) */\n type: string;\n\n /** Browser client x coordinate from the source event */\n clientX: number;\n\n /** Browser client y coordinate from the source event */\n clientY: number;\n\n /** Content x coordinate in CSS pixels */\n contentX: number;\n\n /** Content y coordinate in CSS pixels */\n contentY: number;\n\n /** Frozen viewport snapshot at the moment the pointer event fired */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Mouse button index from the source event */\n button: number;\n\n /** Active button bitmask from the source event */\n buttons: number;\n\n /** Whether the Alt key was held */\n altKey: boolean;\n\n /** Whether the Ctrl key was held */\n ctrlKey: boolean;\n\n /** Whether the Shift key was held */\n shiftKey: boolean;\n\n /** Whether the Meta key was held */\n metaKey: boolean;\n\n /** The original DOM event that produced this detail */\n sourceEvent: PointerEvent | MouseEvent;\n};\n\n/** CSS `image-rendering` value applied to the slotted canvas */\nexport type RCVirtualCanvasImageRendering = 'auto' | 'crisp-edges' | 'pixelated';\n\n/** Detail shape for `rc-virtual-canvas-render` events */\nexport type RCVirtualCanvasRenderInit = {\n /** High-resolution timestamp from `requestAnimationFrame` */\n time: DOMHighResTimeStamp;\n\n /** What triggered this render */\n reason: RCVirtualCanvasRenderReason;\n\n /** Frozen snapshot of the viewport for this frame */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Frozen snapshot of the full content bounds for this frame */\n contentRect: RCVirtualCanvasViewRect;\n};\n\nfunction createRectSnapshot(rect: RCVirtualCanvasViewRect) {\n return Object.freeze({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n}\n\n/**\n * A scrollable virtual canvas component.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas rc-virtual-canvas docs}\n *\n * @slot - The HTMLCanvasElement\n * @slot overlay - Optional viewport-positioned content rendered inside the\n * scroll container above the canvas.\n *\n * @fires rc-virtual-canvas-render - Fires with viewport data when the canvas should redraw.\n * @fires rc-virtual-canvas-pointer - Fires pointer/mouse input mapped to virtual content coordinates.\n *\n * @csspart scroller - Internal scroll container that owns the virtual content scroll range.\n * @csspart overlay - Viewport-positioned overlay container rendered inside the scroll container.\n *\n * @attr content-width - Total pixel width of the virtual content.\n * @attr content-height - Total pixel height of the virtual content.\n * @attr auto-resize-canvas - Keep the slotted canvas backing store aligned to the viewport.\n * @attr render-mode - Controls when render events are dispatched.\n * @attr image-rendering - Convenience `image-rendering` value applied to the slotted canvas.\n *\n * @cssprop [--rc-virtual-canvas-scrollbar-width=thin] - `scrollbar-width` of the internal\n * scroll container.\n * @cssprop [--rc-virtual-canvas-scrollbar-size=auto] - WebKit scrollbar thickness.\n * @cssprop [--rc-virtual-canvas-scrollbar-thumb-background=ButtonFace] - WebKit scrollbar\n * thumb color.\n * @cssprop [--rc-virtual-canvas-scrollbar-button-background=ButtonFace] - WebKit scrollbar\n * button color.\n * @cssprop [--rc-virtual-canvas-scrollbar-track-background=Canvas] - WebKit scrollbar\n * track color.\n * @cssprop [--rc-virtual-canvas-image-rendering=auto] - `image-rendering` applied to the\n * slotted canvas; kept in sync with the `imageRendering` property.\n */\nexport class RCVirtualCanvas extends LitElement {\n static styles = [virtualCanvasStyles];\n\n protected _rafHandle: number = 0;\n protected _pendingRenderReason?: RCVirtualCanvasRenderReason;\n\n protected override firstUpdated(): void {\n if (import.meta.env.DEV && !this.querySelector(':scope > canvas')) {\n console.warn(\n '[rc-virtual-canvas] No direct child <canvas> found. Place a native <canvas> inside <rc-virtual-canvas>.',\n this,\n );\n }\n }\n\n protected readonly _handledPointerEvents = new WeakSet<Event>();\n\n // Stored bound reference so the same closure is used for scheduling and\n // cancellation — `bind()` returns a new function every call.\n protected readonly _boundUpdate = (time: DOMHighResTimeStamp) => this._update(time);\n\n protected readonly _boundPointerEvent = (event: PointerEvent | MouseEvent) =>\n this._onPointerEvent(event);\n\n /** Pixel width of the virtual content */\n @property({ type: Number, attribute: 'content-width' })\n set contentWidth(val: number) {\n const oldValue = this._contentWidth;\n\n this._contentWidth = val;\n\n this._contentRect.width = this._contentWidth;\n this.requestUpdate('contentWidth', oldValue);\n this._scheduleRender('viewport-change');\n }\n\n get contentWidth() {\n return this._contentWidth;\n }\n\n private _contentWidth: number = 0;\n\n /** Pixel height of the virtual content */\n @property({ type: Number, attribute: 'content-height' })\n set contentHeight(val: number) {\n const oldValue = this._contentHeight;\n\n this._contentHeight = val;\n\n this._contentRect.height = this._contentHeight;\n this.requestUpdate('contentHeight', oldValue);\n this._scheduleRender('viewport-change');\n }\n\n get contentHeight() {\n return this._contentHeight;\n }\n\n private _contentHeight: number = 0;\n\n /** When true, keep the slotted canvas backing store aligned to the viewport. */\n @property({ attribute: 'auto-resize-canvas', type: Boolean })\n autoResizeCanvas: boolean = true;\n\n /** Controls when render events are dispatched. */\n @property({ attribute: 'render-mode' })\n renderMode: RCVirtualCanvasRenderMode = 'continuous';\n\n /** Convenience image-rendering value applied to the slotted canvas. */\n @property({ attribute: 'image-rendering' })\n imageRendering: RCVirtualCanvasImageRendering = 'auto';\n\n /** Shadow DOM scroll container that owns pointer interaction and native scrolling */\n @query('#root', true)\n protected _$root!: HTMLDivElement;\n\n /** Absolutely-positioned div that establishes the virtual scroll range */\n @query('#placeholder', true)\n protected _$placeholder!: HTMLDivElement;\n\n /** Currently-tracked slotted canvas element; `null` when no canvas is slotted */\n @state()\n protected _$canvas: HTMLCanvasElement | null = null;\n\n /** Mutable current-frame viewport geometry; call `getViewRect()` for a frozen snapshot */\n @state()\n protected _viewRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Mutable content bounds; updated when `contentWidth` or `contentHeight` change */\n @state()\n protected _contentRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Watches the slotted canvas for DPR-accurate dimension changes */\n protected _resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const devicePixelBoxSize = Array.isArray(entry.devicePixelContentBoxSize)\n ? entry.devicePixelContentBoxSize[0]\n : entry.devicePixelContentBoxSize;\n\n this._viewRect.width = this._getMeasuredCanvasWidth(\n devicePixelBoxSize?.inlineSize ??\n Math.round(entry.contentRect.width * window.devicePixelRatio),\n );\n\n this._viewRect.height = this._getMeasuredCanvasHeight(\n devicePixelBoxSize?.blockSize ??\n Math.round(entry.contentRect.height * window.devicePixelRatio),\n );\n\n this._syncCanvasBackingStore();\n this._scheduleRender('viewport-change');\n }\n });\n\n /** Reads scroll position from the root container and schedules a render */\n protected _onScroll() {\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n\n this._scheduleRender('viewport-change');\n }\n\n /** Replaces canvas tracking and re-registers the resize observer when slot content changes */\n protected _onSlotChange(e: Event) {\n this._resizeObserver.disconnect();\n\n this._$canvas =\n (e.currentTarget as HTMLSlotElement)\n .assignedElements()\n .filter((el) => el instanceof HTMLCanvasElement)[0] ?? null;\n\n if (this._$canvas != null) {\n this._viewRect = {\n x: this._$root.scrollLeft ?? 0,\n y: this._$root.scrollTop ?? 0,\n width: this._getMeasuredCanvasWidth(this._$canvas.clientWidth),\n height: this._getMeasuredCanvasHeight(this._$canvas.clientHeight),\n };\n\n this._syncCanvasBackingStore();\n this._observeCanvasResize(this._$canvas);\n\n this._scheduleRender('viewport-change');\n }\n }\n\n /** Observes canvas size with DPR-accurate boxes when the browser supports them */\n protected _observeCanvasResize($canvas: HTMLCanvasElement) {\n try {\n this._resizeObserver.observe($canvas, {\n box: 'device-pixel-content-box',\n });\n } catch (error) {\n if (!(error instanceof TypeError)) {\n throw error;\n }\n\n this._resizeObserver.observe($canvas);\n }\n }\n\n /**\n * Returns a frozen snapshot of the current viewport rectangle.\n *\n * Safe to keep between frames — the returned object will not be mutated\n * by future scroll or resize work.\n */\n getViewRect() {\n return createRectSnapshot(this._viewRect);\n }\n\n /**\n * Scrolls so the content coordinate is at the viewport origin.\n *\n * @param x - content x coordinate in CSS pixels\n * @param y - content y coordinate in CSS pixels\n * @param options - native scroll options passed to scrollTo\n */\n scrollToContent(x: number, y: number, options: ScrollOptions = {}) {\n this._$root.scrollTo({\n ...options,\n left: x,\n top: y,\n });\n\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n this._scheduleRender('viewport-change');\n }\n\n /**\n * Scrolls so the content coordinate is centered in the viewport.\n *\n * @param x - content x coordinate in CSS pixels\n * @param y - content y coordinate in CSS pixels\n * @param options - native scroll options passed to scrollTo\n */\n centerOnContent(x: number, y: number, options: ScrollOptions = {}) {\n this.scrollToContent(\n x - this._$root.clientWidth * 0.5,\n y - this._$root.clientHeight * 0.5,\n options,\n );\n }\n\n /**\n * Converts browser client coordinates to CSS-pixel content coordinates.\n * Canvas backing-store resolution does not change content coordinates.\n *\n * @param clientX - browser client x coordinate (e.g. from a pointer event)\n * @param clientY - browser client y coordinate\n *\n * @example\n * vc.addEventListener('pointerdown', (e) => {\n * const { x, y } = vc.clientToContent(e.clientX, e.clientY);\n * placeMarkerAt(x, y);\n * });\n */\n clientToContent(clientX: number, clientY: number) {\n const canvasViewportRect = this._getCanvasClientRect();\n const clientToContentScaleX = this._getClientToContentScaleX(canvasViewportRect);\n const clientToContentScaleY = this._getClientToContentScaleY(canvasViewportRect);\n\n return Object.freeze({\n x: this._viewRect.x + (clientX - canvasViewportRect.left) * clientToContentScaleX,\n y: this._viewRect.y + (clientY - canvasViewportRect.top) * clientToContentScaleY,\n });\n }\n\n /**\n * Converts content coordinates back to browser client coordinates.\n *\n * @param x - content x coordinate in CSS pixels\n * @param y - content y coordinate in CSS pixels\n *\n * @example\n * const { x, y } = vc.contentToClient(contentX, contentY);\n * const elementAtPoint = document.elementFromPoint(x, y);\n */\n contentToClient(x: number, y: number) {\n const canvasViewportRect = this._getCanvasClientRect();\n const clientToContentScaleX = this._getClientToContentScaleX(canvasViewportRect);\n const clientToContentScaleY = this._getClientToContentScaleY(canvasViewportRect);\n\n return Object.freeze({\n x: canvasViewportRect.left + (x - this._viewRect.x) / clientToContentScaleX,\n y: canvasViewportRect.top + (y - this._viewRect.y) / clientToContentScaleY,\n });\n }\n\n /**\n * Queues a render event on the next animation frame.\n *\n * Required when `renderMode` is `'manual'`. In other modes the component\n * schedules renders automatically; calling this with reason `'animation-frame'`\n * is a no-op when `renderMode` is `'viewport-change'`.\n *\n * @param reason - render reason reported in the event detail\n */\n requestRender(reason: RCVirtualCanvasRenderReason = 'manual') {\n this._scheduleRender(reason);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n *\n * Use as the x-scale factor in `ctx.scale()` to draw at CSS pixel resolution.\n * When `autoResizeCanvas` is true, CSS zoom changes this ratio along with\n * the backing-store resolution.\n *\n * @example\n * vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {\n * ctx.save();\n * ctx.scale(vc.canvasScaleX, vc.canvasScaleY);\n * drawScene(ctx, viewRect);\n * ctx.restore();\n * });\n */\n get canvasScaleX(): number {\n const cssWidth = this._getCanvasCssWidth();\n\n return cssWidth > 0 ? this._viewRect.width / cssWidth : 1;\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n *\n * Use as the y-scale factor in `ctx.scale()` to draw at CSS pixel resolution.\n * CSS zoom can make this ratio differ from `devicePixelRatio`.\n */\n get canvasScaleY(): number {\n const cssHeight = this._getCanvasCssHeight();\n\n return cssHeight > 0 ? this._viewRect.height / cssHeight : 1;\n }\n\n /** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */\n protected _onPointerEvent(event: PointerEvent | MouseEvent) {\n if (this._handledPointerEvents.has(event)) {\n return;\n }\n\n if (this._isOverlayEvent(event)) {\n return;\n }\n\n this._handledPointerEvents.add(event);\n\n const contentPoint = this.clientToContent(event.clientX, event.clientY);\n\n const shouldContinue = this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasPointerInit>('rc-virtual-canvas-pointer', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: {\n type: event.type,\n clientX: event.clientX,\n clientY: event.clientY,\n contentX: contentPoint.x,\n contentY: contentPoint.y,\n viewRect: createRectSnapshot(this._viewRect),\n button: event.button,\n buttons: event.buttons,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n sourceEvent: event,\n },\n }),\n );\n\n if (!shouldContinue) {\n event.preventDefault();\n }\n }\n\n protected _isOverlayEvent(event: Event): boolean {\n return event\n .composedPath()\n .some(($node) => $node instanceof HTMLSlotElement && $node.name === 'overlay');\n }\n\n /**\n * RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.\n *\n * @param time - high-resolution timestamp from `requestAnimationFrame`\n */\n protected _update(time: DOMHighResTimeStamp) {\n this._rafHandle = 0;\n\n if (!this.isConnected || this._$canvas == null) {\n return;\n }\n\n const reason =\n this._pendingRenderReason ??\n (this.renderMode === 'continuous' ? 'animation-frame' : 'manual');\n\n this._pendingRenderReason = undefined;\n\n this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasRenderInit>('rc-virtual-canvas-render', {\n bubbles: true,\n composed: true,\n detail: {\n time,\n reason,\n viewRect: createRectSnapshot(this._viewRect),\n contentRect: createRectSnapshot(this._contentRect),\n },\n }),\n );\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Registers pointer event listeners and starts rendering in continuous mode */\n override connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('pointerdown', this._boundPointerEvent);\n this.addEventListener('pointermove', this._boundPointerEvent);\n this.addEventListener('pointerup', this._boundPointerEvent);\n this.addEventListener('click', this._boundPointerEvent);\n this.addEventListener('dblclick', this._boundPointerEvent);\n this.addEventListener('contextmenu', this._boundPointerEvent);\n\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n }\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Cancels any pending animation frame, disconnects the resize observer, and removes pointer listeners */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n this._resizeObserver.disconnect();\n\n this.removeEventListener('pointerdown', this._boundPointerEvent);\n this.removeEventListener('pointermove', this._boundPointerEvent);\n this.removeEventListener('pointerup', this._boundPointerEvent);\n this.removeEventListener('click', this._boundPointerEvent);\n this.removeEventListener('dblclick', this._boundPointerEvent);\n this.removeEventListener('contextmenu', this._boundPointerEvent);\n }\n\n /** Reacts to `renderMode`, `autoResizeCanvas`, and `imageRendering` property changes */\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('renderMode')) {\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n } else if (this._pendingRenderReason === 'animation-frame') {\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n\n this._rafHandle = 0;\n }\n\n this._pendingRenderReason = undefined;\n } else if (this.renderMode === 'viewport-change') {\n this._scheduleRender('viewport-change');\n }\n }\n\n if (changed.has('autoResizeCanvas')) {\n this._syncCanvasBackingStore();\n }\n\n if (changed.has('imageRendering')) {\n this.style.setProperty('--rc-virtual-canvas-image-rendering', this.imageRendering);\n }\n }\n\n protected _scheduleRender(reason: RCVirtualCanvasRenderReason) {\n if (this.renderMode === 'manual' && reason !== 'manual') {\n return;\n }\n\n if (this.renderMode === 'viewport-change' && reason === 'animation-frame') {\n return;\n }\n\n this._pendingRenderReason = reason;\n\n if (!this.isConnected || this._rafHandle) {\n return;\n }\n\n this._rafHandle = window.requestAnimationFrame(this._boundUpdate);\n }\n\n protected _syncCanvasBackingStore() {\n if (!this.autoResizeCanvas || this._$canvas == null) {\n return;\n }\n\n const width = Math.max(0, Math.round(this._viewRect.width));\n const height = Math.max(0, Math.round(this._viewRect.height));\n\n if (this._$canvas.width !== width) {\n this._$canvas.width = width;\n }\n\n if (this._$canvas.height !== height) {\n this._$canvas.height = height;\n }\n }\n\n protected _getCanvasClientRect() {\n if (this._$canvas == null) {\n return this.getBoundingClientRect();\n }\n\n return this._$canvas.getBoundingClientRect();\n }\n\n protected _getMeasuredCanvasWidth(fallbackWidth: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.width > 0) {\n return this._$canvas.width;\n }\n\n return fallbackWidth;\n }\n\n protected _getMeasuredCanvasHeight(fallbackHeight: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.height > 0) {\n return this._$canvas.height;\n }\n\n return fallbackHeight;\n }\n\n protected _getCanvasCssWidth(): number {\n return this._$canvas?.clientWidth ?? this.clientWidth;\n }\n\n protected _getCanvasCssHeight(): number {\n return this._$canvas?.clientHeight ?? this.clientHeight;\n }\n\n protected _getClientToContentScaleX(canvasViewportRect: DOMRect): number {\n const canvasCssWidth = this._getCanvasCssWidth();\n\n return canvasViewportRect.width > 0 && canvasCssWidth > 0\n ? canvasCssWidth / canvasViewportRect.width\n : 1;\n }\n\n protected _getClientToContentScaleY(canvasViewportRect: DOMRect): number {\n const canvasCssHeight = this._getCanvasCssHeight();\n\n return canvasViewportRect.height > 0 && canvasCssHeight > 0\n ? canvasCssHeight / canvasViewportRect.height\n : 1;\n }\n\n render() {\n return html`\n <div\n id=\"root\"\n part=\"scroller\"\n @scroll=${this._onScroll}\n @pointerdown=${this._onPointerEvent}\n @pointermove=${this._onPointerEvent}\n @pointerup=${this._onPointerEvent}\n @click=${this._onPointerEvent}\n @dblclick=${this._onPointerEvent}\n @contextmenu=${this._onPointerEvent}\n >\n <div id=\"overlay\" part=\"overlay\">\n <slot name=\"overlay\"></slot>\n </div>\n\n <div\n id=\"placeholder\"\n style=${styleMap({\n width: `${this.contentWidth}px`,\n height: `${this.contentHeight}px`,\n })}\n ></div>\n </div>\n\n <slot @slotchange=${this._onSlotChange}></slot>\n `;\n }\n}\n\nexport default RCVirtualCanvas;\n"],"names":["virtualCanvasStyles","css","createRectSnapshot","rect","_RCVirtualCanvas","LitElement","time","event","entries","entry","devicePixelBoxSize","val","oldValue","e","el","$canvas","error","x","y","options","clientX","clientY","canvasViewportRect","clientToContentScaleX","clientToContentScaleY","reason","cssWidth","cssHeight","contentPoint","$node","changed","width","height","fallbackWidth","fallbackHeight","canvasCssWidth","canvasCssHeight","html","styleMap","RCVirtualCanvas","__decorateClass","property","query","state"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rc-virtual-canvas-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCVirtualCanvas } from './index.js';\n\ncustomElements.get('rc-virtual-canvas')
|
|
1
|
+
{"version":3,"file":"rc-virtual-canvas-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCVirtualCanvas } from './index.js';\n\ncustomElements.get('rc-virtual-canvas') ||\n customElements.define('rc-virtual-canvas', RCVirtualCanvas);\n\nexport * from './index.js';\n"],"names":["RCVirtualCanvas"],"mappings":";AAEA,eAAe,IAAI,mBAAmB,KACpC,eAAe,OAAO,qBAAqBA,CAAe;"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './rc-virtual-canvas';
|
|
1
|
+
export * from './rc-virtual-canvas.js';
|
|
@@ -48,9 +48,9 @@ export type RCVirtualCanvasPointerInit = {
|
|
|
48
48
|
clientX: number;
|
|
49
49
|
/** Browser client y coordinate from the source event */
|
|
50
50
|
clientY: number;
|
|
51
|
-
/** Content x coordinate
|
|
51
|
+
/** Content x coordinate in CSS pixels */
|
|
52
52
|
contentX: number;
|
|
53
|
-
/** Content y coordinate
|
|
53
|
+
/** Content y coordinate in CSS pixels */
|
|
54
54
|
contentY: number;
|
|
55
55
|
/** Frozen viewport snapshot at the moment the pointer event fired */
|
|
56
56
|
viewRect: RCVirtualCanvasViewRect;
|
|
@@ -119,6 +119,7 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
119
119
|
static styles: import('lit').CSSResult[];
|
|
120
120
|
protected _rafHandle: number;
|
|
121
121
|
protected _pendingRenderReason?: RCVirtualCanvasRenderReason;
|
|
122
|
+
protected firstUpdated(): void;
|
|
122
123
|
protected readonly _handledPointerEvents: WeakSet<Event>;
|
|
123
124
|
protected readonly _boundUpdate: (time: DOMHighResTimeStamp) => void;
|
|
124
125
|
protected readonly _boundPointerEvent: (event: PointerEvent | MouseEvent) => void;
|
|
@@ -179,25 +180,25 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
179
180
|
/**
|
|
180
181
|
* Scrolls so the content coordinate is at the viewport origin.
|
|
181
182
|
*
|
|
182
|
-
* @param x -
|
|
183
|
-
* @param y -
|
|
184
|
-
* @param options -
|
|
183
|
+
* @param x - content x coordinate in CSS pixels
|
|
184
|
+
* @param y - content y coordinate in CSS pixels
|
|
185
|
+
* @param options - native scroll options passed to scrollTo
|
|
185
186
|
*/
|
|
186
187
|
scrollToContent(x: number, y: number, options?: ScrollOptions): void;
|
|
187
188
|
/**
|
|
188
189
|
* Scrolls so the content coordinate is centered in the viewport.
|
|
189
190
|
*
|
|
190
|
-
* @param x -
|
|
191
|
-
* @param y -
|
|
192
|
-
* @param options -
|
|
191
|
+
* @param x - content x coordinate in CSS pixels
|
|
192
|
+
* @param y - content y coordinate in CSS pixels
|
|
193
|
+
* @param options - native scroll options passed to scrollTo
|
|
193
194
|
*/
|
|
194
195
|
centerOnContent(x: number, y: number, options?: ScrollOptions): void;
|
|
195
196
|
/**
|
|
196
|
-
* Converts browser client coordinates to content coordinates
|
|
197
|
-
* backing-store
|
|
197
|
+
* Converts browser client coordinates to CSS-pixel content coordinates.
|
|
198
|
+
* Canvas backing-store resolution does not change content coordinates.
|
|
198
199
|
*
|
|
199
|
-
* @param clientX -
|
|
200
|
-
* @param clientY -
|
|
200
|
+
* @param clientX - browser client x coordinate (e.g. from a pointer event)
|
|
201
|
+
* @param clientY - browser client y coordinate
|
|
201
202
|
*
|
|
202
203
|
* @example
|
|
203
204
|
* vc.addEventListener('pointerdown', (e) => {
|
|
@@ -212,13 +213,12 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
212
213
|
/**
|
|
213
214
|
* Converts content coordinates back to browser client coordinates.
|
|
214
215
|
*
|
|
215
|
-
* @param x -
|
|
216
|
-
* @param y -
|
|
216
|
+
* @param x - content x coordinate in CSS pixels
|
|
217
|
+
* @param y - content y coordinate in CSS pixels
|
|
217
218
|
*
|
|
218
219
|
* @example
|
|
219
220
|
* const { x, y } = vc.contentToClient(contentX, contentY);
|
|
220
|
-
*
|
|
221
|
-
* tooltip.style.top = `${y}px`;
|
|
221
|
+
* const elementAtPoint = document.elementFromPoint(x, y);
|
|
222
222
|
*/
|
|
223
223
|
contentToClient(x: number, y: number): Readonly<{
|
|
224
224
|
x: number;
|
|
@@ -231,14 +231,15 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
231
231
|
* schedules renders automatically; calling this with reason `'animation-frame'`
|
|
232
232
|
* is a no-op when `renderMode` is `'viewport-change'`.
|
|
233
233
|
*
|
|
234
|
-
* @param reason -
|
|
234
|
+
* @param reason - render reason reported in the event detail
|
|
235
235
|
*/
|
|
236
236
|
requestRender(reason?: RCVirtualCanvasRenderReason): void;
|
|
237
237
|
/**
|
|
238
238
|
* Ratio of canvas backing-store pixels to CSS pixels along the x-axis.
|
|
239
239
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
240
|
+
* Use as the x-scale factor in `ctx.scale()` to draw at CSS pixel resolution.
|
|
241
|
+
* When `autoResizeCanvas` is true, CSS zoom changes this ratio along with
|
|
242
|
+
* the backing-store resolution.
|
|
242
243
|
*
|
|
243
244
|
* @example
|
|
244
245
|
* vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {
|
|
@@ -252,8 +253,8 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
252
253
|
/**
|
|
253
254
|
* Ratio of canvas backing-store pixels to CSS pixels along the y-axis.
|
|
254
255
|
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
256
|
+
* Use as the y-scale factor in `ctx.scale()` to draw at CSS pixel resolution.
|
|
257
|
+
* CSS zoom can make this ratio differ from `devicePixelRatio`.
|
|
257
258
|
*/
|
|
258
259
|
get canvasScaleY(): number;
|
|
259
260
|
/** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */
|
|
@@ -262,7 +263,7 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
262
263
|
/**
|
|
263
264
|
* RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.
|
|
264
265
|
*
|
|
265
|
-
* @param time -
|
|
266
|
+
* @param time - high-resolution timestamp from `requestAnimationFrame`
|
|
266
267
|
*/
|
|
267
268
|
protected _update(time: DOMHighResTimeStamp): void;
|
|
268
269
|
/** Registers pointer event listeners and starts rendering in continuous mode */
|
|
@@ -276,8 +277,10 @@ export declare class RCVirtualCanvas extends LitElement {
|
|
|
276
277
|
protected _getCanvasClientRect(): DOMRect;
|
|
277
278
|
protected _getMeasuredCanvasWidth(fallbackWidth: number): number;
|
|
278
279
|
protected _getMeasuredCanvasHeight(fallbackHeight: number): number;
|
|
279
|
-
protected
|
|
280
|
-
protected
|
|
281
|
-
|
|
280
|
+
protected _getCanvasCssWidth(): number;
|
|
281
|
+
protected _getCanvasCssHeight(): number;
|
|
282
|
+
protected _getClientToContentScaleX(canvasViewportRect: DOMRect): number;
|
|
283
|
+
protected _getClientToContentScaleY(canvasViewportRect: DOMRect): number;
|
|
284
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
282
285
|
}
|
|
283
286
|
export default RCVirtualCanvas;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-virtual-canvas-BSpF0tcY.js","sources":["../src/rc-virtual-canvas.styles.ts","../src/rc-virtual-canvas.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const virtualCanvasStyles = css`\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n :host {\n position: relative;\n display: block;\n width: max-content;\n line-height: 0; /* remove extra space under slotted <canvas> element(s) */\n }\n\n :host([hidden]) {\n display: none;\n }\n\n #root {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n overflow: auto;\n scrollbar-width: var(--rc-virtual-canvas-scrollbar-width, thin);\n }\n\n #root::-webkit-scrollbar {\n width: var(--rc-virtual-canvas-scrollbar-size, auto);\n height: var(--rc-virtual-canvas-scrollbar-size, auto);\n }\n\n #root::-webkit-scrollbar-thumb {\n background: var(--rc-virtual-canvas-scrollbar-thumb-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-button {\n background: var(--rc-virtual-canvas-scrollbar-button-background, ButtonFace);\n }\n\n #root::-webkit-scrollbar-track {\n background: var(--rc-virtual-canvas-scrollbar-track-background, Canvas);\n }\n\n #placeholder {\n pointer-events: none;\n }\n\n #overlay {\n position: sticky;\n left: 0;\n top: 0;\n z-index: 1;\n display: block;\n width: 100%;\n height: 0;\n pointer-events: none;\n }\n\n ::slotted([slot='overlay']) {\n pointer-events: auto;\n }\n\n ::slotted(canvas) {\n image-rendering: var(--rc-virtual-canvas-image-rendering, auto);\n }\n`;\n\nexport default virtualCanvasStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport virtualCanvasStyles from './rc-virtual-canvas.styles';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-virtual-canvas': RCVirtualCanvas;\n }\n\n interface HTMLElementEventMap {\n 'rc-virtual-canvas-render': CustomEvent<RCVirtualCanvasRenderInit>;\n 'rc-virtual-canvas-pointer': CustomEvent<RCVirtualCanvasPointerInit>;\n }\n}\n\n/**\n * Scrollable virtual canvas for rendering large coordinate-space content.\n *\n * `x` and `y` are scroll offsets in CSS pixels; `width` and `height` are the canvas\n * backing-store dimensions in device pixels (DPR-accurate when `autoResizeCanvas` is `true`).\n */\nexport type RCVirtualCanvasViewRect = Readonly<{\n /** Scroll offset x in content space (CSS px) */\n x: number;\n\n /** Scroll offset y in content space (CSS px) */\n y: number;\n\n /** Visible width in device pixels */\n width: number;\n\n /** Visible height in device pixels */\n height: number;\n}>;\n\n/** Controls when `rc-virtual-canvas-render` events are dispatched */\nexport type RCVirtualCanvasRenderMode = 'continuous' | 'viewport-change' | 'manual';\n\n/** Identifies what triggered a render event */\nexport type RCVirtualCanvasRenderReason = 'animation-frame' | 'viewport-change' | 'manual';\n\n/** Content-space coordinate pair returned by coordinate-conversion methods */\nexport type RCVirtualCanvasPoint = Readonly<{\n /** Content space x coordinate in CSS pixels */\n x: number;\n\n /** Content space y coordinate in CSS pixels */\n y: number;\n}>;\n\n/**\n * Detail shape for `rc-virtual-canvas-pointer` events.\n *\n * Carries the source event's coordinates in both browser-client and content space,\n * along with all modifier key state.\n */\nexport type RCVirtualCanvasPointerInit = {\n /** DOM event type (e.g. `'pointerdown'`, `'click'`) */\n type: string;\n\n /** Browser client x coordinate from the source event */\n clientX: number;\n\n /** Browser client y coordinate from the source event */\n clientY: number;\n\n /** Content x coordinate mapped through the current backing-store scale */\n contentX: number;\n\n /** Content y coordinate mapped through the current backing-store scale */\n contentY: number;\n\n /** Frozen viewport snapshot at the moment the pointer event fired */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Mouse button index from the source event */\n button: number;\n\n /** Active button bitmask from the source event */\n buttons: number;\n\n /** Whether the Alt key was held */\n altKey: boolean;\n\n /** Whether the Ctrl key was held */\n ctrlKey: boolean;\n\n /** Whether the Shift key was held */\n shiftKey: boolean;\n\n /** Whether the Meta key was held */\n metaKey: boolean;\n\n /** The original DOM event that produced this detail */\n sourceEvent: PointerEvent | MouseEvent;\n};\n\n/** CSS `image-rendering` value applied to the slotted canvas */\nexport type RCVirtualCanvasImageRendering = 'auto' | 'crisp-edges' | 'pixelated';\n\n/** Detail shape for `rc-virtual-canvas-render` events */\nexport type RCVirtualCanvasRenderInit = {\n /** High-resolution timestamp from `requestAnimationFrame` */\n time: DOMHighResTimeStamp;\n\n /** What triggered this render */\n reason: RCVirtualCanvasRenderReason;\n\n /** Frozen snapshot of the viewport for this frame */\n viewRect: RCVirtualCanvasViewRect;\n\n /** Frozen snapshot of the full content bounds for this frame */\n contentRect: RCVirtualCanvasViewRect;\n};\n\nfunction createRectSnapshot(rect: RCVirtualCanvasViewRect) {\n return Object.freeze({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n}\n\n/**\n * A scrollable virtual canvas component.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-virtual-canvas rc-virtual-canvas docs}\n *\n * @slot - The HTMLCanvasElement\n * @slot overlay - Optional viewport-positioned content rendered inside the\n * scroll container above the canvas.\n *\n * @fires rc-virtual-canvas-render - Fires with viewport data when the canvas should redraw.\n * @fires rc-virtual-canvas-pointer - Fires pointer/mouse input mapped to virtual content coordinates.\n *\n * @csspart scroller - Internal scroll container that owns the virtual content scroll range.\n * @csspart overlay - Viewport-positioned overlay container rendered inside the scroll container.\n *\n * @attr content-width - Total pixel width of the virtual content.\n * @attr content-height - Total pixel height of the virtual content.\n * @attr auto-resize-canvas - Keep the slotted canvas backing store aligned to the viewport.\n * @attr render-mode - Controls when render events are dispatched.\n * @attr image-rendering - Convenience `image-rendering` value applied to the slotted canvas.\n *\n * @cssprop [--rc-virtual-canvas-scrollbar-width=thin] - `scrollbar-width` of the internal\n * scroll container.\n * @cssprop [--rc-virtual-canvas-scrollbar-size=auto] - WebKit scrollbar thickness.\n * @cssprop [--rc-virtual-canvas-scrollbar-thumb-background=ButtonFace] - WebKit scrollbar\n * thumb color.\n * @cssprop [--rc-virtual-canvas-scrollbar-button-background=ButtonFace] - WebKit scrollbar\n * button color.\n * @cssprop [--rc-virtual-canvas-scrollbar-track-background=Canvas] - WebKit scrollbar\n * track color.\n * @cssprop [--rc-virtual-canvas-image-rendering=auto] - `image-rendering` applied to the\n * slotted canvas; kept in sync with the `imageRendering` property.\n */\nexport class RCVirtualCanvas extends LitElement {\n static styles = [virtualCanvasStyles];\n\n protected _rafHandle: number = 0;\n protected _pendingRenderReason?: RCVirtualCanvasRenderReason;\n protected readonly _handledPointerEvents = new WeakSet<Event>();\n\n // Stored bound reference so the same closure is used for scheduling and\n // cancellation — `bind()` returns a new function every call.\n protected readonly _boundUpdate = (time: DOMHighResTimeStamp) => this._update(time);\n\n protected readonly _boundPointerEvent = (event: PointerEvent | MouseEvent) =>\n this._onPointerEvent(event);\n\n /** Pixel width of the virtual content */\n @property({ type: Number, attribute: 'content-width' })\n set contentWidth(val: number) {\n const oldValue = this._contentWidth;\n\n this._contentWidth = val;\n\n this._contentRect.width = this._contentWidth;\n this.requestUpdate('contentWidth', oldValue);\n this._scheduleRender('viewport-change');\n }\n get contentWidth() {\n return this._contentWidth;\n }\n private _contentWidth: number = 0;\n\n /** Pixel height of the virtual content */\n @property({ type: Number, attribute: 'content-height' })\n set contentHeight(val: number) {\n const oldValue = this._contentHeight;\n\n this._contentHeight = val;\n\n this._contentRect.height = this._contentHeight;\n this.requestUpdate('contentHeight', oldValue);\n this._scheduleRender('viewport-change');\n }\n get contentHeight() {\n return this._contentHeight;\n }\n private _contentHeight: number = 0;\n\n /** When true, keep the slotted canvas backing store aligned to the viewport. */\n @property({ attribute: 'auto-resize-canvas', type: Boolean })\n autoResizeCanvas: boolean = true;\n\n /** Controls when render events are dispatched. */\n @property({ attribute: 'render-mode' })\n renderMode: RCVirtualCanvasRenderMode = 'continuous';\n\n /** Convenience image-rendering value applied to the slotted canvas. */\n @property({ attribute: 'image-rendering' })\n imageRendering: RCVirtualCanvasImageRendering = 'auto';\n\n /** Shadow DOM scroll container that owns pointer interaction and native scrolling */\n @query('#root', true)\n protected _$root!: HTMLDivElement;\n\n /** Absolutely-positioned div that establishes the virtual scroll range */\n @query('#placeholder', true)\n protected _$placeholder!: HTMLDivElement;\n\n /** Currently-tracked slotted canvas element; `null` when no canvas is slotted */\n @state()\n protected _$canvas: HTMLCanvasElement | null = null;\n\n /** Mutable current-frame viewport geometry; call `getViewRect()` for a frozen snapshot */\n @state()\n protected _viewRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Mutable content bounds; updated when `contentWidth` or `contentHeight` change */\n @state()\n protected _contentRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n /** Watches the slotted canvas for DPR-accurate dimension changes */\n protected _resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n for (const entry of entries) {\n const devicePixelBoxSize = Array.isArray(entry.devicePixelContentBoxSize)\n ? entry.devicePixelContentBoxSize[0]\n : entry.devicePixelContentBoxSize;\n\n this._viewRect.width = this._getMeasuredCanvasWidth(\n devicePixelBoxSize?.inlineSize ??\n Math.round(entry.contentRect.width * window.devicePixelRatio),\n );\n\n this._viewRect.height = this._getMeasuredCanvasHeight(\n devicePixelBoxSize?.blockSize ??\n Math.round(entry.contentRect.height * window.devicePixelRatio),\n );\n\n this._syncCanvasBackingStore();\n this._scheduleRender('viewport-change');\n }\n });\n\n /** Reads scroll position from the root container and schedules a render */\n protected _onScroll() {\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n\n this._scheduleRender('viewport-change');\n }\n\n /** Replaces canvas tracking and re-registers the resize observer when slot content changes */\n protected _onSlotChange(e: Event) {\n this._resizeObserver.disconnect();\n\n this._$canvas =\n (e.currentTarget as HTMLSlotElement)\n .assignedElements()\n .filter((el) => el instanceof HTMLCanvasElement)\n [0] ?? null;\n\n if (this._$canvas != null) {\n this._viewRect = {\n x: this._$root.scrollLeft ?? 0,\n y: this._$root.scrollTop ?? 0,\n width: this._getMeasuredCanvasWidth(this._$canvas.clientWidth),\n height: this._getMeasuredCanvasHeight(this._$canvas.clientHeight),\n };\n\n this._syncCanvasBackingStore();\n this._observeCanvasResize(this._$canvas);\n\n this._scheduleRender('viewport-change');\n }\n }\n\n /** Observes canvas size with DPR-accurate boxes when the browser supports them */\n protected _observeCanvasResize($canvas: HTMLCanvasElement) {\n try {\n this._resizeObserver.observe($canvas, {\n box: 'device-pixel-content-box',\n });\n } catch (error) {\n if (!(error instanceof TypeError)) {\n throw error;\n }\n\n this._resizeObserver.observe($canvas);\n }\n }\n\n /**\n * Returns a frozen snapshot of the current viewport rectangle.\n *\n * Safe to keep between frames — the returned object will not be mutated\n * by future scroll or resize work.\n */\n getViewRect() {\n return createRectSnapshot(this._viewRect);\n }\n\n /**\n * Scrolls so the content coordinate is at the viewport origin.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n scrollToContent(x: number, y: number, options: ScrollOptions = {}) {\n this._$root.scrollTo({\n ...options,\n left: x,\n top: y,\n });\n\n this._viewRect.x = this._$root.scrollLeft;\n this._viewRect.y = this._$root.scrollTop;\n this._scheduleRender('viewport-change');\n }\n\n /**\n * Scrolls so the content coordinate is centered in the viewport.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n * @param options - Native scroll options passed to scrollTo\n */\n centerOnContent(x: number, y: number, options: ScrollOptions = {}) {\n this.scrollToContent(\n x - this._$root.clientWidth * 0.5,\n y - this._$root.clientHeight * 0.5,\n options,\n );\n }\n\n /**\n * Converts browser client coordinates to content coordinates using the current\n * backing-store scale.\n *\n * @param clientX - Browser client x coordinate (e.g. from a pointer event)\n * @param clientY - Browser client y coordinate\n *\n * @example\n * vc.addEventListener('pointerdown', (e) => {\n * const { x, y } = vc.clientToContent(e.clientX, e.clientY);\n * placeMarkerAt(x, y);\n * });\n */\n clientToContent(clientX: number, clientY: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: this._viewRect.x + (clientX - canvasRect.left) * scaleX,\n y: this._viewRect.y + (clientY - canvasRect.top) * scaleY,\n });\n }\n\n /**\n * Converts content coordinates back to browser client coordinates.\n *\n * @param x - Content x coordinate in CSS pixels\n * @param y - Content y coordinate in CSS pixels\n *\n * @example\n * const { x, y } = vc.contentToClient(contentX, contentY);\n * tooltip.style.left = `${x}px`;\n * tooltip.style.top = `${y}px`;\n */\n contentToClient(x: number, y: number) {\n const canvasRect = this._getCanvasClientRect();\n const scaleX = this._getViewportScaleX(canvasRect);\n const scaleY = this._getViewportScaleY(canvasRect);\n\n return Object.freeze({\n x: canvasRect.left + (x - this._viewRect.x) / scaleX,\n y: canvasRect.top + (y - this._viewRect.y) / scaleY,\n });\n }\n\n /**\n * Queues a render event on the next animation frame.\n *\n * Required when `renderMode` is `'manual'`. In other modes the component\n * schedules renders automatically; calling this with reason `'animation-frame'`\n * is a no-op when `renderMode` is `'viewport-change'`.\n *\n * @param reason - Render reason reported in the event detail\n */\n requestRender(reason: RCVirtualCanvasRenderReason = 'manual') {\n this._scheduleRender(reason);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the x-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the x-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n *\n * @example\n * vc.addEventListener('rc-virtual-canvas-render', ({ detail: { viewRect } }) => {\n * ctx.save();\n * ctx.scale(vc.canvasScaleX, vc.canvasScaleY);\n * drawScene(ctx, viewRect);\n * ctx.restore();\n * });\n */\n get canvasScaleX(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleX(canvasRect);\n }\n\n /**\n * Ratio of canvas backing-store pixels to CSS pixels along the y-axis.\n *\n * Equals `devicePixelRatio` when `autoResizeCanvas` is `true`. Use as the y-scale\n * factor in `ctx.scale()` to draw at CSS pixel resolution.\n */\n get canvasScaleY(): number {\n const canvasRect = this._getCanvasClientRect();\n\n return this._getViewportScaleY(canvasRect);\n }\n\n /** Maps pointer and mouse events to content coordinates and dispatches `rc-virtual-canvas-pointer` */\n protected _onPointerEvent(event: PointerEvent | MouseEvent) {\n if (this._handledPointerEvents.has(event)) {\n return;\n }\n\n if (this._isOverlayEvent(event)) {\n return;\n }\n\n this._handledPointerEvents.add(event);\n\n const contentPoint = this.clientToContent(event.clientX, event.clientY);\n\n const shouldContinue = this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasPointerInit>('rc-virtual-canvas-pointer', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: {\n type: event.type,\n clientX: event.clientX,\n clientY: event.clientY,\n contentX: contentPoint.x,\n contentY: contentPoint.y,\n viewRect: createRectSnapshot(this._viewRect),\n button: event.button,\n buttons: event.buttons,\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n shiftKey: event.shiftKey,\n metaKey: event.metaKey,\n sourceEvent: event,\n },\n }),\n );\n\n if (!shouldContinue) event.preventDefault();\n }\n\n protected _isOverlayEvent(event: Event): boolean {\n return event\n .composedPath()\n .some(($node) => $node instanceof HTMLSlotElement && $node.name === 'overlay');\n }\n\n /**\n * RAF callback. Dispatches `rc-virtual-canvas-render` and re-schedules in continuous mode.\n *\n * @param time - High-resolution timestamp from `requestAnimationFrame`\n */\n protected _update(time: DOMHighResTimeStamp) {\n this._rafHandle = 0;\n\n if (!this.isConnected || this._$canvas == null) {\n return;\n }\n\n const reason =\n this._pendingRenderReason ??\n (this.renderMode === 'continuous' ? 'animation-frame' : 'manual');\n\n this._pendingRenderReason = undefined;\n\n this.dispatchEvent(\n new CustomEvent<RCVirtualCanvasRenderInit>('rc-virtual-canvas-render', {\n bubbles: true,\n composed: true,\n detail: {\n time,\n reason,\n viewRect: createRectSnapshot(this._viewRect),\n contentRect: createRectSnapshot(this._contentRect),\n },\n }),\n );\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Registers pointer event listeners and starts rendering in continuous mode */\n override connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('pointerdown', this._boundPointerEvent);\n this.addEventListener('pointermove', this._boundPointerEvent);\n this.addEventListener('pointerup', this._boundPointerEvent);\n this.addEventListener('click', this._boundPointerEvent);\n this.addEventListener('dblclick', this._boundPointerEvent);\n this.addEventListener('contextmenu', this._boundPointerEvent);\n\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n }\n\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n }\n }\n\n /** Cancels any pending animation frame, disconnects the resize observer, and removes pointer listeners */\n override disconnectedCallback() {\n super.disconnectedCallback();\n\n cancelAnimationFrame(this._rafHandle);\n this._rafHandle = 0;\n this._resizeObserver.disconnect();\n\n this.removeEventListener('pointerdown', this._boundPointerEvent);\n this.removeEventListener('pointermove', this._boundPointerEvent);\n this.removeEventListener('pointerup', this._boundPointerEvent);\n this.removeEventListener('click', this._boundPointerEvent);\n this.removeEventListener('dblclick', this._boundPointerEvent);\n this.removeEventListener('contextmenu', this._boundPointerEvent);\n }\n\n /** Reacts to `renderMode`, `autoResizeCanvas`, and `imageRendering` property changes */\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('renderMode')) {\n if (this.renderMode === 'continuous') {\n this._scheduleRender('animation-frame');\n } else if (this._pendingRenderReason === 'animation-frame') {\n if (this._rafHandle) {\n cancelAnimationFrame(this._rafHandle);\n\n this._rafHandle = 0;\n }\n\n this._pendingRenderReason = undefined;\n } else if (this.renderMode === 'viewport-change') {\n this._scheduleRender('viewport-change');\n }\n }\n\n if (changed.has('autoResizeCanvas')) {\n this._syncCanvasBackingStore();\n }\n\n if (changed.has('imageRendering')) {\n this.style.setProperty('--rc-virtual-canvas-image-rendering', this.imageRendering);\n }\n }\n\n protected _scheduleRender(reason: RCVirtualCanvasRenderReason) {\n if (this.renderMode === 'manual' && reason !== 'manual') {\n return;\n }\n\n if (this.renderMode === 'viewport-change' && reason === 'animation-frame') {\n return;\n }\n\n this._pendingRenderReason = reason;\n\n if (!this.isConnected || this._rafHandle) {\n return;\n }\n\n this._rafHandle = window.requestAnimationFrame(this._boundUpdate);\n }\n\n protected _syncCanvasBackingStore() {\n if (!this.autoResizeCanvas || this._$canvas == null) {\n return;\n }\n\n const width = Math.max(0, Math.round(this._viewRect.width));\n const height = Math.max(0, Math.round(this._viewRect.height));\n\n if (this._$canvas.width !== width) {\n this._$canvas.width = width;\n }\n\n if (this._$canvas.height !== height) {\n this._$canvas.height = height;\n }\n }\n\n protected _getCanvasClientRect() {\n if (this._$canvas == null) {\n return this.getBoundingClientRect();\n }\n\n return this._$canvas.getBoundingClientRect();\n }\n\n protected _getMeasuredCanvasWidth(fallbackWidth: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.width > 0) {\n return this._$canvas.width;\n }\n\n return fallbackWidth;\n }\n\n protected _getMeasuredCanvasHeight(fallbackHeight: number) {\n if (!this.autoResizeCanvas && this._$canvas && this._$canvas.height > 0) {\n return this._$canvas.height;\n }\n\n return fallbackHeight;\n }\n\n protected _getViewportScaleX(canvasRect: DOMRect) {\n return canvasRect.width > 0 ? this._viewRect.width / canvasRect.width : 1;\n }\n\n protected _getViewportScaleY(canvasRect: DOMRect) {\n return canvasRect.height > 0 ? this._viewRect.height / canvasRect.height : 1;\n }\n\n render() {\n return html`\n <div\n id=\"root\"\n part=\"scroller\"\n @scroll=${this._onScroll}\n @pointerdown=${this._onPointerEvent}\n @pointermove=${this._onPointerEvent}\n @pointerup=${this._onPointerEvent}\n @click=${this._onPointerEvent}\n @dblclick=${this._onPointerEvent}\n @contextmenu=${this._onPointerEvent}\n >\n <div id=\"overlay\" part=\"overlay\">\n <slot name=\"overlay\"></slot>\n </div>\n\n <div\n id=\"placeholder\"\n style=${styleMap({\n width: `${this.contentWidth}px`,\n height: `${this.contentHeight}px`,\n })}\n ></div>\n </div>\n\n <slot @slotchange=${this._onSlotChange}></slot>\n `;\n }\n}\n\nexport default RCVirtualCanvas;\n"],"names":["virtualCanvasStyles","css","createRectSnapshot","rect","_RCVirtualCanvas","LitElement","time","event","entries","entry","devicePixelBoxSize","val","oldValue","e","el","$canvas","error","x","y","options","clientX","clientY","canvasRect","scaleX","scaleY","reason","contentPoint","$node","changed","width","height","fallbackWidth","fallbackHeight","html","styleMap","RCVirtualCanvas","__decorateClass","property","query","state"],"mappings":"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"}
|
|
File without changes
|