UNPKG

1.84 kBTypeScriptView Raw
1import * as React from 'react';
2import { withMap } from './context';
3import { Map } from 'mapbox-gl';
4
5interface ImageOptionsType {
6 pixelRatio?: number;
7 sdf?: boolean;
8}
9
10type ImageDataType =
11 | HTMLImageElement
12 | ArrayBufferView
13 | { width: number; height: number; data: Uint8Array | Uint8ClampedArray }
14 | ImageData;
15
16export interface Props {
17 id: string;
18 url?: string;
19 data?: ImageDataType;
20 options?: ImageOptionsType;
21 onLoaded?: () => void;
22 onError?: (error: Error) => void;
23 map: Map;
24}
25
26class Image extends React.Component<Props> {
27 public componentDidMount() {
28 this.loadImage(this.props);
29 }
30
31 public componentWillUnmount() {
32 Image.removeImage(this.props);
33 }
34
35 public componentDidUpdate(prevProps: Props) {
36 const { id } = prevProps;
37
38 if (prevProps.map !== this.props.map) {
39 // Remove image from old map
40 Image.removeImage(this.props);
41 }
42
43 if (this.props.map && !this.props.map.hasImage(id)) {
44 // Add missing image to map
45 this.loadImage(this.props);
46 }
47 }
48
49 public render() {
50 return null;
51 }
52
53 private loadImage(props: Props) {
54 const { map, id, url, data, options, onError } = props;
55
56 if (data) {
57 map.addImage(id, data, options);
58 this.loaded();
59 } else if (url) {
60 map.loadImage(url, (error: Error | undefined, image: ImageDataType) => {
61 if (error) {
62 if (onError) {
63 onError(error);
64 }
65
66 return;
67 }
68 map.addImage(id, image, options);
69 this.loaded();
70 });
71 }
72 }
73
74 private static removeImage(props: Props) {
75 const { id, map } = props;
76 if (map && map.getStyle()) {
77 map.removeImage(id);
78 }
79 }
80 private loaded() {
81 const { onLoaded } = this.props;
82 if (onLoaded) {
83 onLoaded();
84 }
85 }
86}
87
88export default withMap(Image);