react-spatial 1.10.2 → 1.10.3-beta.1

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.
@@ -1,4 +1,4 @@
1
- import React, { PureComponent } from "react";
1
+ import React, { useCallback } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import OLMap from "ol/Map";
4
4
  import { getTopLeft, getBottomRight } from "ol/extent";
@@ -27,6 +27,16 @@ const propTypes = {
27
27
  format: PropTypes.oneOf(["image/jpeg", "image/png"]),
28
28
  /** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */
29
29
  map: PropTypes.instanceOf(OLMap),
30
+ /**
31
+ * Space (in pixels) between the border of the canvas and the elements.
32
+ * Default to 1% of the canvas width.
33
+ */
34
+ margin: PropTypes.number,
35
+ /**
36
+ * Space (in pixels) between elements.
37
+ * Default to 5px.
38
+ */
39
+ padding: PropTypes.number,
30
40
  /**
31
41
  * Extent for the export. If no extent is given, the whole map is exported.
32
42
  */
@@ -110,375 +120,376 @@ const propTypes = {
110
120
  PropTypes.instanceOf(CanvasPatternType)
111
121
  ]),
112
122
  background: PropTypes.bool,
113
- maxWidth: PropTypes.number
123
+ maxWidth: PropTypes.number,
124
+ paddingBottom: PropTypes.number,
125
+ paddingBackground: PropTypes.number
114
126
  })
115
127
  })
116
128
  };
