react-spatial 1.5.2 → 1.5.3
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/.github/workflows/conventional-pr-title.yml +21 -0
- package/.github/workflows/main.yml +28 -0
- package/.husky/commit-msg +4 -0
- package/.husky/post-checkout +4 -0
- package/.husky/post-merge +4 -0
- package/.husky/post-rebase +4 -0
- package/.husky/pre-commit +4 -0
- package/.nvmrc +1 -0
- package/.whitesource +8 -0
- package/CHANGELOG.md +65 -0
- package/DEVELOP.md +113 -0
- package/__mocks__/mapbox-gl.js +11 -0
- package/__mocks__/resize-observer-polyfill.js +9 -0
- package/babel.config.js +3 -0
- package/commitlint.config.js +1 -0
- package/data/topic1.js +119 -0
- package/data/topic2.js +28 -0
- package/doc/README.md +21 -0
- package/doc/doc-config.json +4 -0
- package/package.json +4 -3
- package/pull_request_template.md +16 -0
- package/renovate.json +4 -0
- package/scripts/read-pkg-json.js +17 -0
- package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.js +322 -0
- package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.test.js +69 -0
- package/src/components/BaseLayerSwitcher/README.md +61 -0
- package/src/components/BaseLayerSwitcher/__snapshots__/BaseLayerSwitcher.test.js.snap +88 -0
- package/src/components/BaseLayerSwitcher/index.js +1 -0
- package/src/components/BasicMap/BasicMap.js +413 -0
- package/src/components/BasicMap/BasicMap.test.js +281 -0
- package/src/components/BasicMap/README.md +18 -0
- package/src/components/BasicMap/index.js +1 -0
- package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.js +320 -93
- package/src/components/CanvasSaveButton/CanvasSaveButton.test.js +148 -0
- package/src/components/CanvasSaveButton/README.md +76 -0
- package/src/components/CanvasSaveButton/__snapshots__/CanvasSaveButton.test.js.snap +76 -0
- package/src/components/CanvasSaveButton/index.js +1 -0
- package/src/components/Copyright/Copyright.js +89 -0
- package/src/components/Copyright/Copyright.test.js +134 -0
- package/src/components/Copyright/README.md +36 -0
- package/src/components/Copyright/index.js +1 -0
- package/src/components/FeatureExportButton/FeatureExportButton.js +118 -0
- package/src/components/FeatureExportButton/FeatureExportButton.test.js +417 -0
- package/src/components/FeatureExportButton/README.md +76 -0
- package/src/components/FeatureExportButton/__snapshots__/FeatureExportButton.test.js.snap +67 -0
- package/src/components/FeatureExportButton/index.js +1 -0
- package/src/components/FitExtent/FitExtent.js +62 -0
- package/src/components/FitExtent/FitExtent.test.js +48 -0
- package/src/components/FitExtent/README.md +34 -0
- package/src/components/FitExtent/__snapshots__/FitExtent.test.js.snap +13 -0
- package/src/components/FitExtent/index.js +1 -0
- package/{components → src/components}/Geolocation/Geolocation.js +144 -61
- package/src/components/Geolocation/Geolocation.test.js +267 -0
- package/src/components/Geolocation/README.md +25 -0
- package/src/components/Geolocation/__snapshots__/Geolocation.test.js.snap +92 -0
- package/src/components/Geolocation/index.js +1 -0
- package/src/components/LayerTree/LayerTree.js +487 -0
- package/src/components/LayerTree/LayerTree.test.js +337 -0
- package/src/components/LayerTree/README.md +92 -0
- package/src/components/LayerTree/__snapshots__/LayerTree.test.js.snap +1746 -0
- package/src/components/LayerTree/index.js +1 -0
- package/src/components/MousePosition/MousePosition.js +175 -0
- package/src/components/MousePosition/MousePosition.test.js +132 -0
- package/src/components/MousePosition/README.md +50 -0
- package/src/components/MousePosition/__snapshots__/MousePosition.test.js.snap +76 -0
- package/src/components/MousePosition/index.js +1 -0
- package/src/components/NorthArrow/NorthArrow.js +75 -0
- package/src/components/NorthArrow/NorthArrow.test.js +104 -0
- package/src/components/NorthArrow/README.md +59 -0
- package/src/components/NorthArrow/__snapshots__/NorthArrow.test.js.snap +117 -0
- package/src/components/NorthArrow/index.js +1 -0
- package/src/components/Overlay/Overlay.js +176 -0
- package/src/components/Overlay/Overlay.test.js +149 -0
- package/src/components/Overlay/README.md +59 -0
- package/src/components/Overlay/__snapshots__/Overlay.test.js.snap +9 -0
- package/src/components/Overlay/index.js +1 -0
- package/src/components/Permalink/Permalink.js +326 -0
- package/src/components/Permalink/Permalink.test.js +285 -0
- package/src/components/Permalink/README.md +105 -0
- package/src/components/Permalink/index.js +1 -0
- package/{components → src/components}/Popup/Popup.js +165 -55
- package/src/components/Popup/Popup.test.js +307 -0
- package/src/components/Popup/README.md +93 -0
- package/src/components/Popup/__snapshots__/Popup.test.js.snap +180 -0
- package/src/components/Popup/index.js +1 -0
- package/src/components/README.md +41 -0
- package/{components → src/components}/ResizeHandler/ResizeHandler.js +50 -15
- package/src/components/ResizeHandler/ResizeHandler.test.js +344 -0
- package/src/components/ResizeHandler/index.js +1 -0
- package/src/components/RouteSchedule/README.md +118 -0
- package/src/components/RouteSchedule/RouteSchedule.js +370 -0
- package/src/components/RouteSchedule/RouteSchedule.test.js +113 -0
- package/src/components/RouteSchedule/__snapshots__/RouteSchedule.test.js.snap +248 -0
- package/src/components/RouteSchedule/index.js +1 -0
- package/src/components/ScaleLine/README.md +29 -0
- package/src/components/ScaleLine/ScaleLine.js +50 -0
- package/src/components/ScaleLine/ScaleLine.test.js +30 -0
- package/src/components/ScaleLine/__snapshots__/ScaleLine.test.js.snap +7 -0
- package/src/components/ScaleLine/index.js +1 -0
- package/src/components/StopsFinder/README.md +50 -0
- package/src/components/StopsFinder/StopsFinder.js +284 -0
- package/src/components/StopsFinder/StopsFinder.test.js +17 -0
- package/src/components/StopsFinder/StopsFinderOption.js +61 -0
- package/src/components/StopsFinder/__snapshots__/StopsFinder.test.js.snap +133 -0
- package/src/components/StopsFinder/index.js +1 -0
- package/src/components/Zoom/README.md +25 -0
- package/src/components/Zoom/Zoom.js +180 -0
- package/src/components/Zoom/Zoom.test.js +141 -0
- package/src/components/Zoom/__snapshots__/Zoom.test.js.snap +201 -0
- package/src/components/Zoom/index.js +1 -0
- package/{propTypes.js → src/propTypes.js} +16 -12
- package/{setupTests.js → src/setupTests.js} +1 -1
- package/src/styleguidist/ComponentsList.js +52 -0
- package/src/styleguidist/StyleGuide.js +277 -0
- package/src/styleguidist/styleguidist.css +38 -0
- package/src/utils/GlobalsForOle.js +99 -0
- package/src/utils/KML.js +594 -0
- package/src/utils/KML.test.js +337 -0
- package/src/utils/KMLFormat.js +100 -0
- package/src/utils/KMLFormat.test.js +50 -0
- package/{utils → src/utils}/Styles.js +20 -14
- package/src/utils/__snapshots__/KML.test.js.snap.KML-readFeatures()-and-writeFeatures()-should-read-and-write-lineDash-and-fillPattern-style-for-polygon.canvas-image.png +0 -0
- package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-2-(cross)-color-and-(light-blue)-opacity.canvas-image.png +0 -0
- package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-3-(diagonal-line-from-bottom-left-tot-top-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
- package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-4-(diagonal-line-from-top-left-to-bottom-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
- package/{utils → src/utils}/getPolygonPattern.js +34 -6
- package/src/utils/getPolygonPattern.test.js +61 -0
- package/src/utils/timeUtils.js +52 -0
- package/src/utils/timeUtils.test.js +30 -0
- package/styleguide.config.js +251 -0
- package/components/BaseLayerSwitcher/BaseLayerSwitcher.js +0 -231
- package/components/BaseLayerSwitcher/BaseLayerSwitcher.js.map +0 -7
- package/components/BaseLayerSwitcher/index.js +0 -1
- package/components/BaseLayerSwitcher/index.js.map +0 -7
- package/components/BasicMap/BasicMap.js +0 -278
- package/components/BasicMap/BasicMap.js.map +0 -7
- package/components/BasicMap/index.js +0 -1
- package/components/BasicMap/index.js.map +0 -7
- package/components/CanvasSaveButton/CanvasSaveButton.js.map +0 -7
- package/components/CanvasSaveButton/index.js +0 -1
- package/components/CanvasSaveButton/index.js.map +0 -7
- package/components/Copyright/Copyright.js +0 -55
- package/components/Copyright/Copyright.js.map +0 -7
- package/components/Copyright/index.js +0 -1
- package/components/Copyright/index.js.map +0 -7
- package/components/FeatureExportButton/FeatureExportButton.js +0 -62
- package/components/FeatureExportButton/FeatureExportButton.js.map +0 -7
- package/components/FeatureExportButton/index.js +0 -1
- package/components/FeatureExportButton/index.js.map +0 -7
- package/components/FitExtent/FitExtent.js +0 -32
- package/components/FitExtent/FitExtent.js.map +0 -7
- package/components/FitExtent/index.js +0 -1
- package/components/FitExtent/index.js.map +0 -7
- package/components/Geolocation/Geolocation.js.map +0 -7
- package/components/Geolocation/index.js +0 -1
- package/components/Geolocation/index.js.map +0 -7
- package/components/LayerTree/LayerTree.js +0 -278
- package/components/LayerTree/LayerTree.js.map +0 -7
- package/components/LayerTree/index.js +0 -1
- package/components/LayerTree/index.js.map +0 -7
- package/components/MousePosition/MousePosition.js +0 -110
- package/components/MousePosition/MousePosition.js.map +0 -7
- package/components/MousePosition/index.js +0 -1
- package/components/MousePosition/index.js.map +0 -7
- package/components/NorthArrow/NorthArrow.js +0 -43
- package/components/NorthArrow/NorthArrow.js.map +0 -7
- package/components/NorthArrow/index.js +0 -1
- package/components/NorthArrow/index.js.map +0 -7
- package/components/Overlay/Overlay.js +0 -122
- package/components/Overlay/Overlay.js.map +0 -7
- package/components/Overlay/index.js +0 -1
- package/components/Overlay/index.js.map +0 -7
- package/components/Permalink/Permalink.js +0 -206
- package/components/Permalink/Permalink.js.map +0 -7
- package/components/Permalink/index.js +0 -1
- package/components/Permalink/index.js.map +0 -7
- package/components/Popup/Popup.js.map +0 -7
- package/components/Popup/index.js +0 -1
- package/components/Popup/index.js.map +0 -7
- package/components/ResizeHandler/ResizeHandler.js.map +0 -7
- package/components/ResizeHandler/index.js +0 -1
- package/components/ResizeHandler/index.js.map +0 -7
- package/components/RouteSchedule/RouteSchedule.js +0 -220
- package/components/RouteSchedule/RouteSchedule.js.map +0 -7
- package/components/RouteSchedule/index.js +0 -1
- package/components/RouteSchedule/index.js.map +0 -7
- package/components/ScaleLine/ScaleLine.js +0 -32
- package/components/ScaleLine/ScaleLine.js.map +0 -7
- package/components/ScaleLine/index.js +0 -1
- package/components/ScaleLine/index.js.map +0 -7
- package/components/StopsFinder/StopsFinder.js +0 -210
- package/components/StopsFinder/StopsFinder.js.map +0 -7
- package/components/StopsFinder/StopsFinderOption.js +0 -51
- package/components/StopsFinder/StopsFinderOption.js.map +0 -7
- package/components/StopsFinder/index.js +0 -1
- package/components/StopsFinder/index.js.map +0 -7
- package/components/Zoom/Zoom.js +0 -130
- package/components/Zoom/Zoom.js.map +0 -7
- package/components/Zoom/index.js +0 -1
- package/components/Zoom/index.js.map +0 -7
- package/propTypes.js.map +0 -7
- package/setupTests.js.map +0 -7
- package/utils/GlobalsForOle.js +0 -94
- package/utils/GlobalsForOle.js.map +0 -7
- package/utils/KML.js +0 -412
- package/utils/KML.js.map +0 -7
- package/utils/KMLFormat.js +0 -69
- package/utils/KMLFormat.js.map +0 -7
- package/utils/Styles.js.map +0 -7
- package/utils/getPolygonPattern.js.map +0 -7
- package/utils/timeUtils.js +0 -31
- package/utils/timeUtils.js.map +0 -7
- /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.md.scss +0 -0
- /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.scss +0 -0
- /package/{components → src/components}/BasicMap/BasicMap.md.scss +0 -0
- /package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.md.scss +0 -0
- /package/{components → src/components}/Copyright/Copyright.md.scss +0 -0
- /package/{components → src/components}/FeatureExportButton/FeatureExportButton.md.scss +0 -0
- /package/{components → src/components}/FitExtent/FitExtent.md.scss +0 -0
- /package/{components → src/components}/Geolocation/Geolocation.md.scss +0 -0
- /package/{components → src/components}/Geolocation/Geolocation.scss +0 -0
- /package/{components → src/components}/LayerTree/LayerTree.md.scss +0 -0
- /package/{components → src/components}/LayerTree/LayerTree.scss +0 -0
- /package/{components → src/components}/MousePosition/MousePosition.md.scss +0 -0
- /package/{components → src/components}/NorthArrow/NorthArrow.scss +0 -0
- /package/{components → src/components}/Overlay/Overlay.md.scss +0 -0
- /package/{components → src/components}/Overlay/Overlay.scss +0 -0
- /package/{components → src/components}/Permalink/Permalink.md.scss +0 -0
- /package/{components → src/components}/Popup/Popup.md.scss +0 -0
- /package/{components → src/components}/Popup/Popup.scss +0 -0
- /package/{components → src/components}/RouteSchedule/RouteSchedule.md.scss +0 -0
- /package/{components → src/components}/RouteSchedule/RouteSchedule.scss +0 -0
- /package/{components → src/components}/ScaleLine/ScaleLine.scss +0 -0
- /package/{components → src/components}/Zoom/Zoom.md.scss +0 -0
- /package/{components → src/components}/Zoom/Zoom.scss +0 -0
- /package/{images → src/images}/RouteSchedule/firstStation.png +0 -0
- /package/{images → src/images}/RouteSchedule/lastStation.png +0 -0
- /package/{images → src/images}/RouteSchedule/line.png +0 -0
- /package/{images → src/images}/RouteSchedule/station.png +0 -0
- /package/{images → src/images}/baselayer/baselayer.basebright.png +0 -0
- /package/{images → src/images}/baselayer/baselayer.osm.png +0 -0
- /package/{images → src/images}/baselayer/baselayer.travic.png +0 -0
- /package/{images → src/images}/baselayer/open.topo.map.png +0 -0
- /package/{images → src/images}/baselayer/osm.baselayer.hot.png +0 -0
- /package/{images → src/images}/baselayer/osm.baselayer.png +0 -0
- /package/{images → src/images}/favicon.png +0 -0
- /package/{images → src/images}/geops_logo.png +0 -0
- /package/{images → src/images}/geops_logo.svg +0 -0
- /package/{images → src/images}/geops_qr.png +0 -0
- /package/{images → src/images}/mots/bus_poi-blue-01.svg +0 -0
- /package/{images → src/images}/mots/bus_poi-grey-01.svg +0 -0
- /package/{images → src/images}/mots/bus_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/bus_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/bus_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/bus_square-grey-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_poi-blue-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_poi-grey-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/cable_car_square-grey-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_poi-blue-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_poi-grey-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/ferry_square-grey-01.svg +0 -0
- /package/{images → src/images}/mots/funicular_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/funicular_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/funicular_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/gondola_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/rail_poi-blue-01.svg +0 -0
- /package/{images → src/images}/mots/rail_poi-grey-01.svg +0 -0
- /package/{images → src/images}/mots/rail_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/rail_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/rail_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/rail_square-grey-01.svg +0 -0
- /package/{images → src/images}/mots/subway_round blue-01.svg +0 -0
- /package/{images → src/images}/mots/subway_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/tram_poi-blue-01.svg +0 -0
- /package/{images → src/images}/mots/tram_poi-grey-01.svg +0 -0
- /package/{images → src/images}/mots/tram_round-blue-01.svg +0 -0
- /package/{images → src/images}/mots/tram_round-grey-01.svg +0 -0
- /package/{images → src/images}/mots/tram_square-blue-01.svg +0 -0
- /package/{images → src/images}/mots/tram_square-grey-01.svg +0 -0
- /package/{images → src/images}/northArrow.svg +0 -0
- /package/{images → src/images}/northArrow.url.svg +0 -0
- /package/{images → src/images}/northArrowCircle.svg +0 -0
- /package/{images → src/images}/northArrowCircle.url.svg +0 -0
- /package/{themes → src/themes}/README.md +0 -0
- /package/{themes → src/themes}/default/components.scss +0 -0
- /package/{themes → src/themes}/default/examples.scss +0 -0
- /package/{themes → src/themes}/default/index.scss +0 -0
- /package/{themes → src/themes}/default/mixins.scss +0 -0
- /package/{themes → src/themes}/default/variables.scss +0 -0
|
@@ -1,26 +1,114 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
import React, { PureComponent } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import OLMap from 'ol/Map';
|
|
5
|
+
import { getTopLeft, getBottomRight } from 'ol/extent';
|
|
6
|
+
import NorthArrowSimple from '../../images/northArrow.url.svg';
|
|
7
|
+
import NorthArrowCircle from '../../images/northArrowCircle.url.svg';
|
|
8
|
+
|
|
7
9
|
const extraDataImgPropType = PropTypes.shape({
|
|
8
10
|
src: PropTypes.string,
|
|
9
11
|
width: PropTypes.number,
|
|
10
12
|
height: PropTypes.number,
|
|
11
13
|
rotation: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
|
|
12
|
-
circled: PropTypes.bool
|
|
14
|
+
circled: PropTypes.bool,
|
|
13
15
|
});
|
|
16
|
+
|
|
14
17
|
const propTypes = {
|
|
18
|
+
/**
|
|
19
|
+
* Automatically download the image saved.
|
|
20
|
+
*/
|
|
15
21
|
autoDownload: PropTypes.bool,
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Children content of the button.
|
|
25
|
+
*/
|
|
16
26
|
children: PropTypes.node,
|
|
17
|
-
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Output format of the image.
|
|
30
|
+
*/
|
|
31
|
+
format: PropTypes.oneOf(['image/jpeg', 'image/png']),
|
|
32
|
+
|
|
33
|
+
/** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */
|
|
18
34
|
map: PropTypes.instanceOf(OLMap),
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Extent for the export. If no extent is given, the whole map is exported.
|
|
38
|
+
*/
|
|
19
39
|
extent: PropTypes.arrayOf(PropTypes.number),
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Array of 4 [ol/Coordinate](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~Coordinate).
|
|
43
|
+
* If no coordinates and no extent are given, the whole map is exported.
|
|
44
|
+
* This property must be used to export rotated map.
|
|
45
|
+
* If you don't need to export rotated map the extent property can be used as well.
|
|
46
|
+
* If extent is specified, coordinates property is ignored.
|
|
47
|
+
*/
|
|
20
48
|
coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Scale the map for better quality. Possible values: 1, 2 or 3.
|
|
52
|
+
* WARNING: The tiled layer with a WMTS or XYZ source must provides an url
|
|
53
|
+
* for each scale in the config file.
|
|
54
|
+
*/
|
|
21
55
|
scale: PropTypes.number,
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Function called before the dowload process begins.
|
|
59
|
+
*/
|
|
22
60
|
onSaveStart: PropTypes.func,
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Function called after the dowload process ends.
|
|
64
|
+
*
|
|
65
|
+
* @param {object} error Error message the process fails.
|
|
66
|
+
*/
|
|
23
67
|
onSaveEnd: PropTypes.func,
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Extra data, such as copyright, north arrow configuration.
|
|
71
|
+
* All extra data is optional.
|
|
72
|
+
*
|
|
73
|
+
* Example 1:
|
|
74
|
+
*
|
|
75
|
+
{
|
|
76
|
+
copyright: {
|
|
77
|
+
text: 'Example copyright', // Copyright text or function
|
|
78
|
+
font: '10px Arial', // Font, default is '12px Arial'
|
|
79
|
+
fillStyle: 'blue', // Fill style, default is 'black'
|
|
80
|
+
},
|
|
81
|
+
northArrow, // True if the north arrow
|
|
82
|
+
// should be placed with default configuration
|
|
83
|
+
// (default image, rotation=0, circled=false)
|
|
84
|
+
}
|
|
85
|
+
* Example 2:
|
|
86
|
+
*
|
|
87
|
+
{
|
|
88
|
+
northArrow: {
|
|
89
|
+
src: NorthArrowCustom,
|
|
90
|
+
width: 60, // Width in px, default is 80
|
|
91
|
+
height: 100, // Height in px, default is 80
|
|
92
|
+
rotation: 25, // Absolute rotation in degrees as number or function
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
* Example 3:
|
|
97
|
+
*
|
|
98
|
+
{
|
|
99
|
+
copyright: {
|
|
100
|
+
text: () => { // Copyright as function
|
|
101
|
+
return this.copyright;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
northArrow: {
|
|
105
|
+
rotation: () => { // Rotation as function
|
|
106
|
+
return NorthArrow.radToDeg(this.map.getView().getRotation());
|
|
107
|
+
},
|
|
108
|
+
circled, // Display circle around the north arrow (Does not work for custom src)
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
*/
|
|
24
112
|
extraData: PropTypes.shape({
|
|
25
113
|
logo: extraDataImgPropType,
|
|
26
114
|
northArrow: extraDataImgPropType,
|
|
@@ -30,17 +118,18 @@ const propTypes = {
|
|
|
30
118
|
font: PropTypes.string,
|
|
31
119
|
fillStyle: PropTypes.oneOfType([
|
|
32
120
|
PropTypes.string,
|
|
33
|
-
PropTypes.instanceOf(CanvasPattern)
|
|
121
|
+
PropTypes.instanceOf(CanvasPattern),
|
|
34
122
|
]),
|
|
35
|
-
background: PropTypes.bool
|
|
36
|
-
})
|
|
37
|
-
})
|
|
123
|
+
background: PropTypes.bool,
|
|
124
|
+
}),
|
|
125
|
+
}),
|
|
38
126
|
};
|
|
127
|
+
|
|
39
128
|
const defaultProps = {
|
|
40
129
|
autoDownload: true,
|
|
41
130
|
children: null,
|
|
42
131
|
map: null,
|
|
43
|
-
format:
|
|
132
|
+
format: 'image/png',
|
|
44
133
|
extent: null,
|
|
45
134
|
extraData: null,
|
|
46
135
|
coordinates: null,
|
|
@@ -48,113 +137,169 @@ const defaultProps = {
|
|
|
48
137
|
onSaveStart: (map) => {
|
|
49
138
|
return Promise.resolve(map);
|
|
50
139
|
},
|
|
51
|
-
onSaveEnd: () => {
|
|
52
|
-
}
|
|
140
|
+
onSaveEnd: () => {},
|
|
53
141
|
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The CanvasSaveButton component creates a button to save
|
|
145
|
+
* an [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)
|
|
146
|
+
* canvas as an image.
|
|
147
|
+
*/
|
|
54
148
|
class CanvasSaveButton extends PureComponent {
|
|
55
149
|
constructor(props) {
|
|
56
150
|
super(props);
|
|
57
151
|
this.padding = 5;
|
|
58
152
|
}
|
|
153
|
+
|
|
59
154
|
static getMargin(destCanvas) {
|
|
60
|
-
const newMargin = destCanvas.width / 100;
|
|
155
|
+
const newMargin = destCanvas.width / 100; // 1% of the canvas width
|
|
61
156
|
return newMargin;
|
|
62
157
|
}
|
|
158
|
+
|
|
63
159
|
onClick(evt) {
|
|
64
160
|
const { map, onSaveStart, onSaveEnd, autoDownload } = this.props;
|
|
65
161
|
if (window.navigator.msSaveBlob) {
|
|
162
|
+
// ie only
|
|
66
163
|
evt.preventDefault();
|
|
67
164
|
evt.stopPropagation();
|
|
68
165
|
}
|
|
69
166
|
onSaveStart(map).then((mapToExport) => {
|
|
70
|
-
return this.createCanvasImage(mapToExport || map)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
167
|
+
return this.createCanvasImage(mapToExport || map)
|
|
168
|
+
.then((canvas) => {
|
|
169
|
+
if (autoDownload) {
|
|
170
|
+
this.downloadCanvasImage(canvas).then((blob) => {
|
|
171
|
+
onSaveEnd(mapToExport, canvas, blob);
|
|
172
|
+
});
|
|
173
|
+
} else {
|
|
174
|
+
onSaveEnd(mapToExport, canvas);
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
.catch((err) => {
|
|
178
|
+
if (err) {
|
|
179
|
+
// eslint-disable-next-line no-console
|
|
180
|
+
console.error(err);
|
|
181
|
+
}
|
|
182
|
+
onSaveEnd(mapToExport, err);
|
|
183
|
+
});
|
|
84
184
|
});
|
|
85
185
|
}
|
|
186
|
+
|
|
86
187
|
getDownloadImageName() {
|
|
87
188
|
const { format } = this.props;
|
|
88
|
-
const fileExt = format ===
|
|
89
|
-
return
|
|
189
|
+
const fileExt = format === 'image/jpeg' ? 'jpg' : 'png';
|
|
190
|
+
return (
|
|
191
|
+
`${window.document.title.replace(/ /g, '_').toLowerCase()}` +
|
|
192
|
+
`.${fileExt}`
|
|
193
|
+
);
|
|
90
194
|
}
|
|
195
|
+
|
|
196
|
+
// Ensure the font size fita with the image width.
|
|
91
197
|
decreaseFontSize(destContext, maxWidth, copyright, scale) {
|
|
92
198
|
const minFontSize = 8;
|
|
93
199
|
let sizeMatch;
|
|
94
200
|
let fontSize;
|
|
95
201
|
do {
|
|
96
202
|
sizeMatch = destContext.font.match(/[0-9]+(?:\.[0-9]+)?(px)/i);
|
|
97
|
-
fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1],
|
|
203
|
+
fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], ''), 10);
|
|
204
|
+
|
|
205
|
+
// eslint-disable-next-line no-param-reassign
|
|
98
206
|
destContext.font = destContext.font.replace(fontSize, fontSize - 1);
|
|
207
|
+
|
|
99
208
|
if (fontSize - 1 === minFontSize) {
|
|
100
209
|
this.multilineCopyright = true;
|
|
101
210
|
}
|
|
102
|
-
} while (
|
|
211
|
+
} while (
|
|
212
|
+
fontSize - 1 > minFontSize &&
|
|
213
|
+
destContext.measureText(copyright).width * scale > maxWidth
|
|
214
|
+
);
|
|
215
|
+
|
|
103
216
|
return destContext.font;
|
|
104
217
|
}
|
|
105
|
-
|
|
218
|
+
|
|
219
|
+
// eslint-disable-next-line class-methods-use-this
|
|
220
|
+
drawTextBackground(
|
|
221
|
+
destContext,
|
|
222
|
+
textMeasure,
|
|
223
|
+
textX,
|
|
224
|
+
textY,
|
|
225
|
+
padding,
|
|
226
|
+
styleOptions = {},
|
|
227
|
+
) {
|
|
228
|
+
/// get width of text
|
|
106
229
|
const { width, height, actualBoundingBoxAscent } = textMeasure;
|
|
107
230
|
destContext.save();
|
|
108
|
-
|
|
109
|
-
|
|
231
|
+
// Dflt is a white background
|
|
232
|
+
destContext.fillStyle = 'rgba(255,255,255,.8)';
|
|
233
|
+
|
|
234
|
+
// To simplify usability the user could pass a boolean to use only default values.
|
|
235
|
+
if (typeof styleOptions === 'object') {
|
|
110
236
|
Object.entries(styleOptions).forEach(([key, value]) => {
|
|
111
237
|
destContext[key] = value;
|
|
112
238
|
});
|
|
113
239
|
}
|
|
240
|
+
|
|
241
|
+
/// draw background rect assuming height of font
|
|
114
242
|
destContext.fillRect(
|
|
115
243
|
textX - padding,
|
|
116
244
|
textY - actualBoundingBoxAscent - padding,
|
|
117
245
|
width + padding * 2,
|
|
118
|
-
height + padding * 2
|
|
246
|
+
height + padding * 2,
|
|
119
247
|
);
|
|
120
248
|
destContext.restore();
|
|
121
249
|
}
|
|
250
|
+
|
|
122
251
|
drawCopyright(destContext, destCanvas, maxWidth) {
|
|
123
252
|
const { extraData, scale } = this.props;
|
|
124
253
|
const { text, font, fillStyle, background } = extraData.copyright;
|
|
125
|
-
let copyright = typeof text ===
|
|
254
|
+
let copyright = typeof text === 'function' ? text() : text;
|
|
255
|
+
|
|
126
256
|
if (Array.isArray(copyright)) {
|
|
127
257
|
copyright = copyright.join();
|
|
128
258
|
}
|
|
259
|
+
|
|
129
260
|
destContext.save();
|
|
130
261
|
destContext.scale(scale, scale);
|
|
131
|
-
destContext.font = font ||
|
|
262
|
+
destContext.font = font || '12px Arial';
|
|
132
263
|
destContext.font = this.decreaseFontSize(
|
|
133
264
|
destContext,
|
|
134
265
|
maxWidth - this.padding,
|
|
135
266
|
copyright,
|
|
136
|
-
scale
|
|
267
|
+
scale,
|
|
137
268
|
);
|
|
269
|
+
|
|
138
270
|
destContext.scale(scale, scale);
|
|
139
|
-
destContext.fillStyle = fillStyle ||
|
|
271
|
+
destContext.fillStyle = fillStyle || 'black';
|
|
272
|
+
|
|
273
|
+
// We search if the display on 2 line is necessary
|
|
140
274
|
let firstLine = copyright;
|
|
141
|
-
const wordNumber = copyright.split(
|
|
275
|
+
const wordNumber = copyright.split(' ').length;
|
|
276
|
+
|
|
277
|
+
// If the text is bigger than the max width we split it into 2 lines
|
|
142
278
|
if (this.multilineCopyright) {
|
|
143
279
|
for (let i = 0; i < wordNumber; i += 1) {
|
|
144
|
-
firstLine = firstLine.substring(0, firstLine.lastIndexOf(
|
|
145
|
-
|
|
280
|
+
firstLine = firstLine.substring(0, firstLine.lastIndexOf(' '));
|
|
281
|
+
// Stop removing word when fits within one line.
|
|
282
|
+
if (
|
|
283
|
+
destContext.measureText(firstLine).width * scale <
|
|
284
|
+
maxWidth - this.padding
|
|
285
|
+
) {
|
|
146
286
|
break;
|
|
147
287
|
}
|
|
148
288
|
}
|
|
149
289
|
}
|
|
150
|
-
const secondLine = copyright.replace(firstLine,
|
|
290
|
+
const secondLine = copyright.replace(firstLine, '');
|
|
291
|
+
|
|
292
|
+
// Draw first line (line break isn't supported for fillText).
|
|
151
293
|
const textX = this.margin;
|
|
152
294
|
let textMeasure = destContext.measureText(firstLine);
|
|
153
|
-
textMeasure.height =
|
|
295
|
+
textMeasure.height =
|
|
296
|
+
textMeasure.actualBoundingBoxAscent +
|
|
297
|
+
textMeasure.actualBoundingBoxDescent;
|
|
154
298
|
let firstLineY = destCanvas.height / scale - this.padding;
|
|
155
299
|
const secondLineY = firstLineY;
|
|
156
300
|
const paddingBetweenLines = 3;
|
|
157
301
|
const paddingBackground = paddingBetweenLines / 2;
|
|
302
|
+
|
|
158
303
|
if (secondLine) {
|
|
159
304
|
firstLineY -= textMeasure.height + paddingBetweenLines;
|
|
160
305
|
}
|
|
@@ -165,13 +310,17 @@ class CanvasSaveButton extends PureComponent {
|
|
|
165
310
|
textX,
|
|
166
311
|
firstLineY,
|
|
167
312
|
paddingBackground,
|
|
168
|
-
background
|
|
313
|
+
background,
|
|
169
314
|
);
|
|
170
315
|
}
|
|
171
316
|
destContext.fillText(firstLine, textX, firstLineY);
|
|
317
|
+
|
|
318
|
+
// Draw second line.
|
|
172
319
|
if (secondLine) {
|
|
173
320
|
textMeasure = destContext.measureText(secondLine);
|
|
174
|
-
textMeasure.height =
|
|
321
|
+
textMeasure.height =
|
|
322
|
+
textMeasure.actualBoundingBoxAscent +
|
|
323
|
+
textMeasure.actualBoundingBoxDescent;
|
|
175
324
|
if (background) {
|
|
176
325
|
this.drawTextBackground(
|
|
177
326
|
destContext,
|
|
@@ -179,109 +328,155 @@ class CanvasSaveButton extends PureComponent {
|
|
|
179
328
|
textX,
|
|
180
329
|
secondLineY,
|
|
181
330
|
paddingBackground,
|
|
182
|
-
background
|
|
331
|
+
background,
|
|
183
332
|
);
|
|
184
333
|
}
|
|
185
334
|
destContext.fillText(secondLine, textX, secondLineY);
|
|
186
335
|
}
|
|
336
|
+
|
|
187
337
|
const firstLineMetrics = destContext.measureText(firstLine);
|
|
188
338
|
const secondLineMetrics = destContext.measureText(secondLine);
|
|
189
|
-
const heightFirstLine =
|
|
190
|
-
|
|
191
|
-
|
|
339
|
+
const heightFirstLine =
|
|
340
|
+
firstLineMetrics.actualBoundingBoxAscent +
|
|
341
|
+
firstLineMetrics.actualBoundingBoxDescent;
|
|
342
|
+
const heightSecondLine =
|
|
343
|
+
secondLineMetrics.actualBoundingBoxAscent +
|
|
344
|
+
secondLineMetrics.actualBoundingBoxDescent;
|
|
345
|
+
this.copyrightY =
|
|
346
|
+
destCanvas.height -
|
|
347
|
+
(heightFirstLine + paddingBetweenLines + heightSecondLine) / 2;
|
|
192
348
|
destContext.restore();
|
|
193
349
|
}
|
|
194
|
-
|
|
195
|
-
|
|
350
|
+
|
|
351
|
+
drawElement(data, destCanvas, previousItemSize = [0, 0], side = 'right') {
|
|
352
|
+
const destContext = destCanvas.getContext('2d');
|
|
196
353
|
const { scale } = this.props;
|
|
197
354
|
const { src, width, height, rotation } = data;
|
|
355
|
+
|
|
198
356
|
return new Promise((resolve) => {
|
|
199
357
|
const img = new Image();
|
|
200
|
-
img.crossOrigin =
|
|
358
|
+
img.crossOrigin = 'Anonymous';
|
|
201
359
|
img.src = src;
|
|
202
360
|
img.onload = () => {
|
|
203
361
|
destContext.save();
|
|
204
362
|
const elementWidth = (width || 80) * scale;
|
|
205
363
|
const elementHeight = (height || 80) * scale;
|
|
206
|
-
const left =
|
|
207
|
-
|
|
364
|
+
const left =
|
|
365
|
+
side === 'left'
|
|
366
|
+
? this.margin + elementWidth / 2
|
|
367
|
+
: destCanvas.width - this.margin - elementWidth / 2;
|
|
368
|
+
const top =
|
|
369
|
+
(side === 'left' && this.copyrightY
|
|
370
|
+
? this.copyrightY - 2 * this.padding
|
|
371
|
+
: destCanvas.height) -
|
|
372
|
+
this.margin -
|
|
373
|
+
elementHeight / 2 -
|
|
374
|
+
previousItemSize[1];
|
|
375
|
+
|
|
208
376
|
destContext.translate(left, top);
|
|
377
|
+
|
|
209
378
|
if (rotation) {
|
|
210
|
-
const angle = typeof rotation ===
|
|
379
|
+
const angle = typeof rotation === 'function' ? rotation() : rotation;
|
|
211
380
|
destContext.rotate(angle * (Math.PI / 180));
|
|
212
381
|
}
|
|
382
|
+
|
|
213
383
|
destContext.drawImage(
|
|
214
384
|
img,
|
|
215
385
|
-elementWidth / 2,
|
|
216
386
|
-elementHeight / 2,
|
|
217
387
|
elementWidth,
|
|
218
|
-
elementHeight
|
|
388
|
+
elementHeight,
|
|
219
389
|
);
|
|
220
390
|
destContext.restore();
|
|
391
|
+
|
|
392
|
+
// Return the pixels width of the arrow and the margin right,
|
|
393
|
+
// that must not be occupied by the copyright.
|
|
221
394
|
resolve([
|
|
222
395
|
elementWidth + 2 * this.padding,
|
|
223
|
-
elementHeight + 2 * this.padding
|
|
396
|
+
elementHeight + 2 * this.padding,
|
|
224
397
|
]);
|
|
225
398
|
};
|
|
399
|
+
|
|
226
400
|
img.onerror = () => {
|
|
227
401
|
resolve();
|
|
228
402
|
};
|
|
229
403
|
});
|
|
230
404
|
}
|
|
405
|
+
|
|
231
406
|
calculatePixelsToExport(mapToExport) {
|
|
232
407
|
const { extent, coordinates } = this.props;
|
|
233
408
|
let firstCoordinate;
|
|
234
409
|
let oppositeCoordinate;
|
|
410
|
+
|
|
235
411
|
if (extent) {
|
|
236
412
|
firstCoordinate = getTopLeft(extent);
|
|
237
413
|
oppositeCoordinate = getBottomRight(extent);
|
|
238
414
|
} else if (coordinates) {
|
|
415
|
+
// In case of coordinates coming from DragBox interaction:
|
|
416
|
+
// firstCoordinate is the first coordinate drawn by the user.
|
|
417
|
+
// oppositeCoordinate is the coordinate of the point dragged by the user.
|
|
239
418
|
[firstCoordinate, , oppositeCoordinate] = coordinates;
|
|
240
419
|
}
|
|
420
|
+
|
|
241
421
|
if (firstCoordinate && oppositeCoordinate) {
|
|
242
422
|
const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);
|
|
243
|
-
const oppositePixel =
|
|
423
|
+
const oppositePixel =
|
|
424
|
+
mapToExport.getPixelFromCoordinate(oppositeCoordinate);
|
|
244
425
|
const pixelTopLeft = [
|
|
245
426
|
firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
|
|
246
|
-
firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
|
|
427
|
+
firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1],
|
|
247
428
|
];
|
|
248
429
|
const pixelBottomRight = [
|
|
249
430
|
firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
|
|
250
|
-
firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
|
|
431
|
+
firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1],
|
|
251
432
|
];
|
|
433
|
+
|
|
252
434
|
return {
|
|
253
435
|
x: pixelTopLeft[0],
|
|
254
436
|
y: pixelTopLeft[1],
|
|
255
437
|
w: pixelBottomRight[0] - pixelTopLeft[0],
|
|
256
|
-
h: pixelBottomRight[1] - pixelTopLeft[1]
|
|
438
|
+
h: pixelBottomRight[1] - pixelTopLeft[1],
|
|
257
439
|
};
|
|
258
440
|
}
|
|
259
441
|
return null;
|
|
260
442
|
}
|
|
443
|
+
|
|
261
444
|
createCanvasImage(mapToExport) {
|
|
262
445
|
const { extraData } = this.props;
|
|
446
|
+
|
|
263
447
|
return new Promise((resolve) => {
|
|
264
|
-
mapToExport.once(
|
|
265
|
-
|
|
448
|
+
mapToExport.once('rendercomplete', () => {
|
|
449
|
+
// Find all layer canvases and add it to dest canvas.
|
|
450
|
+
const canvases = mapToExport
|
|
451
|
+
.getTargetElement()
|
|
452
|
+
.getElementsByTagName('canvas');
|
|
453
|
+
|
|
454
|
+
// Create the canvas to export with the good size.
|
|
266
455
|
let destCanvas;
|
|
267
456
|
let destContext;
|
|
457
|
+
|
|
458
|
+
// canvases is an HTMLCollection, we don't try to transform to array because some compilers like cra doesn't translate it right.
|
|
268
459
|
for (let i = 0; i < canvases.length; i += 1) {
|
|
269
460
|
const canvas = canvases[i];
|
|
270
461
|
if (!canvas.width || !canvas.height) {
|
|
462
|
+
// eslint-disable-next-line no-continue
|
|
271
463
|
continue;
|
|
272
464
|
}
|
|
273
465
|
const clip = this.calculatePixelsToExport(mapToExport) || {
|
|
274
466
|
x: 0,
|
|
275
467
|
y: 0,
|
|
276
468
|
w: canvas.width,
|
|
277
|
-
h: canvas.height
|
|
469
|
+
h: canvas.height,
|
|
278
470
|
};
|
|
471
|
+
|
|
279
472
|
if (!destCanvas) {
|
|
280
|
-
destCanvas = document.createElement(
|
|
473
|
+
destCanvas = document.createElement('canvas');
|
|
281
474
|
destCanvas.width = clip.w;
|
|
282
475
|
destCanvas.height = clip.h;
|
|
283
|
-
destContext = destCanvas.getContext(
|
|
476
|
+
destContext = destCanvas.getContext('2d');
|
|
284
477
|
}
|
|
478
|
+
|
|
479
|
+
// Draw canvas to the canvas to export.
|
|
285
480
|
destContext.drawImage(
|
|
286
481
|
canvas,
|
|
287
482
|
clip.x,
|
|
@@ -291,30 +486,46 @@ class CanvasSaveButton extends PureComponent {
|
|
|
291
486
|
0,
|
|
292
487
|
0,
|
|
293
488
|
destCanvas.width,
|
|
294
|
-
destCanvas.height
|
|
489
|
+
destCanvas.height,
|
|
295
490
|
);
|
|
296
491
|
}
|
|
492
|
+
|
|
297
493
|
this.margin = CanvasSaveButton.getMargin(destCanvas);
|
|
494
|
+
|
|
495
|
+
// Custom info
|
|
298
496
|
let logoPromise = Promise.resolve();
|
|
299
497
|
if (destContext && extraData && extraData.logo) {
|
|
300
498
|
logoPromise = this.drawElement(extraData.logo, destCanvas);
|
|
301
499
|
}
|
|
500
|
+
|
|
302
501
|
logoPromise.then((logoSize = [0, 0]) => {
|
|
502
|
+
// North arrow
|
|
303
503
|
let arrowPromise = Promise.resolve();
|
|
304
504
|
if (destContext && extraData && extraData.northArrow) {
|
|
305
505
|
arrowPromise = this.drawElement(
|
|
306
506
|
{
|
|
307
|
-
src: extraData.northArrow.circled
|
|
308
|
-
|
|
507
|
+
src: extraData.northArrow.circled
|
|
508
|
+
? NorthArrowCircle
|
|
509
|
+
: NorthArrowSimple,
|
|
510
|
+
...extraData.northArrow,
|
|
309
511
|
},
|
|
310
512
|
destCanvas,
|
|
311
|
-
logoSize
|
|
513
|
+
logoSize,
|
|
312
514
|
);
|
|
313
515
|
}
|
|
516
|
+
|
|
517
|
+
// Copyright
|
|
314
518
|
arrowPromise.then((arrowSize = [0, 0]) => {
|
|
315
519
|
const widestElement = Math.max(logoSize[0], arrowSize[0]);
|
|
316
|
-
if (
|
|
317
|
-
|
|
520
|
+
if (
|
|
521
|
+
destContext &&
|
|
522
|
+
extraData &&
|
|
523
|
+
extraData.copyright &&
|
|
524
|
+
extraData.copyright.text
|
|
525
|
+
) {
|
|
526
|
+
const maxWidth = widestElement
|
|
527
|
+
? destContext.canvas.width - widestElement - this.margin
|
|
528
|
+
: destContext.canvas.width;
|
|
318
529
|
this.drawCopyright(destContext, destCanvas, maxWidth);
|
|
319
530
|
}
|
|
320
531
|
let qrCodePromise = Promise.resolve();
|
|
@@ -322,8 +533,8 @@ class CanvasSaveButton extends PureComponent {
|
|
|
322
533
|
qrCodePromise = this.drawElement(
|
|
323
534
|
extraData.qrCode,
|
|
324
535
|
destCanvas,
|
|
325
|
-
|
|
326
|
-
|
|
536
|
+
undefined,
|
|
537
|
+
'left',
|
|
327
538
|
);
|
|
328
539
|
}
|
|
329
540
|
qrCodePromise.then(() => {
|
|
@@ -335,32 +546,38 @@ class CanvasSaveButton extends PureComponent {
|
|
|
335
546
|
mapToExport.renderSync();
|
|
336
547
|
});
|
|
337
548
|
}
|
|
549
|
+
|
|
338
550
|
downloadCanvasImage(canvas) {
|
|
551
|
+
// Use blob for large images
|
|
339
552
|
const promise = new Promise((resolve) => {
|
|
340
553
|
const { format } = this.props;
|
|
341
554
|
if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {
|
|
555
|
+
// ie 9 and 10
|
|
342
556
|
const url = canvas.toDataURL(format);
|
|
343
|
-
const w = window.open(
|
|
557
|
+
const w = window.open('about:blank', '');
|
|
344
558
|
w.document.write(`<img src="${url}" alt="from canvas"/>`);
|
|
345
559
|
resolve(url);
|
|
346
560
|
}
|
|
347
561
|
if (window.navigator.msSaveBlob) {
|
|
562
|
+
// ie 11 and higher
|
|
348
563
|
let image;
|
|
349
564
|
try {
|
|
350
565
|
image = canvas.msToBlob();
|
|
351
566
|
} catch (e) {
|
|
567
|
+
// eslint-disable-next-line no-console
|
|
352
568
|
console.log(e);
|
|
353
569
|
}
|
|
354
570
|
const blob = new Blob([image], {
|
|
355
|
-
type: format
|
|
571
|
+
type: format,
|
|
356
572
|
});
|
|
357
573
|
resolve(blob);
|
|
358
574
|
window.navigator.msSaveBlob(blob, this.getDownloadImageName());
|
|
359
575
|
} else {
|
|
360
576
|
canvas.toBlob((blob) => {
|
|
361
|
-
const link = document.createElement(
|
|
577
|
+
const link = document.createElement('a');
|
|
362
578
|
link.download = this.getDownloadImageName();
|
|
363
579
|
link.href = URL.createObjectURL(blob);
|
|
580
|
+
// append child to document for firefox to be able to download.
|
|
364
581
|
document.body.appendChild(link);
|
|
365
582
|
link.click();
|
|
366
583
|
resolve(blob);
|
|
@@ -369,8 +586,10 @@ class CanvasSaveButton extends PureComponent {
|
|
|
369
586
|
});
|
|
370
587
|
return promise;
|
|
371
588
|
}
|
|
589
|
+
|
|
372
590
|
render() {
|
|
373
591
|
const { children, ...other } = this.props;
|
|
592
|
+
|
|
374
593
|
delete other.onSaveStart;
|
|
375
594
|
delete other.onSaveEnd;
|
|
376
595
|
delete other.extraData;
|
|
@@ -380,20 +599,28 @@ class CanvasSaveButton extends PureComponent {
|
|
|
380
599
|
delete other.coordinates;
|
|
381
600
|
delete other.autoDownload;
|
|
382
601
|
delete other.scale;
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
602
|
+
|
|
603
|
+
return (
|
|
604
|
+
<div
|
|
605
|
+
role="button"
|
|
606
|
+
className="rs-canvas-save-button"
|
|
607
|
+
tabIndex={0}
|
|
608
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
609
|
+
{...other}
|
|
610
|
+
onClick={(e) => {
|
|
611
|
+
return this.onClick(e);
|
|
612
|
+
}}
|
|
613
|
+
onKeyPress={(e) => {
|
|
614
|
+
return e.which === 13 && this.onClick(e);
|
|
615
|
+
}}
|
|
616
|
+
>
|
|
617
|
+
{children}
|
|
618
|
+
</div>
|
|
619
|
+
);
|
|
395
620
|
}
|
|
396
621
|
}
|
|
622
|
+
|
|
397
623
|
CanvasSaveButton.propTypes = propTypes;
|
|
398
624
|
CanvasSaveButton.defaultProps = defaultProps;
|
|
625
|
+
|
|
399
626
|
export default CanvasSaveButton;
|