UNPKG

1.76 kBJavaScriptView Raw
1import { useState, useEffect } from 'react';
2
3/**
4 * Fetch and load an image for programatic use such as in a `<canvas>` element.
5 *
6 * @param imageOrUrl The `HtmlImageElement` or image url to load
7 * @param crossOrigin The `crossorigin` attribute to set
8 *
9 * ```ts
10 * const { image, error } = useImage('/static/kittens.png')
11 * const ref = useRef<HTMLCanvasElement>()
12 *
13 * useEffect(() => {
14 * const ctx = ref.current.getContext('2d')
15 *
16 * if (image) {
17 * ctx.drawImage(image, 0, 0)
18 * }
19 * }, [ref, image])
20 *
21 * return (
22 * <>
23 * {error && "there was a problem loading the image"}
24 * <canvas ref={ref} />
25 * </>
26 * ```
27 */
28export default function useImage(imageOrUrl, crossOrigin) {
29 var _useState = useState({
30 image: null,
31 error: null
32 }),
33 state = _useState[0],
34 setState = _useState[1];
35
36 useEffect(function () {
37 if (!imageOrUrl) return undefined;
38 var image;
39
40 if (typeof imageOrUrl === 'string') {
41 image = new Image();
42 if (crossOrigin) image.crossOrigin = crossOrigin;
43 image.src = imageOrUrl;
44 } else {
45 image = imageOrUrl;
46
47 if (image.complete && image.naturalHeight > 0) {
48 setState({
49 image: image,
50 error: null
51 });
52 return;
53 }
54 }
55
56 function onLoad() {
57 setState({
58 image: image,
59 error: null
60 });
61 }
62
63 function onError(error) {
64 setState({
65 image: image,
66 error: error
67 });
68 }
69
70 image.addEventListener('load', onLoad);
71 image.addEventListener('error', onError);
72 return function () {
73 image.removeEventListener('load', onLoad);
74 image.removeEventListener('error', onError);
75 };
76 }, [imageOrUrl, crossOrigin]);
77 return state;
78}
\No newline at end of file