117
- const defaultProps = {
118
- autoDownload: true,
119
- children: null,
120
- map: null,
121
- format: "image/png",
122
- extraData: null,
123
- extent: null,
124
- coordinates: null,
125
- scale: 1,
126
- onSaveStart: (map) => {
127
- return Promise.resolve(map);
128
- },
129
- onSaveEnd: () => {
130
- }
129
+ const getMargin = (destCanvas) => {
130
+ const newMargin = destCanvas.width / 100;
131
+ return newMargin;
131
132
  };
132
- class CanvasSaveButton extends PureComponent {
133
- constructor(props) {
134
- super(props);
135
- this.padding = 5;
136
- }
137
- static getMargin(destCanvas) {
138
- const newMargin = destCanvas.width / 100;
139
- return newMargin;
140
- }
141
- onClick(evt) {
142
- const { map, onSaveStart, onSaveEnd, autoDownload } = this.props;
143
- if (window.navigator.msSaveBlob) {
144
- evt.preventDefault();
145
- evt.stopPropagation();
133
+ const getDownloadImageName = (format) => {
134
+ const fileExt = format === "image/jpeg" ? "jpg" : "png";
135
+ return `${window.document.title.replace(/ /g, "_").toLowerCase()}.${fileExt}`;
136
+ };
137
+ let multilineCopyright = false;
138
+ let copyrightY = 0;
139
+ const decreaseFontSize = (destContext, maxWidth, copyright, scale) => {
140
+ const minFontSize = 8;
141
+ let sizeMatch;
142
+ let fontSize;
143
+ do {
144
+ sizeMatch = destContext.font.match(/[0-9]+(?:\.[0-9]+)?(px)/i);
145
+ fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], ""), 10);
146
+ destContext.font = destContext.font.replace(fontSize, fontSize - 1);
147
+ multilineCopyright = false;
148
+ if (fontSize - 1 === minFontSize) {
149
+ multilineCopyright = true;
146
150
  }
147
- onSaveStart(map).then((mapToExport) => {
148
- return this.createCanvasImage(mapToExport || map).then((canvas) => {
149
- if (autoDownload) {
150
- this.downloadCanvasImage(canvas).then((blob) => {
151
- onSaveEnd(mapToExport, canvas, blob);
152
- });
153
- } else {
154
- onSaveEnd(mapToExport, canvas);
155
- }
156
- }).catch((err) => {
157
- if (err) {
158
- console.error(err);
159
- }
160
- onSaveEnd(mapToExport, err);
161
- });
151
+ } while (fontSize - 1 > minFontSize && destContext.measureText(copyright).width * scale > maxWidth);
152
+ return destContext.font;
153
+ };
154
+ const drawTextBackground = (destContext, x, y, width, height, styleOptions = {}) => {
155
+ destContext.save();
156
+ destContext.fillStyle = "rgba(255,255,255,.8)";
157
+ if (typeof styleOptions === "object") {
158
+ Object.entries(styleOptions).forEach(([key, value]) => {
159
+ destContext[key] = value;
162
160
  });
163
161
  }
164
- getDownloadImageName() {
165
- const { format } = this.props;
166
- const fileExt = format === "image/jpeg" ? "jpg" : "png";
167
- return `${window.document.title.replace(/ /g, "_").toLowerCase()}.${fileExt}`;
168
- }
169
- // Ensure the font size fita with the image width.
170
- decreaseFontSize(destContext, maxWidth, copyright, scale) {
171
- const minFontSize = 8;
172
- let sizeMatch;
173
- let fontSize;
174
- do {
175
- sizeMatch = destContext.font.match(/[0-9]+(?:\.[0-9]+)?(px)/i);
176
- fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], ""), 10);
177
- destContext.font = destContext.font.replace(fontSize, fontSize - 1);
178
- this.multilineCopyright = null;
179
- if (fontSize - 1 === minFontSize) {
180
- this.multilineCopyright = true;
181
- }
182
- } while (fontSize - 1 > minFontSize && destContext.measureText(copyright).width * scale > maxWidth);
183
- return destContext.font;
184
- }
185
- // eslint-disable-next-line class-methods-use-this
186
- drawTextBackground(destContext, textMeasure, textX, textY, padding, styleOptions = {}) {
187
- const { width, height, actualBoundingBoxAscent } = textMeasure;
188
- destContext.save();
189
- destContext.fillStyle = "rgba(255,255,255,.8)";
190
- if (typeof styleOptions === "object") {
191
- Object.entries(styleOptions).forEach(([key, value]) => {
192
- destContext[key] = value;
193
- });
194
- }
195
- destContext.fillRect(
196
- textX - padding,
197
- textY - actualBoundingBoxAscent - padding,
198
- width + padding * 2,
199
- height + padding * 2
200
- );
201
- destContext.restore();
162
+ destContext.fillRect(x, y, width, height);
163
+ destContext.restore();
164
+ };
165
+ const drawCopyright = (destContext, destCanvas, maxWidth, extraData, scale, margin, padding) => {
166
+ const { text, font, fillStyle, background } = extraData.copyright;
167
+ const { paddingBottom = padding, paddingBackground = 2 } = extraData.copyright;
168
+ let copyright = typeof text === "function" ? text() : text?.trim();
169
+ if (Array.isArray(copyright)) {
170
+ copyright = copyright.join();
202
171
  }
203
- drawCopyright(destContext, destCanvas, maxWidth) {
204
- const { extraData, scale } = this.props;
205
- const { text, font, fillStyle, background } = extraData.copyright;
206
- let copyright = typeof text === "function" ? text() : text;
207
- if (Array.isArray(copyright)) {
208
- copyright = copyright.join();
209
- }
210
- destContext.save();
211
- destContext.scale(scale, scale);
212
- destContext.font = font || "12px Arial";
213
- destContext.font = this.decreaseFontSize(
214
- destContext,
215
- maxWidth - this.padding,
216
- copyright,
217
- scale
218
- );
219
- destContext.scale(scale, scale);
220
- destContext.fillStyle = fillStyle || "black";
221
- let firstLine = copyright;
172
+ destContext.save();
173
+ destContext.scale(scale, scale);
174
+ destContext.font = font || "12px Arial";
175
+ destContext.font = decreaseFontSize(destContext, maxWidth, copyright, scale);
176
+ destContext.textBaseline = "bottom";
177
+ destContext.scale(scale, scale);
178
+ destContext.fillStyle = fillStyle || "black";
179
+ let firstLine = copyright;
180
+ let firstLineMetrics = destContext.measureText(firstLine);
181
+ if (multilineCopyright) {
222
182
  const wordNumber = copyright.split(" ").length;
223
- if (this.multilineCopyright) {
224
- for (let i = 0; i < wordNumber; i += 1) {
225
- firstLine = firstLine.substring(0, firstLine.lastIndexOf(" "));
226
- if (destContext.measureText(firstLine).width * scale < maxWidth - this.padding) {
227
- break;
228
- }
183
+ for (let i = 0; i < wordNumber; i += 1) {
184
+ if (firstLineMetrics.width * scale < maxWidth) {
185
+ break;
229
186
  }
187
+ firstLine = firstLine.substring(0, firstLine.lastIndexOf(" "));
188
+ firstLineMetrics = destContext.measureText(firstLine);
230
189
  }
231
- const secondLine = copyright.replace(firstLine, "");
232
- const textX = this.margin;
233
- let textMeasure = destContext.measureText(firstLine);
234
- textMeasure.height = textMeasure.actualBoundingBoxAscent + textMeasure.actualBoundingBoxDescent;
235
- let firstLineY = destCanvas.height / scale - this.padding;
236
- const secondLineY = firstLineY;
237
- const paddingBetweenLines = 3;
238
- const paddingBackground = paddingBetweenLines / 2;
239
- if (secondLine) {
240
- firstLineY -= textMeasure.height + paddingBetweenLines;
241
- }
190
+ }
191
+ const secondLine = copyright.replace(firstLine, "").trim();
192
+ const lines = [firstLine, secondLine].filter((l) => !!l).reverse();
193
+ let lineX = margin;
194
+ let lineY = destCanvas.height - paddingBottom;
195
+ lines.forEach((line) => {
196
+ const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } = destContext.measureText(line);
197
+ const height = fontBoundingBoxAscent + fontBoundingBoxDescent;
198
+ let lineTop = lineY - height;
242
199
  if (background) {
243
- this.drawTextBackground(
200
+ const backgroundX = margin;
201
+ lineTop -= paddingBackground * 2;
202
+ drawTextBackground(
244
203
  destContext,
245
- textMeasure,
246
- textX,
247
- firstLineY,
248
- paddingBackground,
204
+ backgroundX,
205
+ lineTop,
206
+ width + paddingBackground * 2,
207
+ height + paddingBackground * 2,
249
208
  background
250
209
  );
210
+ lineX += paddingBackground;
211
+ lineY -= paddingBackground;
251
212
  }
252
- destContext.fillText(firstLine, textX, firstLineY);
253
- if (secondLine) {
254
- textMeasure = destContext.measureText(secondLine);
255
- textMeasure.height = textMeasure.actualBoundingBoxAscent + textMeasure.actualBoundingBoxDescent;
256
- if (background) {
257
- this.drawTextBackground(
258
- destContext,
259
- textMeasure,
260
- textX,
261
- secondLineY,
262
- paddingBackground,
263
- background
264
- );
213
+ destContext.fillText(line, lineX, lineY);
214
+ lineY = lineTop;
215
+ });
216
+ copyrightY = lineY;
217
+ destContext.restore();
218
+ };
219
+ const drawElement = (data, destCanvas, scale, margin, padding, previousItemSize = [0, 0], side = "right") => {
220
+ const destContext = destCanvas.getContext("2d");
221
+ const { src, width, height, rotation } = data;
222
+ return new Promise((resolve) => {
223
+ const img = new Image();
224
+ img.crossOrigin = "Anonymous";
225
+ img.src = src;
226
+ img.onload = () => {
227
+ destContext.save();
228
+ const elementWidth = (width || 80) * scale;
229
+ const elementHeight = (height || 80) * scale;
230
+ const left = side === "left" ? margin + elementWidth / 2 : destCanvas.width - margin - elementWidth / 2;
231
+ const top = (side === "left" && copyrightY ? copyrightY - padding : destCanvas.height) - margin - elementHeight / 2 - previousItemSize[1];
232
+ destContext.translate(left, top);
233
+ if (rotation) {
234
+ const angle = typeof rotation === "function" ? rotation() : rotation;
235
+ destContext.rotate(angle * (Math.PI / 180));
265
236
  }
266
- destContext.fillText(secondLine, textX, secondLineY);
267
- }
268
- const firstLineMetrics = destContext.measureText(firstLine);
269
- const secondLineMetrics = destContext.measureText(secondLine);
270
- const heightFirstLine = firstLineMetrics.actualBoundingBoxAscent + firstLineMetrics.actualBoundingBoxDescent;
271
- const heightSecondLine = secondLineMetrics.actualBoundingBoxAscent + secondLineMetrics.actualBoundingBoxDescent;
272
- this.copyrightY = destCanvas.height - (heightFirstLine + paddingBetweenLines + heightSecondLine) / 2;
273
- destContext.restore();
237
+ destContext.drawImage(
238
+ img,
239
+ -elementWidth / 2,
240
+ -elementHeight / 2,
241
+ elementWidth,
242
+ elementHeight
243
+ );
244
+ destContext.restore();
245
+ resolve([elementWidth + 2 * padding, elementHeight + 2 * padding]);
246
+ };
247
+ img.onerror = () => {
248
+ resolve();
249
+ };
250
+ });
251
+ };
252
+ const calculatePixelsToExport = (mapToExport, extent, coordinates) => {
253
+ let firstCoordinate;
254
+ let oppositeCoordinate;
255
+ if (extent) {
256
+ firstCoordinate = getTopLeft(extent);
257
+ oppositeCoordinate = getBottomRight(extent);
258
+ } else if (coordinates) {
259
+ [firstCoordinate, , oppositeCoordinate] = coordinates;
274
260
  }
275
- drawElement(data, destCanvas, previousItemSize = [0, 0], side = "right") {
276
- const destContext = destCanvas.getContext("2d");
277
- const { scale } = this.props;
278
- const { src, width, height, rotation } = data;
279
- return new Promise((resolve) => {
280
- const img = new Image();
281
- img.crossOrigin = "Anonymous";
282
- img.src = src;
283
- img.onload = () => {
284
- destContext.save();
285
- const elementWidth = (width || 80) * scale;
286
- const elementHeight = (height || 80) * scale;
287
- const left = side === "left" ? this.margin + elementWidth / 2 : destCanvas.width - this.margin - elementWidth / 2;
288
- const top = (side === "left" && this.copyrightY ? this.copyrightY - 2 * this.padding : destCanvas.height) - this.margin - elementHeight / 2 - previousItemSize[1];
289
- destContext.translate(left, top);
290
- if (rotation) {
291
- const angle = typeof rotation === "function" ? rotation() : rotation;
292
- destContext.rotate(angle * (Math.PI / 180));
261
+ if (firstCoordinate && oppositeCoordinate) {
262
+ const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);
263
+ const oppositePixel = mapToExport.getPixelFromCoordinate(oppositeCoordinate);
264
+ const pixelTopLeft = [
265
+ firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
266
+ firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
267
+ ];
268
+ const pixelBottomRight = [
269
+ firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
270
+ firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
271
+ ];
272
+ return {
273
+ x: pixelTopLeft[0],
274
+ y: pixelTopLeft[1],
275
+ w: pixelBottomRight[0] - pixelTopLeft[0],
276
+ h: pixelBottomRight[1] - pixelTopLeft[1]
277
+ };
278
+ }
279
+ return null;
280
+ };
281
+ const createCanvasImage = (mapToExport, extraData, scale, extent, coordinates, margin, padding) => {
282
+ return new Promise((resolve) => {
283
+ mapToExport.once("rendercomplete", () => {
284
+ const canvases = mapToExport.getTargetElement().getElementsByTagName("canvas");
285
+ let destCanvas;
286
+ let destContext;
287
+ for (let i = 0; i < canvases.length; i += 1) {
288
+ const canvas = canvases[i];
289
+ if (!canvas.width || !canvas.height) {
290
+ continue;
291
+ }
292
+ const clip = calculatePixelsToExport(
293
+ mapToExport,
294
+ extent,
295
+ coordinates
296
+ ) || {
297
+ x: 0,
298
+ y: 0,
299
+ w: canvas.width,
300
+ h: canvas.height
301
+ };
302
+ if (!destCanvas) {
303
+ destCanvas = document.createElement("canvas");
304
+ destCanvas.width = clip.w;
305
+ destCanvas.height = clip.h;
306
+ destContext = destCanvas.getContext("2d");
293
307
  }
294
308
  destContext.drawImage(
295
- img,
296
- -elementWidth / 2,
297
- -elementHeight / 2,
298
- elementWidth,
299
- elementHeight
309
+ canvas,
310
+ clip.x,
311
+ clip.y,
312
+ clip.w,
313
+ clip.h,
314
+ 0,
315
+ 0,
316
+ destCanvas.width,
317
+ destCanvas.height
300
318
  );
301
- destContext.restore();
302
- resolve([
303
- elementWidth + 2 * this.padding,
304
- elementHeight + 2 * this.padding
305
- ]);
306
- };
307
- img.onerror = () => {
308
- resolve();
309
- };
310
- });
311
- }
312
- calculatePixelsToExport(mapToExport) {
313
- const { extent, coordinates } = this.props;
314
- let firstCoordinate;
315
- let oppositeCoordinate;
316
- if (extent) {
317
- firstCoordinate = getTopLeft(extent);
318
- oppositeCoordinate = getBottomRight(extent);
319
- } else if (coordinates) {
320
- [firstCoordinate, , oppositeCoordinate] = coordinates;
321
- }
322
- if (firstCoordinate && oppositeCoordinate) {
323
- const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);
324
- const oppositePixel = mapToExport.getPixelFromCoordinate(oppositeCoordinate);
325
- const pixelTopLeft = [
326
- firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
327
- firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
328
- ];
329
- const pixelBottomRight = [
330
- firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],
331
- firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1]
332
- ];
333
- return {
334
- x: pixelTopLeft[0],
335
- y: pixelTopLeft[1],
336
- w: pixelBottomRight[0] - pixelTopLeft[0],
337
- h: pixelBottomRight[1] - pixelTopLeft[1]
338
- };
339
- }
340
- return null;
341
- }
342
- createCanvasImage(mapToExport) {
343
- const { extraData } = this.props;
344
- return new Promise((resolve) => {
345
- mapToExport.once("rendercomplete", () => {
346
- const canvases = mapToExport.getTargetElement().getElementsByTagName("canvas");
347
- let destCanvas;
348
- let destContext;
349
- for (let i = 0; i < canvases.length; i += 1) {
350
- const canvas = canvases[i];
351
- if (!canvas.width || !canvas.height) {
352
- continue;
353
- }
354
- const clip = this.calculatePixelsToExport(mapToExport) || {
355
- x: 0,
356
- y: 0,
357
- w: canvas.width,
358
- h: canvas.height
359
- };
360
- if (!destCanvas) {
361
- destCanvas = document.createElement("canvas");
362
- destCanvas.width = clip.w;
363
- destCanvas.height = clip.h;
364
- destContext = destCanvas.getContext("2d");
365
- }
366
- destContext.drawImage(
367
- canvas,
368
- clip.x,
369
- clip.y,
370
- clip.w,
371
- clip.h,
372
- 0,
373
- 0,
374
- destCanvas.width,
375
- destCanvas.height
319
+ }
320
+ margin = margin || getMargin(destCanvas);
321
+ let logoPromise = Promise.resolve();
322
+ if (destContext && extraData && extraData.logo) {
323
+ logoPromise = drawElement(
324
+ extraData.logo,
325
+ destCanvas,
326
+ scale,
327
+ margin,
328
+ padding
329
+ );
330
+ }
331
+ logoPromise.then((logoSize = [0, 0]) => {
332
+ let arrowPromise = Promise.resolve();
333
+ if (destContext && extraData && extraData.northArrow) {
334
+ arrowPromise = drawElement(
335
+ {
336
+ src: extraData.northArrow.circled ? NorthArrowCircle : NorthArrowSimple,
337
+ ...extraData.northArrow
338
+ },
339
+ destCanvas,
340
+ scale,
341
+ margin,
342
+ padding,
343
+ logoSize
376
344
  );
377
345
  }
378
- this.margin = CanvasSaveButton.getMargin(destCanvas);
379
- let logoPromise = Promise.resolve();
380
- if (destContext && extraData && extraData.logo) {
381
- logoPromise = this.drawElement(extraData.logo, destCanvas);
382
- }
383
- logoPromise.then((logoSize = [0, 0]) => {
384
- let arrowPromise = Promise.resolve();
385
- if (destContext && extraData && extraData.northArrow) {
386
- arrowPromise = this.drawElement(
387
- {
388
- src: extraData.northArrow.circled ? NorthArrowCircle : NorthArrowSimple,
389
- ...extraData.northArrow
390
- },
346
+ arrowPromise.then((arrowSize = [0, 0]) => {
347
+ const widestElement = Math.max(logoSize[0], arrowSize[0]);
348
+ if (destContext && extraData && extraData.copyright && extraData.copyright.text) {
349
+ const maxWidth = extraData.copyright.maxWidth || (widestElement ? destContext.canvas.width - widestElement - margin : destContext.canvas.width);
350
+ drawCopyright(
351
+ destContext,
391
352
  destCanvas,
392
- logoSize
353
+ maxWidth,
354
+ extraData,
355
+ scale,
356
+ margin,
357
+ padding
393
358
  );
394
359
  }
395
- arrowPromise.then((arrowSize = [0, 0]) => {
396
- const widestElement = Math.max(logoSize[0], arrowSize[0]);
397
- if (destContext && extraData && extraData.copyright && extraData.copyright.text) {
398
- const maxWidth = extraData.copyright.maxWidth || (widestElement ? destContext.canvas.width - widestElement - this.margin : destContext.canvas.width);
399
- this.drawCopyright(destContext, destCanvas, maxWidth);
400
- }
401
- let qrCodePromise = Promise.resolve();
402
- if (destContext && extraData && extraData.qrCode) {
403
- qrCodePromise = this.drawElement(
404
- extraData.qrCode,
405
- destCanvas,
406
- void 0,
407
- "left"
408
- );
409
- }
410
- qrCodePromise.then(() => {
411
- return resolve(destCanvas);
412
- });
360
+ let qrCodePromise = Promise.resolve();
361
+ if (destContext && extraData && extraData.qrCode) {
362
+ qrCodePromise = drawElement(
363
+ extraData.qrCode,
364
+ destCanvas,
365
+ scale,
366
+ margin,
367
+ padding,
368
+ void 0,
369
+ "left"
370
+ );
371
+ }
372
+ qrCodePromise.then(() => {
373
+ return resolve(destCanvas);
413
374
  });
414
375
  });
415
376
  });
416
- mapToExport.renderSync();
417
377
  });
418
- }
419
- downloadCanvasImage(canvas) {
420
- const promise = new Promise((resolve) => {
421
- const { format } = this.props;
422
- if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {
423
- const url = canvas.toDataURL(format);
424
- const w = window.open("about:blank", "");
425
- w.document.write(`<img src="${url}" alt="from canvas"/>`);
426
- resolve(url);
378
+ mapToExport.renderSync();
379
+ });
380
+ };
381
+ const downloadCanvasImage = (canvas, format) => {
382
+ const promise = new Promise((resolve) => {
383
+ if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {
384
+ const url = canvas.toDataURL(format);
385
+ const w = window.open("about:blank", "");
386
+ w.document.write(`<img src="${url}" alt="from canvas"/>`);
387
+ resolve(url);
388
+ }
389
+ if (window.navigator.msSaveBlob) {
390
+ let image;
391
+ try {
392
+ image = canvas.msToBlob();
393
+ } catch (e) {
394
+ console.log(e);
427
395
  }
396
+ const blob = new Blob([image], {
397
+ type: format
398
+ });
399
+ resolve(blob);
400
+ window.navigator.msSaveBlob(blob, getDownloadImageName(format));
401
+ } else {
402
+ canvas.toBlob((blob) => {
403
+ const link = document.createElement("a");
404
+ link.download = getDownloadImageName(format);
405
+ link.href = URL.createObjectURL(blob);
406
+ document.body.appendChild(link);
407
+ link.click();
408
+ resolve(blob);
409
+ }, format);
410
+ }
411
+ });
412
+ return promise;
413
+ };
414
+ function CanvasSaveButton({
415
+ margin = null,
416
+ padding = 5,
417
+ autoDownload = true,
418
+ children = null,
419
+ map = null,
420
+ format = "image/png",
421
+ extraData = null,
422
+ extent = null,
423
+ coordinates = null,
424
+ scale = 1,
425
+ onSaveStart = (mapp) => {
426
+ return Promise.resolve(mapp);
427
+ },
428
+ onSaveEnd = () => {
429
+ },
430
+ ...props
431
+ }) {
432
+ const onClick = useCallback(
433
+ (evt) => {
428
434
  if (window.navigator.msSaveBlob) {
429
- let image;
430
- try {
431
- image = canvas.msToBlob();
432
- } catch (e) {
433
- console.log(e);
434
- }
435
- const blob = new Blob([image], {
436
- type: format
435
+ evt.preventDefault();
436
+ evt.stopPropagation();
437
+ }
438
+ multilineCopyright = false;
439
+ copyrightY = 0;
440
+ onSaveStart(map).then((mapToExport) => {
441
+ return createCanvasImage(
442
+ mapToExport || map,
443
+ extraData,
444
+ scale,
445
+ extent,
446
+ coordinates,
447
+ margin,
448
+ padding
449
+ ).then((canvas) => {
450
+ if (autoDownload) {
451
+ downloadCanvasImage(canvas, format).then((blob) => {
452
+ onSaveEnd(mapToExport, canvas, blob);
453
+ });
454
+ } else {
455
+ onSaveEnd(mapToExport, canvas);
456
+ }
457
+ }).catch((err) => {
458
+ if (err) {
459
+ console.error(err);
460
+ }
461
+ onSaveEnd(mapToExport, err);
437
462
  });
438
- resolve(blob);
439
- window.navigator.msSaveBlob(blob, this.getDownloadImageName());
440
- } else {
441
- canvas.toBlob((blob) => {
442
- const link = document.createElement("a");
443
- link.download = this.getDownloadImageName();
444
- link.href = URL.createObjectURL(blob);
445
- document.body.appendChild(link);
446
- link.click();
447
- resolve(blob);
448
- }, format);
463
+ });
464
+ },
465
+ [
466
+ autoDownload,
467
+ coordinates,
468
+ extent,
469
+ extraData,
470
+ format,
471
+ map,
472
+ margin,
473
+ onSaveEnd,
474
+ onSaveStart,
475
+ padding,
476
+ scale
477
+ ]
478
+ );
479
+ return /* @__PURE__ */ React.createElement(
480
+ "div",
481
+ {
482
+ role: "button",
483
+ className: "rs-canvas-save-button",
484
+ tabIndex: 0,
485
+ ...props,
486
+ onClick,
487
+ onKeyPress: (evt) => {
488
+ return evt.which === 13 && onClick(evt);
449
489
  }
450
- });
451
- return promise;
452
- }
453
- render() {
454
- const { children, ...other } = this.props;
455
- delete other.onSaveStart;
456
- delete other.onSaveEnd;
457
- delete other.extraData;
458
- delete other.extent;
459
- delete other.format;
460
- delete other.map;
461
- delete other.coordinates;
462
- delete other.autoDownload;
463
- delete other.scale;
464
- return /* @__PURE__ */ React.createElement(
465
- "div",
466
- {
467
- role: "button",
468
- className: "rs-canvas-save-button",
469
- tabIndex: 0,
470
- ...other,
471
- onClick: (e) => {
472
- return this.onClick(e);
473
- },
474
- onKeyPress: (e) => {
475
- return e.which === 13 && this.onClick(e);
476
- }
477
- },
478
- children
479
- );
480
- }
490
+ },
491
+ children
492
+ );
481
493
  }
482
494
  CanvasSaveButton.propTypes = propTypes;
483
- CanvasSaveButton.defaultProps = defaultProps;
484
495
  export default CanvasSaveButton;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/CanvasSaveButton/CanvasSaveButton.js"],
4
- "sourcesContent": ["/* eslint-disable no-param-reassign */\nimport React, { PureComponent } from \"react\";\nimport PropTypes from \"prop-types\";\nimport OLMap from \"ol/Map\";\nimport { getTopLeft, getBottomRight } from \"ol/extent\";\nimport NorthArrowSimple from \"../../images/northArrow.url.svg\";\nimport NorthArrowCircle from \"../../images/northArrowCircle.url.svg\";\n\nconst extraDataImgPropType = PropTypes.shape({\n src: PropTypes.string,\n width: PropTypes.number,\n height: PropTypes.number,\n rotation: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),\n circled: PropTypes.bool,\n});\n\n// support server-side rendering where `Element` will not be defined\nconst CanvasPatternType =\n typeof CanvasPattern === \"undefined\" ? Function : CanvasPattern;\n\nconst propTypes = {\n /**\n * Automatically download the image saved.\n */\n autoDownload: PropTypes.bool,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.node,\n\n /**\n * Output format of the image.\n */\n format: PropTypes.oneOf([\"image/jpeg\", \"image/png\"]),\n\n /** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */\n map: PropTypes.instanceOf(OLMap),\n\n /**\n * Extent for the export. If no extent is given, the whole map is exported.\n */\n extent: PropTypes.arrayOf(PropTypes.number),\n\n /**\n * Array of 4 [ol/Coordinate](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~Coordinate).\n * If no coordinates and no extent are given, the whole map is exported.\n * This property must be used to export rotated map.\n * If you don't need to export rotated map the extent property can be used as well.\n * If extent is specified, coordinates property is ignored.\n */\n coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),\n\n /**\n * Scale the map for better quality. Possible values: 1, 2 or 3.\n * WARNING: The tiled layer with a WMTS or XYZ source must provides an url\n * for each scale in the config file.\n */\n scale: PropTypes.number,\n\n /**\n * Function called before the dowload process begins.\n */\n onSaveStart: PropTypes.func,\n\n /**\n * Function called after the dowload process ends.\n *\n * @param {object} error Error message the process fails.\n */\n onSaveEnd: PropTypes.func,\n\n /**\n * Extra data, such as copyright, north arrow configuration.\n * All extra data is optional.\n *\n * Example 1:\n *\n {\n copyright: {\n text: 'Example copyright', // Copyright text or function\n font: '10px Arial', // Font, default is '12px Arial'\n fillStyle: 'blue', // Fill style, default is 'black'\n },\n northArrow, // True if the north arrow\n // should be placed with default configuration\n // (default image, rotation=0, circled=false)\n }\n * Example 2:\n *\n {\n northArrow: {\n src: NorthArrowCustom,\n width: 60, // Width in px, default is 80\n height: 100, // Height in px, default is 80\n rotation: 25, // Absolute rotation in degrees as number or function\n\n }\n }\n * Example 3:\n *\n {\n copyright: {\n text: () => { // Copyright as function\n return this.copyright;\n },\n },\n northArrow: {\n rotation: () => { // Rotation as function\n return NorthArrow.radToDeg(this.map.getView().getRotation());\n },\n circled, // Display circle around the north arrow (Does not work for custom src)\n },\n }\n */\n extraData: PropTypes.shape({\n logo: extraDataImgPropType,\n northArrow: extraDataImgPropType,\n qrCode: extraDataImgPropType,\n copyright: PropTypes.shape({\n text: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n font: PropTypes.string,\n fillStyle: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.instanceOf(CanvasPatternType),\n ]),\n background: PropTypes.bool,\n maxWidth: PropTypes.number,\n }),\n }),\n};\n\nconst defaultProps = {\n autoDownload: true,\n children: null,\n map: null,\n format: \"image/png\",\n extraData: null,\n extent: null,\n coordinates: null,\n scale: 1,\n onSaveStart: (map) => {\n return Promise.resolve(map);\n },\n onSaveEnd: () => {},\n};\n\n/**\n * The CanvasSaveButton component creates a button to save\n * an [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)\n * canvas as an image.\n */\nclass CanvasSaveButton extends PureComponent {\n constructor(props) {\n super(props);\n this.padding = 5;\n }\n\n static getMargin(destCanvas) {\n const newMargin = destCanvas.width / 100; // 1% of the canvas width\n return newMargin;\n }\n\n onClick(evt) {\n const { map, onSaveStart, onSaveEnd, autoDownload } = this.props;\n if (window.navigator.msSaveBlob) {\n // ie only\n evt.preventDefault();\n evt.stopPropagation();\n }\n onSaveStart(map).then((mapToExport) => {\n return this.createCanvasImage(mapToExport || map)\n .then((canvas) => {\n if (autoDownload) {\n this.downloadCanvasImage(canvas).then((blob) => {\n onSaveEnd(mapToExport, canvas, blob);\n });\n } else {\n onSaveEnd(mapToExport, canvas);\n }\n })\n .catch((err) => {\n if (err) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n onSaveEnd(mapToExport, err);\n });\n });\n }\n\n getDownloadImageName() {\n const { format } = this.props;\n const fileExt = format === \"image/jpeg\" ? \"jpg\" : \"png\";\n return (\n `${window.document.title.replace(/ /g, \"_\").toLowerCase()}` +\n `.${fileExt}`\n );\n }\n\n // Ensure the font size fita with the image width.\n decreaseFontSize(destContext, maxWidth, copyright, scale) {\n const minFontSize = 8;\n let sizeMatch;\n let fontSize;\n do {\n sizeMatch = destContext.font.match(/[0-9]+(?:\\.[0-9]+)?(px)/i);\n fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], \"\"), 10);\n\n // eslint-disable-next-line no-param-reassign\n destContext.font = destContext.font.replace(fontSize, fontSize - 1);\n\n this.multilineCopyright = null;\n\n if (fontSize - 1 === minFontSize) {\n this.multilineCopyright = true;\n }\n } while (\n fontSize - 1 > minFontSize &&\n destContext.measureText(copyright).width * scale > maxWidth\n );\n\n return destContext.font;\n }\n\n // eslint-disable-next-line class-methods-use-this\n drawTextBackground(\n destContext,\n textMeasure,\n textX,\n textY,\n padding,\n styleOptions = {},\n ) {\n /// get width of text\n const { width, height, actualBoundingBoxAscent } = textMeasure;\n destContext.save();\n // Dflt is a white background\n destContext.fillStyle = \"rgba(255,255,255,.8)\";\n\n // To simplify usability the user could pass a boolean to use only default values.\n if (typeof styleOptions === \"object\") {\n Object.entries(styleOptions).forEach(([key, value]) => {\n destContext[key] = value;\n });\n }\n\n /// draw background rect assuming height of font\n destContext.fillRect(\n textX - padding,\n textY - actualBoundingBoxAscent - padding,\n width + padding * 2,\n height + padding * 2,\n );\n destContext.restore();\n }\n\n drawCopyright(destContext, destCanvas, maxWidth) {\n const { extraData, scale } = this.props;\n const { text, font, fillStyle, background } = extraData.copyright;\n let copyright = typeof text === \"function\" ? text() : text;\n\n if (Array.isArray(copyright)) {\n copyright = copyright.join();\n }\n\n destContext.save();\n destContext.scale(scale, scale);\n destContext.font = font || \"12px Arial\";\n destContext.font = this.decreaseFontSize(\n destContext,\n maxWidth - this.padding,\n copyright,\n scale,\n );\n\n destContext.scale(scale, scale);\n destContext.fillStyle = fillStyle || \"black\";\n\n // We search if the display on 2 line is necessary\n let firstLine = copyright;\n const wordNumber = copyright.split(\" \").length;\n\n // If the text is bigger than the max width we split it into 2 lines\n if (this.multilineCopyright) {\n for (let i = 0; i < wordNumber; i += 1) {\n firstLine = firstLine.substring(0, firstLine.lastIndexOf(\" \"));\n // Stop removing word when fits within one line.\n if (\n destContext.measureText(firstLine).width * scale <\n maxWidth - this.padding\n ) {\n break;\n }\n }\n }\n const secondLine = copyright.replace(firstLine, \"\");\n\n // Draw first line (line break isn't supported for fillText).\n const textX = this.margin;\n let textMeasure = destContext.measureText(firstLine);\n textMeasure.height =\n textMeasure.actualBoundingBoxAscent +\n textMeasure.actualBoundingBoxDescent;\n let firstLineY = destCanvas.height / scale - this.padding;\n const secondLineY = firstLineY;\n const paddingBetweenLines = 3;\n const paddingBackground = paddingBetweenLines / 2;\n\n if (secondLine) {\n firstLineY -= textMeasure.height + paddingBetweenLines;\n }\n if (background) {\n this.drawTextBackground(\n destContext,\n textMeasure,\n textX,\n firstLineY,\n paddingBackground,\n background,\n );\n }\n destContext.fillText(firstLine, textX, firstLineY);\n\n // Draw second line.\n if (secondLine) {\n textMeasure = destContext.measureText(secondLine);\n textMeasure.height =\n textMeasure.actualBoundingBoxAscent +\n textMeasure.actualBoundingBoxDescent;\n if (background) {\n this.drawTextBackground(\n destContext,\n textMeasure,\n textX,\n secondLineY,\n paddingBackground,\n background,\n );\n }\n destContext.fillText(secondLine, textX, secondLineY);\n }\n\n const firstLineMetrics = destContext.measureText(firstLine);\n const secondLineMetrics = destContext.measureText(secondLine);\n const heightFirstLine =\n firstLineMetrics.actualBoundingBoxAscent +\n firstLineMetrics.actualBoundingBoxDescent;\n const heightSecondLine =\n secondLineMetrics.actualBoundingBoxAscent +\n secondLineMetrics.actualBoundingBoxDescent;\n this.copyrightY =\n destCanvas.height -\n (heightFirstLine + paddingBetweenLines + heightSecondLine) / 2;\n destContext.restore();\n }\n\n drawElement(data, destCanvas, previousItemSize = [0, 0], side = \"right\") {\n const destContext = destCanvas.getContext(\"2d\");\n const { scale } = this.props;\n const { src, width, height, rotation } = data;\n\n return new Promise((resolve) => {\n const img = new Image();\n img.crossOrigin = \"Anonymous\";\n img.src = src;\n img.onload = () => {\n destContext.save();\n const elementWidth = (width || 80) * scale;\n const elementHeight = (height || 80) * scale;\n const left =\n side === \"left\"\n ? this.margin + elementWidth / 2\n : destCanvas.width - this.margin - elementWidth / 2;\n const top =\n (side === \"left\" && this.copyrightY\n ? this.copyrightY - 2 * this.padding\n : destCanvas.height) -\n this.margin -\n elementHeight / 2 -\n previousItemSize[1];\n\n destContext.translate(left, top);\n\n if (rotation) {\n const angle = typeof rotation === \"function\" ? rotation() : rotation;\n destContext.rotate(angle * (Math.PI / 180));\n }\n\n destContext.drawImage(\n img,\n -elementWidth / 2,\n -elementHeight / 2,\n elementWidth,\n elementHeight,\n );\n destContext.restore();\n\n // Return the pixels width of the arrow and the margin right,\n // that must not be occupied by the copyright.\n resolve([\n elementWidth + 2 * this.padding,\n elementHeight + 2 * this.padding,\n ]);\n };\n\n img.onerror = () => {\n resolve();\n };\n });\n }\n\n calculatePixelsToExport(mapToExport) {\n const { extent, coordinates } = this.props;\n let firstCoordinate;\n let oppositeCoordinate;\n\n if (extent) {\n firstCoordinate = getTopLeft(extent);\n oppositeCoordinate = getBottomRight(extent);\n } else if (coordinates) {\n // In case of coordinates coming from DragBox interaction:\n // firstCoordinate is the first coordinate drawn by the user.\n // oppositeCoordinate is the coordinate of the point dragged by the user.\n [firstCoordinate, , oppositeCoordinate] = coordinates;\n }\n\n if (firstCoordinate && oppositeCoordinate) {\n const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);\n const oppositePixel =\n mapToExport.getPixelFromCoordinate(oppositeCoordinate);\n const pixelTopLeft = [\n firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n const pixelBottomRight = [\n firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n\n return {\n x: pixelTopLeft[0],\n y: pixelTopLeft[1],\n w: pixelBottomRight[0] - pixelTopLeft[0],\n h: pixelBottomRight[1] - pixelTopLeft[1],\n };\n }\n return null;\n }\n\n createCanvasImage(mapToExport) {\n const { extraData } = this.props;\n\n return new Promise((resolve) => {\n mapToExport.once(\"rendercomplete\", () => {\n // Find all layer canvases and add it to dest canvas.\n const canvases = mapToExport\n .getTargetElement()\n .getElementsByTagName(\"canvas\");\n\n // Create the canvas to export with the good size.\n let destCanvas;\n let destContext;\n\n // canvases is an HTMLCollection, we don't try to transform to array because some compilers like cra doesn't translate it right.\n for (let i = 0; i < canvases.length; i += 1) {\n const canvas = canvases[i];\n if (!canvas.width || !canvas.height) {\n // eslint-disable-next-line no-continue\n continue;\n }\n const clip = this.calculatePixelsToExport(mapToExport) || {\n x: 0,\n y: 0,\n w: canvas.width,\n h: canvas.height,\n };\n\n if (!destCanvas) {\n destCanvas = document.createElement(\"canvas\");\n destCanvas.width = clip.w;\n destCanvas.height = clip.h;\n destContext = destCanvas.getContext(\"2d\");\n }\n\n // Draw canvas to the canvas to export.\n destContext.drawImage(\n canvas,\n clip.x,\n clip.y,\n clip.w,\n clip.h,\n 0,\n 0,\n destCanvas.width,\n destCanvas.height,\n );\n }\n\n this.margin = CanvasSaveButton.getMargin(destCanvas);\n\n // Custom info\n let logoPromise = Promise.resolve();\n if (destContext && extraData && extraData.logo) {\n logoPromise = this.drawElement(extraData.logo, destCanvas);\n }\n\n logoPromise.then((logoSize = [0, 0]) => {\n // North arrow\n let arrowPromise = Promise.resolve();\n if (destContext && extraData && extraData.northArrow) {\n arrowPromise = this.drawElement(\n {\n src: extraData.northArrow.circled\n ? NorthArrowCircle\n : NorthArrowSimple,\n ...extraData.northArrow,\n },\n destCanvas,\n logoSize,\n );\n }\n\n // Copyright\n arrowPromise.then((arrowSize = [0, 0]) => {\n const widestElement = Math.max(logoSize[0], arrowSize[0]);\n if (\n destContext &&\n extraData &&\n extraData.copyright &&\n extraData.copyright.text\n ) {\n const maxWidth =\n extraData.copyright.maxWidth ||\n (widestElement\n ? destContext.canvas.width - widestElement - this.margin\n : destContext.canvas.width);\n this.drawCopyright(destContext, destCanvas, maxWidth);\n }\n let qrCodePromise = Promise.resolve();\n if (destContext && extraData && extraData.qrCode) {\n qrCodePromise = this.drawElement(\n extraData.qrCode,\n destCanvas,\n undefined,\n \"left\",\n );\n }\n qrCodePromise.then(() => {\n return resolve(destCanvas);\n });\n });\n });\n });\n mapToExport.renderSync();\n });\n }\n\n downloadCanvasImage(canvas) {\n // Use blob for large images\n const promise = new Promise((resolve) => {\n const { format } = this.props;\n if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {\n // ie 9 and 10\n const url = canvas.toDataURL(format);\n const w = window.open(\"about:blank\", \"\");\n w.document.write(`<img src=\"${url}\" alt=\"from canvas\"/>`);\n resolve(url);\n }\n if (window.navigator.msSaveBlob) {\n // ie 11 and higher\n let image;\n try {\n image = canvas.msToBlob();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(e);\n }\n const blob = new Blob([image], {\n type: format,\n });\n resolve(blob);\n window.navigator.msSaveBlob(blob, this.getDownloadImageName());\n } else {\n canvas.toBlob((blob) => {\n const link = document.createElement(\"a\");\n link.download = this.getDownloadImageName();\n link.href = URL.createObjectURL(blob);\n // append child to document for firefox to be able to download.\n document.body.appendChild(link);\n link.click();\n resolve(blob);\n }, format);\n }\n });\n return promise;\n }\n\n render() {\n const { children, ...other } = this.props;\n\n delete other.onSaveStart;\n delete other.onSaveEnd;\n delete other.extraData;\n delete other.extent;\n delete other.format;\n delete other.map;\n delete other.coordinates;\n delete other.autoDownload;\n delete other.scale;\n\n return (\n <div\n role=\"button\"\n className=\"rs-canvas-save-button\"\n tabIndex={0}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...other}\n onClick={(e) => {\n return this.onClick(e);\n }}\n onKeyPress={(e) => {\n return e.which === 13 && this.onClick(e);\n }}\n >\n {children}\n </div>\n );\n }\n}\n\nCanvasSaveButton.propTypes = propTypes;\nCanvasSaveButton.defaultProps = defaultProps;\n\nexport default CanvasSaveButton;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable no-param-reassign */\nimport React, { useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport OLMap from \"ol/Map\";\nimport { getTopLeft, getBottomRight } from \"ol/extent\";\nimport NorthArrowSimple from \"../../images/northArrow.url.svg\";\nimport NorthArrowCircle from \"../../images/northArrowCircle.url.svg\";\n\nconst extraDataImgPropType = PropTypes.shape({\n src: PropTypes.string,\n width: PropTypes.number,\n height: PropTypes.number,\n rotation: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),\n circled: PropTypes.bool,\n});\n\n// support server-side rendering where `Element` will not be defined\nconst CanvasPatternType =\n typeof CanvasPattern === \"undefined\" ? Function : CanvasPattern;\n\nconst propTypes = {\n /**\n * Automatically download the image saved.\n */\n autoDownload: PropTypes.bool,\n\n /**\n * Children content of the button.\n */\n children: PropTypes.node,\n\n /**\n * Output format of the image.\n */\n format: PropTypes.oneOf([\"image/jpeg\", \"image/png\"]),\n\n /** An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html). */\n map: PropTypes.instanceOf(OLMap),\n\n /**\n * Space (in pixels) between the border of the canvas and the elements.\n * Default to 1% of the canvas width.\n */\n margin: PropTypes.number,\n\n /**\n * Space (in pixels) between elements.\n * Default to 5px.\n */\n padding: PropTypes.number,\n\n /**\n * Extent for the export. If no extent is given, the whole map is exported.\n */\n extent: PropTypes.arrayOf(PropTypes.number),\n\n /**\n * Array of 4 [ol/Coordinate](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~Coordinate).\n * If no coordinates and no extent are given, the whole map is exported.\n * This property must be used to export rotated map.\n * If you don't need to export rotated map the extent property can be used as well.\n * If extent is specified, coordinates property is ignored.\n */\n coordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),\n\n /**\n * Scale the map for better quality. Possible values: 1, 2 or 3.\n * WARNING: The tiled layer with a WMTS or XYZ source must provides an url\n * for each scale in the config file.\n */\n scale: PropTypes.number,\n\n /**\n * Function called before the dowload process begins.\n */\n onSaveStart: PropTypes.func,\n\n /**\n * Function called after the dowload process ends.\n *\n * @param {object} error Error message the process fails.\n */\n onSaveEnd: PropTypes.func,\n\n /**\n * Extra data, such as copyright, north arrow configuration.\n * All extra data is optional.\n *\n * Example 1:\n *\n {\n copyright: {\n text: 'Example copyright', // Copyright text or function\n font: '10px Arial', // Font, default is '12px Arial'\n fillStyle: 'blue', // Fill style, default is 'black'\n },\n northArrow, // True if the north arrow\n // should be placed with default configuration\n // (default image, rotation=0, circled=false)\n }\n * Example 2:\n *\n {\n northArrow: {\n src: NorthArrowCustom,\n width: 60, // Width in px, default is 80\n height: 100, // Height in px, default is 80\n rotation: 25, // Absolute rotation in degrees as number or function\n\n }\n }\n * Example 3:\n *\n {\n copyright: {\n text: () => { // Copyright as function\n return this.copyright;\n },\n },\n northArrow: {\n rotation: () => { // Rotation as function\n return NorthArrow.radToDeg(this.map.getView().getRotation());\n },\n circled, // Display circle around the north arrow (Does not work for custom src)\n },\n }\n */\n extraData: PropTypes.shape({\n logo: extraDataImgPropType,\n northArrow: extraDataImgPropType,\n qrCode: extraDataImgPropType,\n copyright: PropTypes.shape({\n text: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n font: PropTypes.string,\n fillStyle: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.instanceOf(CanvasPatternType),\n ]),\n background: PropTypes.bool,\n maxWidth: PropTypes.number,\n paddingBottom: PropTypes.number,\n paddingBackground: PropTypes.number,\n }),\n }),\n};\n\nconst getMargin = (destCanvas) => {\n const newMargin = destCanvas.width / 100; // 1% of the canvas width\n return newMargin;\n};\n\nconst getDownloadImageName = (format) => {\n const fileExt = format === \"image/jpeg\" ? \"jpg\" : \"png\";\n return `${window.document.title.replace(/ /g, \"_\").toLowerCase()}.${fileExt}`;\n};\n\nlet multilineCopyright = false;\nlet copyrightY = 0;\n\n// Ensure the font size fita with the image width.\nconst decreaseFontSize = (destContext, maxWidth, copyright, scale) => {\n const minFontSize = 8;\n let sizeMatch;\n let fontSize;\n do {\n sizeMatch = destContext.font.match(/[0-9]+(?:\\.[0-9]+)?(px)/i);\n fontSize = parseInt(sizeMatch[0].replace(sizeMatch[1], \"\"), 10);\n\n // eslint-disable-next-line no-param-reassign\n destContext.font = destContext.font.replace(fontSize, fontSize - 1);\n\n multilineCopyright = false;\n\n if (fontSize - 1 === minFontSize) {\n multilineCopyright = true;\n }\n } while (\n fontSize - 1 > minFontSize &&\n destContext.measureText(copyright).width * scale > maxWidth\n );\n\n return destContext.font;\n};\n\n// eslint-disable-next-line class-methods-use-this\nconst drawTextBackground = (\n destContext,\n x,\n y,\n width,\n height,\n styleOptions = {},\n) => {\n destContext.save();\n // Dflt is a white background\n destContext.fillStyle = \"rgba(255,255,255,.8)\";\n\n // To simplify usability the user could pass a boolean to use only default values.\n if (typeof styleOptions === \"object\") {\n Object.entries(styleOptions).forEach(([key, value]) => {\n destContext[key] = value;\n });\n }\n\n /// draw background rect assuming height of font\n destContext.fillRect(x, y, width, height);\n destContext.restore();\n};\n\nconst drawCopyright = (\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n) => {\n const { text, font, fillStyle, background } = extraData.copyright;\n const { paddingBottom = padding, paddingBackground = 2 } =\n extraData.copyright;\n\n let copyright = typeof text === \"function\" ? text() : text?.trim();\n\n if (Array.isArray(copyright)) {\n copyright = copyright.join();\n }\n\n destContext.save();\n destContext.scale(scale, scale);\n destContext.font = font || \"12px Arial\";\n destContext.font = decreaseFontSize(destContext, maxWidth, copyright, scale);\n destContext.textBaseline = \"bottom\";\n destContext.scale(scale, scale);\n destContext.fillStyle = fillStyle || \"black\";\n\n // We search if the display on 2 line is necessary\n let firstLine = copyright;\n let firstLineMetrics = destContext.measureText(firstLine);\n\n // If the text is bigger than the max width we split it into 2 lines\n if (multilineCopyright) {\n const wordNumber = copyright.split(\" \").length;\n for (let i = 0; i < wordNumber; i += 1) {\n // Stop removing word when fits within one line.\n if (firstLineMetrics.width * scale < maxWidth) {\n break;\n }\n firstLine = firstLine.substring(0, firstLine.lastIndexOf(\" \"));\n firstLineMetrics = destContext.measureText(firstLine);\n }\n }\n\n // Define second line if necessary\n const secondLine = copyright.replace(firstLine, \"\").trim();\n\n // At this point we the number of lines to display.\n const lines = [firstLine, secondLine].filter((l) => !!l).reverse();\n\n // We draw from bottom to top because textBaseline is 'bottom\n let lineX = margin;\n let lineY = destCanvas.height - paddingBottom; // we apply the margin only on the left side\n\n lines.forEach((line) => {\n const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } =\n destContext.measureText(line);\n const height = fontBoundingBoxAscent + fontBoundingBoxDescent; // we include paddingBackground to have a bit of distance between lines\n let lineTop = lineY - height;\n\n if (background) {\n const backgroundX = margin;\n lineTop -= paddingBackground * 2;\n drawTextBackground(\n destContext,\n backgroundX,\n lineTop,\n width + paddingBackground * 2,\n height + paddingBackground * 2,\n background,\n );\n lineX += paddingBackground;\n lineY -= paddingBackground;\n }\n\n destContext.fillText(line, lineX, lineY);\n lineY = lineTop;\n });\n\n copyrightY = lineY;\n destContext.restore();\n};\n\nconst drawElement = (\n data,\n destCanvas,\n scale,\n margin,\n padding,\n previousItemSize = [0, 0],\n side = \"right\",\n) => {\n const destContext = destCanvas.getContext(\"2d\");\n const { src, width, height, rotation } = data;\n\n return new Promise((resolve) => {\n const img = new Image();\n img.crossOrigin = \"Anonymous\";\n img.src = src;\n img.onload = () => {\n destContext.save();\n const elementWidth = (width || 80) * scale;\n const elementHeight = (height || 80) * scale;\n const left =\n side === \"left\"\n ? margin + elementWidth / 2\n : destCanvas.width - margin - elementWidth / 2;\n const top =\n (side === \"left\" && copyrightY\n ? copyrightY - padding\n : destCanvas.height) -\n margin -\n elementHeight / 2 -\n previousItemSize[1];\n\n destContext.translate(left, top);\n\n if (rotation) {\n const angle = typeof rotation === \"function\" ? rotation() : rotation;\n destContext.rotate(angle * (Math.PI / 180));\n }\n\n destContext.drawImage(\n img,\n -elementWidth / 2,\n -elementHeight / 2,\n elementWidth,\n elementHeight,\n );\n destContext.restore();\n\n // Return the pixels width of the arrow and the margin right,\n // that must not be occupied by the copyright.\n resolve([elementWidth + 2 * padding, elementHeight + 2 * padding]);\n };\n\n img.onerror = () => {\n resolve();\n };\n });\n};\n\nconst calculatePixelsToExport = (mapToExport, extent, coordinates) => {\n let firstCoordinate;\n let oppositeCoordinate;\n\n if (extent) {\n firstCoordinate = getTopLeft(extent);\n oppositeCoordinate = getBottomRight(extent);\n } else if (coordinates) {\n // In case of coordinates coming from DragBox interaction:\n // firstCoordinate is the first coordinate drawn by the user.\n // oppositeCoordinate is the coordinate of the point dragged by the user.\n [firstCoordinate, , oppositeCoordinate] = coordinates;\n }\n\n if (firstCoordinate && oppositeCoordinate) {\n const firstPixel = mapToExport.getPixelFromCoordinate(firstCoordinate);\n const oppositePixel =\n mapToExport.getPixelFromCoordinate(oppositeCoordinate);\n const pixelTopLeft = [\n firstPixel[0] <= oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] <= oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n const pixelBottomRight = [\n firstPixel[0] > oppositePixel[0] ? firstPixel[0] : oppositePixel[0],\n firstPixel[1] > oppositePixel[1] ? firstPixel[1] : oppositePixel[1],\n ];\n\n return {\n x: pixelTopLeft[0],\n y: pixelTopLeft[1],\n w: pixelBottomRight[0] - pixelTopLeft[0],\n h: pixelBottomRight[1] - pixelTopLeft[1],\n };\n }\n return null;\n};\n\nconst createCanvasImage = (\n mapToExport,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n) => {\n return new Promise((resolve) => {\n mapToExport.once(\"rendercomplete\", () => {\n // Find all layer canvases and add it to dest canvas.\n const canvases = mapToExport\n .getTargetElement()\n .getElementsByTagName(\"canvas\");\n\n // Create the canvas to export with the good size.\n let destCanvas;\n let destContext;\n\n // canvases is an HTMLCollection, we don't try to transform to array because some compilers like cra doesn't translate it right.\n for (let i = 0; i < canvases.length; i += 1) {\n const canvas = canvases[i];\n if (!canvas.width || !canvas.height) {\n // eslint-disable-next-line no-continue\n continue;\n }\n const clip = calculatePixelsToExport(\n mapToExport,\n extent,\n coordinates,\n ) || {\n x: 0,\n y: 0,\n w: canvas.width,\n h: canvas.height,\n };\n\n if (!destCanvas) {\n destCanvas = document.createElement(\"canvas\");\n destCanvas.width = clip.w;\n destCanvas.height = clip.h;\n destContext = destCanvas.getContext(\"2d\");\n }\n\n // Draw canvas to the canvas to export.\n destContext.drawImage(\n canvas,\n clip.x,\n clip.y,\n clip.w,\n clip.h,\n 0,\n 0,\n destCanvas.width,\n destCanvas.height,\n );\n }\n\n margin = margin || getMargin(destCanvas);\n\n // Custom info\n let logoPromise = Promise.resolve();\n if (destContext && extraData && extraData.logo) {\n logoPromise = drawElement(\n extraData.logo,\n destCanvas,\n scale,\n margin,\n padding,\n );\n }\n\n logoPromise.then((logoSize = [0, 0]) => {\n // North arrow\n let arrowPromise = Promise.resolve();\n if (destContext && extraData && extraData.northArrow) {\n arrowPromise = drawElement(\n {\n src: extraData.northArrow.circled\n ? NorthArrowCircle\n : NorthArrowSimple,\n ...extraData.northArrow,\n },\n destCanvas,\n scale,\n margin,\n padding,\n logoSize,\n );\n }\n\n // Copyright\n arrowPromise.then((arrowSize = [0, 0]) => {\n const widestElement = Math.max(logoSize[0], arrowSize[0]);\n if (\n destContext &&\n extraData &&\n extraData.copyright &&\n extraData.copyright.text\n ) {\n const maxWidth =\n extraData.copyright.maxWidth ||\n (widestElement\n ? destContext.canvas.width - widestElement - margin\n : destContext.canvas.width);\n drawCopyright(\n destContext,\n destCanvas,\n maxWidth,\n extraData,\n scale,\n margin,\n padding,\n );\n }\n let qrCodePromise = Promise.resolve();\n if (destContext && extraData && extraData.qrCode) {\n qrCodePromise = drawElement(\n extraData.qrCode,\n destCanvas,\n scale,\n margin,\n padding,\n undefined,\n \"left\",\n );\n }\n qrCodePromise.then(() => {\n return resolve(destCanvas);\n });\n });\n });\n });\n mapToExport.renderSync();\n });\n};\n\nconst downloadCanvasImage = (canvas, format) => {\n // Use blob for large images\n const promise = new Promise((resolve) => {\n if (/msie (9|10)/gi.test(window.navigator.userAgent.toLowerCase())) {\n // ie 9 and 10\n const url = canvas.toDataURL(format);\n const w = window.open(\"about:blank\", \"\");\n w.document.write(`<img src=\"${url}\" alt=\"from canvas\"/>`);\n resolve(url);\n }\n if (window.navigator.msSaveBlob) {\n // ie 11 and higher\n let image;\n try {\n image = canvas.msToBlob();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(e);\n }\n const blob = new Blob([image], {\n type: format,\n });\n resolve(blob);\n window.navigator.msSaveBlob(blob, getDownloadImageName(format));\n } else {\n canvas.toBlob((blob) => {\n const link = document.createElement(\"a\");\n link.download = getDownloadImageName(format);\n link.href = URL.createObjectURL(blob);\n // append child to document for firefox to be able to download.\n document.body.appendChild(link);\n link.click();\n resolve(blob);\n }, format);\n }\n });\n return promise;\n};\n\n/**\n * The CanvasSaveButton component creates a button to save\n * an [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)\n * canvas as an image.\n */\nfunction CanvasSaveButton({\n margin = null,\n padding = 5,\n autoDownload = true,\n children = null,\n map = null,\n format = \"image/png\",\n extraData = null,\n extent = null,\n coordinates = null,\n scale = 1,\n onSaveStart = (mapp) => {\n return Promise.resolve(mapp);\n },\n onSaveEnd = () => {},\n ...props\n}) {\n const onClick = useCallback(\n (evt) => {\n if (window.navigator.msSaveBlob) {\n // ie only\n evt.preventDefault();\n evt.stopPropagation();\n }\n multilineCopyright = false;\n copyrightY = 0;\n onSaveStart(map).then((mapToExport) => {\n return createCanvasImage(\n mapToExport || map,\n extraData,\n scale,\n extent,\n coordinates,\n margin,\n padding,\n )\n .then((canvas) => {\n if (autoDownload) {\n downloadCanvasImage(canvas, format).then((blob) => {\n onSaveEnd(mapToExport, canvas, blob);\n });\n } else {\n onSaveEnd(mapToExport, canvas);\n }\n })\n .catch((err) => {\n if (err) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n onSaveEnd(mapToExport, err);\n });\n });\n },\n [\n autoDownload,\n coordinates,\n extent,\n extraData,\n format,\n map,\n margin,\n onSaveEnd,\n onSaveStart,\n padding,\n scale,\n ],\n );\n\n return (\n <div\n role=\"button\"\n className=\"rs-canvas-save-button\"\n tabIndex={0}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...props}\n onClick={onClick}\n onKeyPress={(evt) => {\n return evt.which === 13 && onClick(evt);\n }}\n >\n {children}\n </div>\n );\n}\n\nCanvasSaveButton.propTypes = propTypes;\n\nexport default CanvasSaveButton;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "react-spatial",
3
3
  "license": "MIT",
4
4
  "description": "Components to build React map apps.",
5
- "version": "1.10.2",
5
+ "version": "1.10.3-beta.1",
6
6
  "dependencies": {
7
7
  "@emotion/react": "^11.11.4",
8
8
  "@emotion/styled": "^11.11.5",
@@ -157,7 +157,8 @@
157
157
  "no-restricted-exports": "Off",
158
158
  "react/forbid-prop-types": "Off",
159
159
  "prettier/prettier": "error",
160
- "jsx-a11y/no-access-key": "Off"
160
+ "jsx-a11y/no-access-key": "Off",
161
+ "react/require-default-props": "Off"
161
162
  }
162
163
  },
163
164
  "jest": {