hdrify-react 1.3.0 โ 2.1.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/README.md +57 -29
- package/dist/HdrifyCanvas.d.ts +31 -4
- package/dist/HdrifyCanvas.d.ts.map +1 -1
- package/dist/HdrifyCanvas.js +197 -38
- package/dist/HdrifyCanvas.js.map +1 -1
- package/dist/ImageViewer.d.ts +86 -0
- package/dist/ImageViewer.d.ts.map +1 -0
- package/dist/ImageViewer.js +241 -0
- package/dist/ImageViewer.js.map +1 -0
- package/dist/capture.d.ts +22 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +62 -0
- package/dist/capture.js.map +1 -0
- package/dist/decode.d.ts +7 -0
- package/dist/decode.d.ts.map +1 -0
- package/dist/decode.js +25 -0
- package/dist/decode.js.map +1 -0
- package/dist/display.d.ts +17 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +37 -0
- package/dist/display.js.map +1 -0
- package/dist/element.d.ts +51 -0
- package/dist/element.d.ts.map +1 -0
- package/dist/element.js +215 -0
- package/dist/element.js.map +1 -0
- package/dist/image-viewer.js +174 -0
- package/dist/image-viewer.js.map +7 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +19 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +47 -0
- package/dist/progress.js.map +1 -0
- package/dist/readiness.d.ts +15 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +46 -0
- package/dist/readiness.js.map +1 -0
- package/dist/styles.d.ts +6 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +84 -0
- package/dist/styles.js.map +1 -0
- package/dist/webgpuDisplay.d.ts +4 -0
- package/dist/webgpuDisplay.d.ts.map +1 -0
- package/dist/webgpuDisplay.js +208 -0
- package/dist/webgpuDisplay.js.map +1 -0
- package/package.json +42 -13
package/README.md
CHANGED
|
@@ -1,18 +1,34 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://hdrify.ben3d.ca" target="_blank" rel="noopener noreferrer">
|
|
3
|
+
<img alt="hdrify-react logo" src="https://raw.githubusercontent.com/bhouston/hdrify/main/packages/hdrify-vscode-extension/images/icon.png" height="96">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
<br/>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://npmjs.com/package/hdrify-react"><img src="https://img.shields.io/npm/v/hdrify-react.svg" alt="npm package"></a>
|
|
9
|
+
<a href="https://www.npmtrends.com/hdrify-react"><img src="https://img.shields.io/npm/dw/hdrify-react.svg" alt="npm downloads"></a>
|
|
10
|
+
<a href="https://codecov.io/gh/bhouston/hdrify"><img src="https://codecov.io/gh/bhouston/hdrify/branch/main/graph/badge.svg" alt="coverage"></a>
|
|
11
|
+
<a href="https://discord.gg/5J5Ur3F6Z2"><img src="https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord" alt="discord chat"></a>
|
|
12
|
+
<a href="https://hdrify.ben3d.ca"><img src="https://img.shields.io/badge/docs-read-blue?style=flat" alt="documentation"></a>
|
|
13
|
+
</p>
|
|
14
|
+
<br/>
|
|
15
|
+
|
|
1
16
|
# hdrify-react
|
|
2
17
|
|
|
3
|
-
|
|
18
|
+
> Display HDR images in React with configurable tone mapping.
|
|
4
19
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
20
|
+
- ๐ผ๏ธ `<image-viewer>` Web Component and `ImageViewer` React Component
|
|
21
|
+
- โ๏ธ React Canvas Component
|
|
22
|
+
- ๐จ Four Tone Mappers
|
|
23
|
+
- โ๏ธ Adjustable Exposure
|
|
24
|
+
- ๐ผ๏ธ Works With hdrify Readers
|
|
25
|
+
- ๐ท Typed Props
|
|
10
26
|
|
|
11
|
-
React component for displaying HDR images from [hdrify](https://www.npmjs.com/package/hdrify). Accepts `HdrifyImage` (returned by `readHdr`, `readExr`, `readJpegGainMap`) and renders with configurable tone mapping and exposure.
|
|
27
|
+
React component for displaying HDR images from [hdrify](https://www.npmjs.com/package/hdrify). Accepts `HdrifyImage` (returned by `readHdr`, `readExr`, `readJxl`, `readJpegGainMap`) and renders with configurable tone mapping and exposure.
|
|
12
28
|
|
|
13
29
|
**Related packages:** [hdrify](https://www.npmjs.com/package/hdrify) (core library) ยท [hdrify-cli](https://www.npmjs.com/package/hdrify-cli) (CLI tool)
|
|
14
30
|
|
|
15
|
-
|
|
31
|
+
Try the **[online demo](https://hdrify.ben3d.ca/demo/)** โ HDR, EXR, and Ultra HDR viewer and converter built with this component; try it in your browser.
|
|
16
32
|
|
|
17
33
|
## Installation
|
|
18
34
|
|
|
@@ -28,18 +44,39 @@ import { readExr } from 'hdrify';
|
|
|
28
44
|
|
|
29
45
|
const hdrifyImage: HdrifyImage = readExr(buffer);
|
|
30
46
|
|
|
31
|
-
<HdrifyCanvas hdrifyImage={hdrifyImage}
|
|
47
|
+
<HdrifyCanvas hdrifyImage={hdrifyImage} exposure={1.0} className="max-w-full" />;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
See [`HdrifyCanvas`](https://hdrify.ben3d.ca/docs/api/react/functions/HdrifyCanvas/) and [`HdrifyCanvasProps`](https://hdrify.ben3d.ca/docs/api/react/interfaces/HdrifyCanvasProps/) for rendering behavior and props.
|
|
51
|
+
|
|
52
|
+
### Image viewer
|
|
53
|
+
|
|
54
|
+
`ImageViewer` loads an EXR, HDR, JPEG XL or gain map JPEG (detected from its content, gzip allowed) and adds an options panel and an optional vertical exposure slider:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { ImageViewer } from 'hdrify-react';
|
|
58
|
+
|
|
59
|
+
<ImageViewer src="/images/memorial.exr" exposureControl toneMapping="agx" style={{ height: 600 }} />;
|
|
32
60
|
```
|
|
33
61
|
|
|
34
|
-
|
|
62
|
+
The same viewer is available as a web component for plain HTML and other frameworks:
|
|
35
63
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
```html
|
|
65
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/hdrify-react/dist/image-viewer.js"></script>
|
|
66
|
+
<image-viewer src="/images/memorial.exr" exposure-control></image-viewer>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
API reference: [`ImageViewer`](https://hdrify.ben3d.ca/docs/api/react/functions/ImageViewer/) ยท [`ImageViewerProps`](https://hdrify.ben3d.ca/docs/api/react/interfaces/ImageViewerProps/) ยท [`ImageViewerHandle`](https://hdrify.ben3d.ca/docs/api/react/interfaces/ImageViewerHandle/).
|
|
70
|
+
|
|
71
|
+
With a bundler, `import 'hdrify-react/element'` to register the web component.
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
Full documentation for the React components is available [on the HDRify documentation website](https://hdrify.ben3d.ca/docs/react/). See the [React guide](https://hdrify.ben3d.ca/docs/react/) and [`<image-viewer>` documentation](https://hdrify.ben3d.ca/docs/image-viewer/) for loading, capture, attributes, events, and theming.
|
|
76
|
+
|
|
77
|
+
## Contribution
|
|
78
|
+
|
|
79
|
+
See [Contributing Guide](https://github.com/bhouston/hdrify/blob/main/CONTRIBUTING.md).
|
|
43
80
|
|
|
44
81
|
## License
|
|
45
82
|
|
|
@@ -47,15 +84,6 @@ MIT
|
|
|
47
84
|
|
|
48
85
|
## Author
|
|
49
86
|
|
|
50
|
-
[Ben Houston](https://ben3d.ca), Sponsored by [Land of Assets](https://landofassets.com)
|
|
51
|
-
|
|
52
|
-
[
|
|
53
|
-
[npm-url]: https://www.npmjs.com/package/hdrify-react
|
|
54
|
-
[npm-downloads]: https://img.shields.io/npm/dw/hdrify-react
|
|
55
|
-
[npmtrends-url]: https://www.npmtrends.com/hdrify-react
|
|
56
|
-
[tests-badge]: https://github.com/bhouston/hdrify/workflows/Tests/badge.svg
|
|
57
|
-
[tests-url]: https://github.com/bhouston/hdrify/actions/workflows/test.yml
|
|
58
|
-
[coverage-badge]: https://codecov.io/gh/bhouston/hdrify/branch/main/graph/badge.svg
|
|
59
|
-
[coverage-url]: https://codecov.io/gh/bhouston/hdrify
|
|
60
|
-
[discord-badge]: https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white
|
|
61
|
-
[discord-url]: https://discord.gg/5J5Ur3F6Z2
|
|
87
|
+
[Ben Houston](https://ben3d.ca), Sponsored by [Land of Assets](https://landofassets.com).
|
|
88
|
+
|
|
89
|
+
Compare browser behavior at [hdr-capabilities.ben3d.ca](https://hdr-capabilities.ben3d.ca), maintained in the separate [hdr-capabilities repository](https://github.com/bhouston/hdr-capabilities).
|
package/dist/HdrifyCanvas.d.ts
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { HdrifyImage } from 'hdrify';
|
|
2
2
|
import type * as React from 'react';
|
|
3
|
+
import { type DisplayMode, type ViewerToneMapping } from './display.js';
|
|
3
4
|
export interface HdrifyCanvasProps {
|
|
5
|
+
/** Decoded floating-point RGBA image from a hdrify reader. */
|
|
4
6
|
hdrifyImage: HdrifyImage;
|
|
5
|
-
|
|
7
|
+
/** Omit to use None on HDR displays and Neutral on SDR displays. */
|
|
8
|
+
toneMapping?: ViewerToneMapping;
|
|
9
|
+
/** Linear exposure multiplier: 1 is nominal, 2 adds one stop. */
|
|
6
10
|
exposure: number;
|
|
11
|
+
/** CSS class applied to the canvas wrapper. */
|
|
7
12
|
className?: string;
|
|
8
|
-
/**
|
|
13
|
+
/** Ref to the active canvas, updated when HDR/SDR fallback replaces it. */
|
|
9
14
|
forwardedRef?: React.RefObject<HTMLCanvasElement | null>;
|
|
15
|
+
/** Called after the current image has finished rendering. */
|
|
16
|
+
onDraw?: (image: HdrifyImage, mode: DisplayMode) => void;
|
|
17
|
+
onError?: (error: Error) => void;
|
|
10
18
|
}
|
|
11
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Display a decoded HDR image with exposure and tone mapping.
|
|
21
|
+
* Uses native WebGPU only when an HDR-capable display and extended `rgba16float`
|
|
22
|
+
* presentation succeed. The capability probe caches success or failure per page;
|
|
23
|
+
* each mounted canvas owns its rendering resources. Otherwise a 2D SDR canvas is used.
|
|
24
|
+
* GPU resources are disposed on unmount; device loss falls back to SDR.
|
|
25
|
+
*
|
|
26
|
+
* Omitting `toneMapping` selects None for HDR and Neutral for SDR. Explicit `none`
|
|
27
|
+
* also falls back to Neutral on SDR; other explicit mappers are preserved.
|
|
28
|
+
* Display size follows the viewport and device pixel ratio. Pass a new image object
|
|
29
|
+
* after editing pixels to trigger a redraw. `onDraw` reports a completed render.
|
|
30
|
+
* Use {@link captureImage} for portable SDR export rather than serializing the GPU canvas.
|
|
31
|
+
*
|
|
32
|
+
* @param props - Image, display settings, and rendering callbacks.
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <HdrifyCanvas hdrifyImage={image} exposure={1} toneMapping="agx" />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function HdrifyCanvas(props: HdrifyCanvasProps): React.ReactElement;
|
|
12
39
|
//# sourceMappingURL=HdrifyCanvas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HdrifyCanvas.d.ts","
|
|
1
|
+
{"version":3,"file":"HdrifyCanvas.d.ts","sources":["../src/HdrifyCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAGpC,OAAO,EAAsB,KAAK,WAAW,EAAqB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE/G,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,WAAW,EAAE,WAAW,CAAC;IACzB,oEAAoE;IACpE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACzD,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACzD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAiLzE"}
|
package/dist/HdrifyCanvas.js
CHANGED
|
@@ -1,44 +1,203 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { drawToneMapped } from './capture.js';
|
|
4
|
+
import { resolveToneMapping } from './display.js';
|
|
5
|
+
const CSS = '.hdrify-canvas{display:grid;place-items:center;width:var(--hdrify-image-width);height:auto;aspect-ratio:var(--hdrify-image-aspect);min-height:0;flex:none;margin:auto;min-width:0}.hdrify-canvas>canvas{display:block;dynamic-range-limit:no-limit}';
|
|
6
|
+
/**
|
|
7
|
+
* Display a decoded HDR image with exposure and tone mapping.
|
|
8
|
+
* Uses native WebGPU only when an HDR-capable display and extended `rgba16float`
|
|
9
|
+
* presentation succeed. The capability probe caches success or failure per page;
|
|
10
|
+
* each mounted canvas owns its rendering resources. Otherwise a 2D SDR canvas is used.
|
|
11
|
+
* GPU resources are disposed on unmount; device loss falls back to SDR.
|
|
12
|
+
*
|
|
13
|
+
* Omitting `toneMapping` selects None for HDR and Neutral for SDR. Explicit `none`
|
|
14
|
+
* also falls back to Neutral on SDR; other explicit mappers are preserved.
|
|
15
|
+
* Display size follows the viewport and device pixel ratio. Pass a new image object
|
|
16
|
+
* after editing pixels to trigger a redraw. `onDraw` reports a completed render.
|
|
17
|
+
* Use {@link captureImage} for portable SDR export rather than serializing the GPU canvas.
|
|
18
|
+
*
|
|
19
|
+
* @param props - Image, display settings, and rendering callbacks.
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <HdrifyCanvas hdrifyImage={image} exposure={1} toneMapping="agx" />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function HdrifyCanvas(props) {
|
|
26
|
+
const hostRef = useRef(null);
|
|
5
27
|
const canvasRef = useRef(null);
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
28
|
+
const latest = useRef(props);
|
|
29
|
+
const redraw = useRef(() => { });
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
latest.current = props;
|
|
32
|
+
});
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
redraw.current();
|
|
35
|
+
}, [props.hdrifyImage, props.toneMapping, props.exposure]);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const forwardedRef = props.forwardedRef;
|
|
38
|
+
if (!forwardedRef)
|
|
39
|
+
return undefined;
|
|
40
|
+
// oxlint-disable-next-line react/immutability -- forward the active canvas into the caller-owned ref
|
|
41
|
+
forwardedRef.current = canvasRef.current;
|
|
42
|
+
return () => {
|
|
43
|
+
// oxlint-disable-next-line react/immutability -- clear the caller-owned ref on replacement or unmount
|
|
44
|
+
forwardedRef.current = null;
|
|
45
|
+
};
|
|
46
|
+
}, [props.forwardedRef]);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const host = hostRef.current;
|
|
49
|
+
const view = host.ownerDocument.defaultView;
|
|
50
|
+
const media = view.matchMedia('(dynamic-range: high)');
|
|
51
|
+
let active;
|
|
52
|
+
let canvas;
|
|
53
|
+
let disposed = false;
|
|
54
|
+
let generation = 0;
|
|
55
|
+
let drawRevision = 0;
|
|
56
|
+
let fallbackDrawing = '';
|
|
57
|
+
let fallbackImage;
|
|
58
|
+
const mount = (next) => {
|
|
59
|
+
canvas = next;
|
|
60
|
+
canvasRef.current = canvas;
|
|
61
|
+
// oxlint-disable-next-line react/immutability -- forwarding the internally created canvas
|
|
62
|
+
if (latest.current.forwardedRef)
|
|
63
|
+
latest.current.forwardedRef.current = canvas;
|
|
64
|
+
host.replaceChildren(canvas);
|
|
65
|
+
};
|
|
66
|
+
const draw = () => {
|
|
67
|
+
if (disposed || !active)
|
|
68
|
+
return;
|
|
69
|
+
const display = active;
|
|
70
|
+
const { hdrifyImage: image, toneMapping, exposure, onDraw, onError } = latest.current;
|
|
71
|
+
const mapper = resolveToneMapping(toneMapping, display.mode);
|
|
72
|
+
const revision = ++drawRevision;
|
|
73
|
+
try {
|
|
74
|
+
const scale = Math.min((host.clientWidth || image.width) / image.width, (host.clientHeight || image.height) / image.height);
|
|
75
|
+
const width = Math.max(1, image.width * scale);
|
|
76
|
+
const height = Math.max(1, image.height * scale);
|
|
77
|
+
canvas.style.width = `${width}px`;
|
|
78
|
+
canvas.style.height = `${height}px`;
|
|
79
|
+
display.resize(width, height, view.devicePixelRatio || 1);
|
|
80
|
+
display.draw(image, mapper, exposure);
|
|
81
|
+
canvas.dataset.displayMode = display.mode;
|
|
82
|
+
canvas.dataset.toneMapping = mapper;
|
|
83
|
+
void display
|
|
84
|
+
.complete()
|
|
85
|
+
.then(() => {
|
|
86
|
+
if (!disposed && revision === drawRevision && active === display)
|
|
87
|
+
onDraw?.(image, display.mode);
|
|
88
|
+
})
|
|
89
|
+
.catch((error) => {
|
|
90
|
+
if (!disposed && active === display) {
|
|
91
|
+
if (display.mode === 'hdr') {
|
|
92
|
+
fallback();
|
|
93
|
+
}
|
|
94
|
+
else
|
|
95
|
+
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (display.mode === 'hdr') {
|
|
101
|
+
fallback();
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const fallback = () => {
|
|
108
|
+
if (disposed)
|
|
109
|
+
return;
|
|
110
|
+
++generation;
|
|
111
|
+
active?.dispose();
|
|
112
|
+
mount(host.ownerDocument.createElement('canvas'));
|
|
113
|
+
fallbackImage = undefined;
|
|
114
|
+
fallbackDrawing = '';
|
|
115
|
+
active = {
|
|
116
|
+
mode: 'sdr',
|
|
117
|
+
draw(image, mapper, exposure) {
|
|
118
|
+
const key = `${mapper}:${exposure}`;
|
|
119
|
+
if (fallbackImage === image && fallbackDrawing === key)
|
|
120
|
+
return;
|
|
121
|
+
drawToneMapped(canvas, image, mapper, exposure);
|
|
122
|
+
fallbackImage = image;
|
|
123
|
+
fallbackDrawing = key;
|
|
124
|
+
},
|
|
125
|
+
resize() { },
|
|
126
|
+
complete: () => Promise.resolve(),
|
|
127
|
+
dispose() { },
|
|
128
|
+
};
|
|
129
|
+
draw();
|
|
130
|
+
};
|
|
131
|
+
const select = async () => {
|
|
132
|
+
const request = ++generation;
|
|
133
|
+
if (!media.matches || !view.navigator.gpu) {
|
|
134
|
+
fallback();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
let next;
|
|
138
|
+
try {
|
|
139
|
+
const { createWebGPUDisplay } = await import('./webgpuDisplay.js');
|
|
140
|
+
if (disposed || request !== generation)
|
|
141
|
+
return;
|
|
142
|
+
const candidate = host.ownerDocument.createElement('canvas');
|
|
143
|
+
next = await createWebGPUDisplay(candidate, () => {
|
|
144
|
+
if (!disposed && request === generation)
|
|
145
|
+
fallback();
|
|
146
|
+
});
|
|
147
|
+
if (disposed || request !== generation) {
|
|
148
|
+
next.dispose();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
active?.dispose();
|
|
152
|
+
active = next;
|
|
153
|
+
mount(candidate);
|
|
154
|
+
draw();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
next?.dispose();
|
|
158
|
+
if (!disposed && request === generation)
|
|
159
|
+
fallback();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
redraw.current = draw;
|
|
163
|
+
const observer = new ResizeObserver(draw);
|
|
164
|
+
try {
|
|
165
|
+
observer.observe(host, { box: 'device-pixel-content-box' });
|
|
10
166
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const canvas = canvasRef.current;
|
|
14
|
-
if (!canvas)
|
|
15
|
-
return;
|
|
16
|
-
const { width, height } = data;
|
|
17
|
-
canvas.width = width;
|
|
18
|
-
canvas.height = height;
|
|
19
|
-
// LDR from applyToneMapping is sRGB; use srgb canvas so it displays correctly
|
|
20
|
-
const ctx = canvas.getContext('2d', { colorSpace: 'srgb' }) ?? canvas.getContext('2d');
|
|
21
|
-
if (!ctx)
|
|
22
|
-
return;
|
|
23
|
-
const ldrRgb = applyToneMapping(data.data, width, height, {
|
|
24
|
-
toneMapping: tone,
|
|
25
|
-
exposure: exp,
|
|
26
|
-
sourceColorSpace: data.linearColorSpace,
|
|
27
|
-
});
|
|
28
|
-
const canvasImageData = ctx.createImageData(width, height);
|
|
29
|
-
const pixels = canvasImageData.data;
|
|
30
|
-
const sourceLength = width * height * 3;
|
|
31
|
-
for (let destIndex = 0, sourceIndex = 0; sourceIndex < sourceLength; destIndex += 4, sourceIndex += 3) {
|
|
32
|
-
pixels[destIndex] = ldrRgb[sourceIndex];
|
|
33
|
-
pixels[destIndex + 1] = ldrRgb[sourceIndex + 1];
|
|
34
|
-
pixels[destIndex + 2] = ldrRgb[sourceIndex + 2];
|
|
35
|
-
pixels[destIndex + 3] = 255;
|
|
167
|
+
catch {
|
|
168
|
+
observer.observe(host);
|
|
36
169
|
}
|
|
37
|
-
|
|
170
|
+
const onMediaChange = () => {
|
|
171
|
+
void select();
|
|
172
|
+
};
|
|
173
|
+
media.addEventListener('change', onMediaChange);
|
|
174
|
+
view.addEventListener('resize', draw);
|
|
175
|
+
let resolution = view.matchMedia(`(resolution: ${view.devicePixelRatio}dppx)`);
|
|
176
|
+
const onResolutionChange = () => {
|
|
177
|
+
resolution.removeEventListener('change', onResolutionChange);
|
|
178
|
+
resolution = view.matchMedia(`(resolution: ${view.devicePixelRatio}dppx)`);
|
|
179
|
+
resolution.addEventListener('change', onResolutionChange);
|
|
180
|
+
draw();
|
|
181
|
+
};
|
|
182
|
+
resolution.addEventListener('change', onResolutionChange);
|
|
183
|
+
void select();
|
|
184
|
+
return () => {
|
|
185
|
+
disposed = true;
|
|
186
|
+
++generation;
|
|
187
|
+
++drawRevision;
|
|
188
|
+
observer.disconnect();
|
|
189
|
+
media.removeEventListener('change', onMediaChange);
|
|
190
|
+
view.removeEventListener('resize', draw);
|
|
191
|
+
resolution.removeEventListener('change', onResolutionChange);
|
|
192
|
+
active?.dispose();
|
|
193
|
+
canvasRef.current = null;
|
|
194
|
+
redraw.current = () => { };
|
|
195
|
+
host.replaceChildren();
|
|
196
|
+
};
|
|
38
197
|
}, []);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
198
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: CSS }), _jsx("div", { ref: hostRef, className: `hdrify-canvas${props.className ? ` ${props.className}` : ''}`, style: {
|
|
199
|
+
'--hdrify-image-width': `${props.hdrifyImage.width}px`,
|
|
200
|
+
'--hdrify-image-aspect': `${props.hdrifyImage.width}/${props.hdrifyImage.height}`,
|
|
201
|
+
} })] }));
|
|
43
202
|
}
|
|
44
203
|
//# sourceMappingURL=HdrifyCanvas.js.map
|
package/dist/HdrifyCanvas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HdrifyCanvas.js","
|
|
1
|
+
{"version":3,"file":"HdrifyCanvas.js","sources":["../src/HdrifyCanvas.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAA+D,MAAM,cAAc,CAAC;AAkB/G,MAAM,GAAG,GACP,qPAAqP,CAAC;AAExP;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAa,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACpC,qGAAqG;QACrG,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QACzC,OAAO,GAAG,EAAE;YACV,sGAAsG;YACtG,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IAEzB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,OAAQ,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,WAAY,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACvD,IAAI,MAAgC,CAAC;QACrC,IAAI,MAAyB,CAAC;QAC9B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,eAAe,GAAG,EAAE,CAAC;QACzB,IAAI,aAAsC,CAAC;QAC3C,MAAM,KAAK,GAAG,CAAC,IAAuB,EAAE,EAAE;YACxC,MAAM,GAAG,IAAI,CAAC;YACd,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;YAC3B,0FAA0F;YAC1F,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY;gBAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC;YAC9E,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,QAAQ,IAAI,CAAC,MAAM;gBAAE,OAAO;YAChC,MAAM,OAAO,GAAG,MAAM,CAAC;YACvB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;YACtF,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,QAAQ,GAAG,EAAE,YAAY,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,EAC/C,CAAC,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CACnD,CAAC;gBACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;gBAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;gBACjD,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC;gBACpC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC;gBAC1D,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACtC,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;gBAC1C,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC;gBACpC,KAAK,OAAO;qBACT,QAAQ,EAAE;qBACV,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,YAAY,IAAI,MAAM,KAAK,OAAO;wBAAE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClG,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;oBACxB,IAAI,CAAC,QAAQ,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;wBACpC,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;4BAC3B,QAAQ,EAAE,CAAC;wBACb,CAAC;;4BAAM,OAAO,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC9E,CAAC;gBACH,CAAC,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBAC3B,QAAQ,EAAE,CAAC;gBACb,CAAC;;oBAAM,OAAO,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,QAAQ;gBAAE,OAAO;YACrB,EAAE,UAAU,CAAC;YACb,MAAM,EAAE,OAAO,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClD,aAAa,GAAG,SAAS,CAAC;YAC1B,eAAe,GAAG,EAAE,CAAC;YACrB,MAAM,GAAG;gBACP,IAAI,EAAE,KAAK;gBACX,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ;oBAC1B,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACpC,IAAI,aAAa,KAAK,KAAK,IAAI,eAAe,KAAK,GAAG;wBAAE,OAAO;oBAC/D,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;oBAChD,aAAa,GAAG,KAAK,CAAC;oBACtB,eAAe,GAAG,GAAG,CAAC;gBACxB,CAAC;gBACD,MAAM,KAAI,CAAC;gBACX,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;gBACjC,OAAO,KAAI,CAAC;aACb,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;YACxB,MAAM,OAAO,GAAG,EAAE,UAAU,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;gBAC1C,QAAQ,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YACD,IAAI,IAA8B,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;gBACnE,IAAI,QAAQ,IAAI,OAAO,KAAK,UAAU;oBAAE,OAAO;gBAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAI,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,GAAG,EAAE;oBAC/C,IAAI,CAAC,QAAQ,IAAI,OAAO,KAAK,UAAU;wBAAE,QAAQ,EAAE,CAAC;gBACtD,CAAC,CAAC,CAAC;gBACH,IAAI,QAAQ,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;oBACvC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,MAAM,EAAE,OAAO,EAAE,CAAC;gBAClB,MAAM,GAAG,IAAI,CAAC;gBACd,KAAK,CAAC,SAAS,CAAC,CAAC;gBACjB,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,EAAE,OAAO,EAAE,CAAC;gBAChB,IAAI,CAAC,QAAQ,IAAI,OAAO,KAAK,UAAU;oBAAE,QAAQ,EAAE,CAAC;YACtD,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,0BAA0B,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,KAAK,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC;QACF,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,OAAO,CAAC,CAAC;QAC/E,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC9B,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;YAC7D,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,OAAO,CAAC,CAAC;YAC3E,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;YAC1D,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAC1D,KAAK,MAAM,EAAE,CAAC;QACd,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,IAAI,CAAC;YAChB,EAAE,UAAU,CAAC;YACb,EAAE,YAAY,CAAC;YACf,QAAQ,CAAC,UAAU,EAAE,CAAC;YACtB,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACzC,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;YAC7D,MAAM,EAAE,OAAO,EAAE,CAAC;YAClB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;YACzB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YAC1B,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,8BACE,0BAAQ,GAAG,GAAS,EACpB,cACE,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,gBAAgB,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EACzE,KAAK,EACH;oBACE,sBAAsB,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI;oBACtD,uBAAuB,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE;iBAC3D,GAE1B,IACD,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { HdrifyImage } from 'hdrify';
|
|
2
|
+
import { type ViewerToneMapping } from './display.js';
|
|
3
|
+
import { type CSSProperties, type Ref } from 'react';
|
|
4
|
+
import { type ImageViewerCaptureOptions } from './capture.js';
|
|
5
|
+
import { type ImageViewerProgress } from './progress.js';
|
|
6
|
+
/** `open` shows the options panel, `closed` shows only its gear button, and `hidden` shows neither. */
|
|
7
|
+
export type SettingsPanelMode = 'open' | 'closed' | 'hidden';
|
|
8
|
+
/** `contain` scales the image to fit the viewer; `actual` shows one image pixel per CSS pixel, scrolling if needed. */
|
|
9
|
+
export type ImageFit = 'contain' | 'actual';
|
|
10
|
+
/** User-adjustable display settings. */
|
|
11
|
+
export interface ImageViewerSettings {
|
|
12
|
+
/** Omit for None on HDR displays and Neutral on SDR; explicit None falls back to Neutral on SDR. */
|
|
13
|
+
toneMapping?: ViewerToneMapping;
|
|
14
|
+
/** Exposure in stops (EV): `0` is unchanged, `+1` doubles the brightness. */
|
|
15
|
+
exposure: number;
|
|
16
|
+
fit: ImageFit;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_IMAGE_VIEWER_SETTINGS: Readonly<ImageViewerSettings>;
|
|
19
|
+
export declare const TONE_MAPPING_OPTIONS: readonly {
|
|
20
|
+
value: ViewerToneMapping;
|
|
21
|
+
label: string;
|
|
22
|
+
}[];
|
|
23
|
+
/** Range of the exposure slider, in stops. The options panel accepts any value. */
|
|
24
|
+
export declare const EXPOSURE_SLIDER_RANGE: {
|
|
25
|
+
readonly min: -10;
|
|
26
|
+
readonly max: 10;
|
|
27
|
+
};
|
|
28
|
+
/** Imperative handle for {@link ImageViewer}, received through its `ref` (React 19). */
|
|
29
|
+
export interface ImageViewerHandle {
|
|
30
|
+
/**
|
|
31
|
+
* Resolve once the current source is loaded and drawn (immediately with no source). If the source changes first,
|
|
32
|
+
* it waits for the new source instead. Rejects with the load's error, or if the component unmounts.
|
|
33
|
+
*/
|
|
34
|
+
whenReady(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Wait for {@link whenReady}, including the first completed render, then export
|
|
37
|
+
* an SDR PNG/JPEG/WebP without viewer controls. Capture is independent of display
|
|
38
|
+
* output: an omitted mapper uses Neutral; explicit `none` clips above-white values.
|
|
39
|
+
*/
|
|
40
|
+
toBlob(options?: ImageViewerCaptureOptions): Promise<Blob>;
|
|
41
|
+
}
|
|
42
|
+
/** Props for {@link ImageViewer}. Settings props override the user's choice whenever they change. */
|
|
43
|
+
export interface ImageViewerProps extends Partial<ImageViewerSettings> {
|
|
44
|
+
/** URL of an EXR, HDR, JPEG XL or gain map JPEG (optionally gzipped). Fetching is cancelled when it changes. */
|
|
45
|
+
src?: string;
|
|
46
|
+
/** Encoded file bytes; takes precedence over `src`. */
|
|
47
|
+
data?: ArrayBuffer | Uint8Array;
|
|
48
|
+
/** An already decoded image; takes precedence over `data` and `src`. */
|
|
49
|
+
image?: HdrifyImage;
|
|
50
|
+
/** Initial state of the options panel. Defaults to `closed`. */
|
|
51
|
+
settingsPanel?: SettingsPanelMode;
|
|
52
|
+
/** Show the vertical exposure slider over the left edge. */
|
|
53
|
+
exposureControl?: boolean;
|
|
54
|
+
/** Wrapper class name. */
|
|
55
|
+
className?: string;
|
|
56
|
+
/** Wrapper style; the default height is 480 pixels. */
|
|
57
|
+
style?: CSSProperties;
|
|
58
|
+
/** Called after each image loads and is drawn. */
|
|
59
|
+
onLoad?: (image: HdrifyImage) => void;
|
|
60
|
+
/** Called with fetch and decode errors; they are also shown in the viewer. */
|
|
61
|
+
onError?: (error: Error) => void;
|
|
62
|
+
/** Called as the image downloads, decodes and is drawn. */
|
|
63
|
+
onProgress?: (progress: ImageViewerProgress) => void;
|
|
64
|
+
/** Called when the user changes a setting with the slider or the options panel. */
|
|
65
|
+
onSettingsChange?: (settings: ImageViewerSettings) => void;
|
|
66
|
+
/** Called when the user opens or closes the options panel. */
|
|
67
|
+
onSettingsPanelChange?: (mode: SettingsPanelMode) => void;
|
|
68
|
+
/** Receives an {@link ImageViewerHandle} for readiness and image capture. */
|
|
69
|
+
ref?: Ref<ImageViewerHandle>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Loads and displays an HDR image with tone mapping, a loading bar, an optional options panel and an optional
|
|
73
|
+
* exposure slider. Accepts every format hdrify reads; see {@link decodeHdrifyImage}.
|
|
74
|
+
* Uses {@link HdrifyCanvas} for HDR presentation and SDR fallback. None is offered
|
|
75
|
+
* and selected by default only after extended FP16 presentation succeeds; otherwise
|
|
76
|
+
* Neutral is the default and None is hidden. There is no Automatic menu item.
|
|
77
|
+
* `fit="actual"` shows one source pixel per CSS pixel. Loading progress is reported
|
|
78
|
+
* through `onProgress`; the imperative handle exposes readiness and SDR capture.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <ImageViewer src="/images/memorial.exr" exposureControl toneMapping="agx" style={{ height: 600 }} />
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function ImageViewer({ src, data, image, toneMapping, exposure, fit, settingsPanel, exposureControl, className, style, onLoad, onError, onProgress, onSettingsChange, onSettingsPanelChange, ref, }: ImageViewerProps): import("react").JSX.Element;
|
|
86
|
+
//# sourceMappingURL=ImageViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageViewer.d.ts","sources":["../src/ImageViewer.tsx"],"names":[],"mappings":"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"}
|