@open-pioneer/printing 0.1.0 → 0.1.2
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/CHANGELOG.md +27 -0
- package/Printing.d.ts +7 -0
- package/Printing.js +6 -4
- package/Printing.js.map +1 -1
- package/PrintingController.d.ts +3 -1
- package/PrintingController.js +6 -1
- package/PrintingController.js.map +1 -1
- package/PrintingServiceImpl.d.ts +3 -0
- package/PrintingServiceImpl.js +65 -5
- package/PrintingServiceImpl.js.map +1 -1
- package/README.md +8 -1
- package/i18n/de.yaml +1 -1
- package/i18n/en.yaml +1 -1
- package/index.d.ts +12 -0
- package/package.json +8 -8
- package/styles.css +8 -0
- package/styles.css.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @open-pioneer/printing
|
|
2
2
|
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c927f60: Remove 'required' attribute from title input since it is not actually required
|
|
8
|
+
- 4140646: Update trails dependencies
|
|
9
|
+
- 4140646: Update to react 18.3.1
|
|
10
|
+
- f2912be: Added more context to some button labels and tooltips for better usability.
|
|
11
|
+
- 0fd366f: Don't include the map view's padding by default (see open-pioneer/trails-openlayers-base-packages#311)
|
|
12
|
+
- 81bc7da: Update trails dependencies
|
|
13
|
+
- 2c092dc: Update dependencies
|
|
14
|
+
- Updated dependencies [4140646]
|
|
15
|
+
- Updated dependencies [4140646]
|
|
16
|
+
- Updated dependencies [b5bb7a1]
|
|
17
|
+
- Updated dependencies [81bc7da]
|
|
18
|
+
- Updated dependencies [2c092dc]
|
|
19
|
+
- Updated dependencies [4140646]
|
|
20
|
+
- @open-pioneer/react-utils@0.2.3
|
|
21
|
+
- @open-pioneer/map@0.5.1
|
|
22
|
+
|
|
23
|
+
## 0.1.1
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [520a97b]
|
|
28
|
+
- @open-pioneer/map@0.5.0
|
|
29
|
+
|
|
3
30
|
## 0.1.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
package/Printing.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CommonComponentProps } from "@open-pioneer/react-utils";
|
|
2
2
|
import { FC } from "react";
|
|
3
|
+
import type { ViewPaddingBehavior } from "./index";
|
|
3
4
|
/**
|
|
4
5
|
* This is special property for the Printing.
|
|
5
6
|
*/
|
|
@@ -8,6 +9,12 @@ export interface PrintingProps extends CommonComponentProps {
|
|
|
8
9
|
* The id of the map.
|
|
9
10
|
*/
|
|
10
11
|
mapId: string;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to respect the map view's padding when printing (default: `"auto"`).
|
|
14
|
+
*
|
|
15
|
+
* See also {@link ViewPaddingBehavior}.
|
|
16
|
+
*/
|
|
17
|
+
viewPadding?: ViewPaddingBehavior;
|
|
11
18
|
}
|
|
12
19
|
/**
|
|
13
20
|
* The `Printing` component can be used to download the current map view as a printable file.
|
package/Printing.js
CHANGED
|
@@ -10,7 +10,7 @@ import { PrintingController } from './PrintingController.js';
|
|
|
10
10
|
const LOG = createLogger("printing");
|
|
11
11
|
const Printing = (props) => {
|
|
12
12
|
const intl = useIntl();
|
|
13
|
-
const { mapId } = props;
|
|
13
|
+
const { mapId, viewPadding = "auto" } = props;
|
|
14
14
|
const { containerProps } = useCommonComponentProps("printing", props);
|
|
15
15
|
const [selectedFileFormat, setSelectedFileFormat] = useState("pdf");
|
|
16
16
|
const [title, setTitle] = useState("");
|
|
@@ -18,7 +18,7 @@ const Printing = (props) => {
|
|
|
18
18
|
const printingService = useService("printing.PrintingService");
|
|
19
19
|
const notifier = useService("notifier.NotificationService");
|
|
20
20
|
const { map } = useMapModel(mapId);
|
|
21
|
-
const controller = useController(map, intl, printingService);
|
|
21
|
+
const controller = useController(map, intl, printingService, viewPadding);
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
controller?.setFileFormat(selectedFileFormat);
|
|
24
24
|
}, [controller, selectedFileFormat]);
|
|
@@ -58,7 +58,6 @@ const Printing = (props) => {
|
|
|
58
58
|
onChange: (event) => {
|
|
59
59
|
setTitle(event.target.value);
|
|
60
60
|
},
|
|
61
|
-
isRequired: true,
|
|
62
61
|
autoFocus: true
|
|
63
62
|
}
|
|
64
63
|
)
|
|
@@ -94,7 +93,7 @@ const Printing = (props) => {
|
|
|
94
93
|
)
|
|
95
94
|
] });
|
|
96
95
|
};
|
|
97
|
-
function useController(map, intl, printingService) {
|
|
96
|
+
function useController(map, intl, printingService, viewPadding) {
|
|
98
97
|
const [controller, setController] = useState(void 0);
|
|
99
98
|
useEffect(() => {
|
|
100
99
|
if (!map) {
|
|
@@ -109,6 +108,9 @@ function useController(map, intl, printingService) {
|
|
|
109
108
|
setController(void 0);
|
|
110
109
|
};
|
|
111
110
|
}, [map, intl, printingService]);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
controller?.setViewPadding(viewPadding);
|
|
113
|
+
}, [controller, viewPadding]);
|
|
112
114
|
return controller;
|
|
113
115
|
}
|
|
114
116
|
|
package/Printing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Printing.js","sources":["Printing.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Button,\n FormControl,\n FormLabel,\n HStack,\n Input,\n Select\n} from \"@open-pioneer/chakra-integration\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { MapModel, useMapModel } from \"@open-pioneer/map\";\nimport { NotificationService } from \"@open-pioneer/notifier\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { FC, useEffect, useState } from \"react\";\nimport { FileFormatType, PrintingController } from \"./PrintingController\";\nimport { PrintingService } from \"./index\";\n\nconst LOG = createLogger(\"printing\");\n\n/**\n * This is special property for the Printing.\n */\nexport interface PrintingProps extends CommonComponentProps {\n /**\n * The id of the map.\n */\n mapId: string;\n}\n\n/**\n * The `Printing` component can be used to download the current map view as a printable file.\n */\nexport const Printing: FC<PrintingProps> = (props) => {\n const intl = useIntl();\n\n const { mapId } = props;\n const { containerProps } = useCommonComponentProps(\"printing\", props);\n const [selectedFileFormat, setSelectedFileFormat] = useState<FileFormatType>(\"pdf\");\n const [title, setTitle] = useState<string>(\"\");\n const [running, setRunning] = useState<boolean>(false);\n\n const printingService = useService<PrintingService>(\"printing.PrintingService\");\n const notifier = useService<NotificationService>(\"notifier.NotificationService\");\n\n const { map } = useMapModel(mapId);\n
|
|
1
|
+
{"version":3,"file":"Printing.js","sources":["Printing.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Button,\n FormControl,\n FormLabel,\n HStack,\n Input,\n Select\n} from \"@open-pioneer/chakra-integration\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { MapModel, useMapModel } from \"@open-pioneer/map\";\nimport { NotificationService } from \"@open-pioneer/notifier\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { FC, useEffect, useState } from \"react\";\nimport { FileFormatType, PrintingController } from \"./PrintingController\";\nimport type { ViewPaddingBehavior, PrintingService } from \"./index\";\n\nconst LOG = createLogger(\"printing\");\n\n/**\n * This is special property for the Printing.\n */\nexport interface PrintingProps extends CommonComponentProps {\n /**\n * The id of the map.\n */\n mapId: string;\n\n /**\n * Whether to respect the map view's padding when printing (default: `\"auto\"`).\n *\n * See also {@link ViewPaddingBehavior}.\n */\n viewPadding?: ViewPaddingBehavior;\n}\n\n/**\n * The `Printing` component can be used to download the current map view as a printable file.\n */\nexport const Printing: FC<PrintingProps> = (props) => {\n const intl = useIntl();\n\n const { mapId, viewPadding = \"auto\" } = props;\n const { containerProps } = useCommonComponentProps(\"printing\", props);\n const [selectedFileFormat, setSelectedFileFormat] = useState<FileFormatType>(\"pdf\");\n const [title, setTitle] = useState<string>(\"\");\n const [running, setRunning] = useState<boolean>(false);\n\n const printingService = useService<PrintingService>(\"printing.PrintingService\");\n const notifier = useService<NotificationService>(\"notifier.NotificationService\");\n\n const { map } = useMapModel(mapId);\n const controller = useController(map, intl, printingService, viewPadding);\n\n useEffect(() => {\n controller?.setFileFormat(selectedFileFormat);\n }, [controller, selectedFileFormat]);\n\n useEffect(() => {\n controller?.setTitle(title);\n }, [controller, title]);\n\n function changeFileFormat(fileFormat: string) {\n if (fileFormat === \"png\" || fileFormat === \"pdf\") {\n setSelectedFileFormat(fileFormat);\n }\n }\n\n function exportMap() {\n if (running || !controller) {\n return;\n }\n\n setRunning(true);\n controller\n .handleMapExport()\n .catch((error) => {\n const errorMessage = intl.formatMessage({ id: \"printingFailed\" });\n notifier.notify({\n level: \"error\",\n message: errorMessage\n });\n LOG.error(\"Failed to print the map\", error);\n })\n .finally(() => {\n setRunning(false);\n });\n }\n\n return (\n <Box {...containerProps}>\n <FormControl mb={4} alignItems=\"center\">\n <HStack mb={2}>\n <FormLabel minWidth=\"82\" mb={1}>\n {intl.formatMessage({ id: \"title\" })}\n </FormLabel>\n <Input\n placeholder={intl.formatMessage({ id: \"input.placeholder\" })}\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n autoFocus // eslint-disable-line jsx-a11y/no-autofocus\n />\n </HStack>\n <HStack mb={2}>\n <FormLabel minWidth=\"82\" mb={1}>\n {intl.formatMessage({ id: \"fileFormat\" })}\n </FormLabel>\n <Select\n value={selectedFileFormat}\n onChange={(e) => changeFileFormat(e.target.value)}\n className=\"printing-select\"\n >\n <option value={\"png\"}>PNG</option>\n <option value={\"pdf\"}>PDF</option>\n </Select>\n </HStack>\n </FormControl>\n <Button\n isLoading={running}\n loadingText={intl.formatMessage({ id: \"printingMap\" })}\n disabled={running}\n padding={2}\n className=\"printing-export-button\"\n onClick={exportMap}\n width=\"100%\"\n >\n {intl.formatMessage({ id: \"export\" })}\n </Button>\n </Box>\n );\n};\n\n/**\n * Create a PrintingController instance to export the map view.\n */\nfunction useController(\n map: MapModel | undefined,\n intl: PackageIntl,\n printingService: PrintingService,\n viewPadding: ViewPaddingBehavior\n) {\n const [controller, setController] = useState<PrintingController | undefined>(undefined);\n\n useEffect(() => {\n if (!map) {\n return;\n }\n\n const controller = new PrintingController(map.olMap, printingService, {\n overlayText: intl.formatMessage({ id: \"printingMap\" })\n });\n setController(controller);\n\n return () => {\n controller.destroy();\n setController(undefined);\n };\n }, [map, intl, printingService]);\n\n useEffect(() => {\n controller?.setViewPadding(viewPadding);\n }, [controller, viewPadding]);\n\n return controller;\n}\n"],"names":["controller"],"mappings":"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"}
|
package/PrintingController.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OlMap from "ol/Map";
|
|
2
|
-
import { PrintingService } from "./index";
|
|
2
|
+
import { PrintingService, ViewPaddingBehavior } from "./index";
|
|
3
3
|
export type FileFormatType = "png" | "pdf";
|
|
4
4
|
export declare class PrintingController {
|
|
5
5
|
private olMap;
|
|
@@ -7,12 +7,14 @@ export declare class PrintingController {
|
|
|
7
7
|
private fileFormat;
|
|
8
8
|
private i18n;
|
|
9
9
|
private printingService;
|
|
10
|
+
private viewPadding;
|
|
10
11
|
private printMap;
|
|
11
12
|
private overlay;
|
|
12
13
|
constructor(olMap: OlMap, printingService: PrintingService, i18n: I18n);
|
|
13
14
|
destroy(): void;
|
|
14
15
|
setTitle(title: string): void;
|
|
15
16
|
setFileFormat(format: FileFormatType): void;
|
|
17
|
+
setViewPadding(padding: ViewPaddingBehavior): void;
|
|
16
18
|
handleMapExport(): Promise<void>;
|
|
17
19
|
private begin;
|
|
18
20
|
private reset;
|
package/PrintingController.js
CHANGED
|
@@ -7,6 +7,7 @@ class PrintingController {
|
|
|
7
7
|
fileFormat = "pdf";
|
|
8
8
|
i18n;
|
|
9
9
|
printingService;
|
|
10
|
+
viewPadding;
|
|
10
11
|
printMap = void 0;
|
|
11
12
|
overlay = void 0;
|
|
12
13
|
constructor(olMap, printingService, i18n) {
|
|
@@ -23,6 +24,9 @@ class PrintingController {
|
|
|
23
24
|
setFileFormat(format) {
|
|
24
25
|
this.fileFormat = format;
|
|
25
26
|
}
|
|
27
|
+
setViewPadding(padding) {
|
|
28
|
+
this.viewPadding = padding;
|
|
29
|
+
}
|
|
26
30
|
async handleMapExport() {
|
|
27
31
|
if (!this.olMap || !this.fileFormat) {
|
|
28
32
|
return;
|
|
@@ -30,7 +34,8 @@ class PrintingController {
|
|
|
30
34
|
try {
|
|
31
35
|
this.begin();
|
|
32
36
|
this.printMap = await this.printingService.printMap(this.olMap, {
|
|
33
|
-
blockUserInteraction: false
|
|
37
|
+
blockUserInteraction: false,
|
|
38
|
+
viewPadding: this.viewPadding
|
|
34
39
|
});
|
|
35
40
|
const canvas = this.printMap.getCanvas();
|
|
36
41
|
if (canvas) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrintingController.js","sources":["PrintingController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport OlMap from \"ol/Map\";\nimport { PrintingService, PrintResult } from \"./index\";\nimport { canvasToPng, createBlockUserOverlay } from \"./utils\";\nimport { Resource } from \"@open-pioneer/core\";\n\nexport type FileFormatType = \"png\" | \"pdf\";\n\nconst DEFAULT_FILE_NAME = \"map\";\n\nexport class PrintingController {\n private olMap: OlMap;\n private title: string = \"\";\n private fileFormat: FileFormatType = \"pdf\";\n private i18n: I18n;\n\n private printingService: PrintingService;\n\n private printMap: PrintResult | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, printingService: PrintingService, i18n: I18n) {\n this.olMap = olMap;\n this.printingService = printingService;\n this.i18n = i18n;\n }\n\n destroy() {\n this.reset();\n }\n\n setTitle(title: string) {\n this.title = title;\n }\n\n setFileFormat(format: FileFormatType) {\n this.fileFormat = format;\n }\n\n async handleMapExport() {\n if (!this.olMap || !this.fileFormat) {\n return;\n }\n\n try {\n this.begin();\n this.printMap = await this.printingService.printMap(this.olMap, {\n blockUserInteraction: false\n });\n const canvas = this.printMap.getCanvas();\n if (canvas) {\n this.fileFormat == \"png\"\n ? await this.exportMapInPNG(canvas)\n : await this.exportMapInPDF(canvas);\n } else {\n throw new Error(\"Canvas export failed\");\n }\n } finally {\n this.reset();\n }\n }\n\n private begin() {\n const container = this.olMap.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.i18n.overlayText);\n }\n }\n\n private reset() {\n this.overlay?.destroy();\n this.overlay = undefined;\n }\n\n private getTitleAndFileName() {\n const titleValue = this.title || \"\";\n const fileName = this.title || DEFAULT_FILE_NAME;\n return { title: titleValue, fileName: fileName };\n }\n\n private async exportMapInPNG(mapCanvas: HTMLCanvasElement) {\n const containerCanvas = document.createElement(\"canvas\");\n containerCanvas.width = mapCanvas.width;\n containerCanvas.height = mapCanvas.height + 50;\n containerCanvas.style.backgroundColor = \"#fff\";\n\n const context = containerCanvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"2d canvas rendering context not available\");\n }\n\n const { title, fileName } = this.getTitleAndFileName();\n\n context.fillStyle = \"#fff\"; // background color for background rect\n context.fillRect(0, 0, containerCanvas.width, containerCanvas.height); //draw background rect\n context.font = 20 + \"px bold sans-serif\";\n context.textAlign = \"center\";\n context.fillStyle = \"#000\"; // text color\n\n const x = containerCanvas.width / 2; //align text to center\n context.fillText(title, x, 20);\n context.drawImage(mapCanvas, 0, 50);\n\n const link = document.createElement(\"a\");\n link.setAttribute(\"download\", fileName + \".png\");\n\n const dataURL = canvasToPng(containerCanvas);\n if (!dataURL) {\n throw new Error(\"Failed to get image data URL\");\n }\n\n link.href = dataURL;\n link.click();\n }\n\n private async exportMapInPDF(canvas: HTMLCanvasElement) {\n // Landscape map export.\n // Lazy load pdfjs as well.\n const { jsPDF } = await import(\"jspdf\");\n const pdf = new jsPDF({\n orientation: \"landscape\",\n unit: \"mm\",\n format: \"a4\"\n });\n\n // Simple layout: 50 pixels for the header and\n // the remaining space can be used by the map export.\n const pageWidth = pdf.internal.pageSize.getWidth();\n const pageHeight = pdf.internal.pageSize.getHeight();\n const titleOffset = 15;\n const mapOffset = 20;\n const mapPageHeight = pageHeight - mapOffset;\n\n // Render title\n pdf.setFontSize(20);\n const { title, fileName } = this.getTitleAndFileName();\n pdf.text(title, pageWidth / 2, titleOffset, { align: \"center\" });\n\n // Resize image while keeping aspect ratio\n const imageAspectRatio = canvas.width / canvas.height;\n let targetImageHeight = mapPageHeight;\n let targetImageWidth = targetImageHeight * imageAspectRatio;\n if (targetImageWidth >= pageWidth) {\n targetImageWidth = pageWidth;\n targetImageHeight = targetImageWidth / imageAspectRatio;\n }\n\n // Center image\n const imageX = (pageWidth - targetImageWidth) / 2;\n const imageY = mapOffset + (mapPageHeight - targetImageHeight) / 2;\n\n pdf.addImage(canvas, \"\", imageX, imageY, targetImageWidth, targetImageHeight);\n pdf.save(fileName + \".pdf\");\n }\n}\n\ninterface I18n {\n overlayText: string;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PrintingController.js","sources":["PrintingController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport OlMap from \"ol/Map\";\nimport { PrintingService, PrintResult, ViewPaddingBehavior } from \"./index\";\nimport { canvasToPng, createBlockUserOverlay } from \"./utils\";\nimport { Resource } from \"@open-pioneer/core\";\n\nexport type FileFormatType = \"png\" | \"pdf\";\n\nconst DEFAULT_FILE_NAME = \"map\";\n\nexport class PrintingController {\n private olMap: OlMap;\n private title: string = \"\";\n private fileFormat: FileFormatType = \"pdf\";\n private i18n: I18n;\n\n private printingService: PrintingService;\n private viewPadding: ViewPaddingBehavior | undefined;\n\n private printMap: PrintResult | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, printingService: PrintingService, i18n: I18n) {\n this.olMap = olMap;\n this.printingService = printingService;\n this.i18n = i18n;\n }\n\n destroy() {\n this.reset();\n }\n\n setTitle(title: string) {\n this.title = title;\n }\n\n setFileFormat(format: FileFormatType) {\n this.fileFormat = format;\n }\n\n setViewPadding(padding: ViewPaddingBehavior) {\n this.viewPadding = padding;\n }\n\n async handleMapExport() {\n if (!this.olMap || !this.fileFormat) {\n return;\n }\n\n try {\n this.begin();\n this.printMap = await this.printingService.printMap(this.olMap, {\n blockUserInteraction: false,\n viewPadding: this.viewPadding\n });\n const canvas = this.printMap.getCanvas();\n if (canvas) {\n this.fileFormat == \"png\"\n ? await this.exportMapInPNG(canvas)\n : await this.exportMapInPDF(canvas);\n } else {\n throw new Error(\"Canvas export failed\");\n }\n } finally {\n this.reset();\n }\n }\n\n private begin() {\n const container = this.olMap.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.i18n.overlayText);\n }\n }\n\n private reset() {\n this.overlay?.destroy();\n this.overlay = undefined;\n }\n\n private getTitleAndFileName() {\n const titleValue = this.title || \"\";\n const fileName = this.title || DEFAULT_FILE_NAME;\n return { title: titleValue, fileName: fileName };\n }\n\n private async exportMapInPNG(mapCanvas: HTMLCanvasElement) {\n const containerCanvas = document.createElement(\"canvas\");\n containerCanvas.width = mapCanvas.width;\n containerCanvas.height = mapCanvas.height + 50;\n containerCanvas.style.backgroundColor = \"#fff\";\n\n const context = containerCanvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"2d canvas rendering context not available\");\n }\n\n const { title, fileName } = this.getTitleAndFileName();\n\n context.fillStyle = \"#fff\"; // background color for background rect\n context.fillRect(0, 0, containerCanvas.width, containerCanvas.height); //draw background rect\n context.font = 20 + \"px bold sans-serif\";\n context.textAlign = \"center\";\n context.fillStyle = \"#000\"; // text color\n\n const x = containerCanvas.width / 2; //align text to center\n context.fillText(title, x, 20);\n context.drawImage(mapCanvas, 0, 50);\n\n const link = document.createElement(\"a\");\n link.setAttribute(\"download\", fileName + \".png\");\n\n const dataURL = canvasToPng(containerCanvas);\n if (!dataURL) {\n throw new Error(\"Failed to get image data URL\");\n }\n\n link.href = dataURL;\n link.click();\n }\n\n private async exportMapInPDF(canvas: HTMLCanvasElement) {\n // Landscape map export.\n // Lazy load pdfjs as well.\n const { jsPDF } = await import(\"jspdf\");\n const pdf = new jsPDF({\n orientation: \"landscape\",\n unit: \"mm\",\n format: \"a4\"\n });\n\n // Simple layout: 50 pixels for the header and\n // the remaining space can be used by the map export.\n const pageWidth = pdf.internal.pageSize.getWidth();\n const pageHeight = pdf.internal.pageSize.getHeight();\n const titleOffset = 15;\n const mapOffset = 20;\n const mapPageHeight = pageHeight - mapOffset;\n\n // Render title\n pdf.setFontSize(20);\n const { title, fileName } = this.getTitleAndFileName();\n pdf.text(title, pageWidth / 2, titleOffset, { align: \"center\" });\n\n // Resize image while keeping aspect ratio\n const imageAspectRatio = canvas.width / canvas.height;\n let targetImageHeight = mapPageHeight;\n let targetImageWidth = targetImageHeight * imageAspectRatio;\n if (targetImageWidth >= pageWidth) {\n targetImageWidth = pageWidth;\n targetImageHeight = targetImageWidth / imageAspectRatio;\n }\n\n // Center image\n const imageX = (pageWidth - targetImageWidth) / 2;\n const imageY = mapOffset + (mapPageHeight - targetImageHeight) / 2;\n\n pdf.addImage(canvas, \"\", imageX, imageY, targetImageWidth, targetImageHeight);\n pdf.save(fileName + \".pdf\");\n }\n}\n\ninterface I18n {\n overlayText: string;\n}\n"],"names":[],"mappings":";;AASA,MAAM,iBAAoB,GAAA,KAAA,CAAA;AAEnB,MAAM,kBAAmB,CAAA;AAAA,EACpB,KAAA,CAAA;AAAA,EACA,KAAgB,GAAA,EAAA,CAAA;AAAA,EAChB,UAA6B,GAAA,KAAA,CAAA;AAAA,EAC7B,IAAA,CAAA;AAAA,EAEA,eAAA,CAAA;AAAA,EACA,WAAA,CAAA;AAAA,EAEA,QAAoC,GAAA,KAAA,CAAA,CAAA;AAAA,EACpC,OAAgC,GAAA,KAAA,CAAA,CAAA;AAAA,EAExC,WAAA,CAAY,KAAc,EAAA,eAAA,EAAkC,IAAY,EAAA;AACpE,IAAA,IAAA,CAAK,KAAQ,GAAA,KAAA,CAAA;AACb,IAAA,IAAA,CAAK,eAAkB,GAAA,eAAA,CAAA;AACvB,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA,CAAA;AAAA,GAChB;AAAA,EAEA,OAAU,GAAA;AACN,IAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,GACf;AAAA,EAEA,SAAS,KAAe,EAAA;AACpB,IAAA,IAAA,CAAK,KAAQ,GAAA,KAAA,CAAA;AAAA,GACjB;AAAA,EAEA,cAAc,MAAwB,EAAA;AAClC,IAAA,IAAA,CAAK,UAAa,GAAA,MAAA,CAAA;AAAA,GACtB;AAAA,EAEA,eAAe,OAA8B,EAAA;AACzC,IAAA,IAAA,CAAK,WAAc,GAAA,OAAA,CAAA;AAAA,GACvB;AAAA,EAEA,MAAM,eAAkB,GAAA;AACpB,IAAA,IAAI,CAAC,IAAA,CAAK,KAAS,IAAA,CAAC,KAAK,UAAY,EAAA;AACjC,MAAA,OAAA;AAAA,KACJ;AAEA,IAAI,IAAA;AACA,MAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AACX,MAAA,IAAA,CAAK,WAAW,MAAM,IAAA,CAAK,eAAgB,CAAA,QAAA,CAAS,KAAK,KAAO,EAAA;AAAA,QAC5D,oBAAsB,EAAA,KAAA;AAAA,QACtB,aAAa,IAAK,CAAA,WAAA;AAAA,OACrB,CAAA,CAAA;AACD,MAAM,MAAA,MAAA,GAAS,IAAK,CAAA,QAAA,CAAS,SAAU,EAAA,CAAA;AACvC,MAAA,IAAI,MAAQ,EAAA;AACR,QAAK,IAAA,CAAA,UAAA,IAAc,KACb,GAAA,MAAM,IAAK,CAAA,cAAA,CAAe,MAAM,CAChC,GAAA,MAAM,IAAK,CAAA,cAAA,CAAe,MAAM,CAAA,CAAA;AAAA,OACnC,MAAA;AACH,QAAM,MAAA,IAAI,MAAM,sBAAsB,CAAA,CAAA;AAAA,OAC1C;AAAA,KACF,SAAA;AACE,MAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,KACf;AAAA,GACJ;AAAA,EAEQ,KAAQ,GAAA;AACZ,IAAM,MAAA,SAAA,GAAY,IAAK,CAAA,KAAA,CAAM,gBAAiB,EAAA,CAAA;AAC9C,IAAA,IAAI,SAAW,EAAA;AACX,MAAA,IAAA,CAAK,OAAU,GAAA,sBAAA,CAAuB,SAAW,EAAA,IAAA,CAAK,KAAK,WAAW,CAAA,CAAA;AAAA,KAC1E;AAAA,GACJ;AAAA,EAEQ,KAAQ,GAAA;AACZ,IAAA,IAAA,CAAK,SAAS,OAAQ,EAAA,CAAA;AACtB,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,GACnB;AAAA,EAEQ,mBAAsB,GAAA;AAC1B,IAAM,MAAA,UAAA,GAAa,KAAK,KAAS,IAAA,EAAA,CAAA;AACjC,IAAM,MAAA,QAAA,GAAW,KAAK,KAAS,IAAA,iBAAA,CAAA;AAC/B,IAAO,OAAA,EAAE,KAAO,EAAA,UAAA,EAAY,QAAmB,EAAA,CAAA;AAAA,GACnD;AAAA,EAEA,MAAc,eAAe,SAA8B,EAAA;AACvD,IAAM,MAAA,eAAA,GAAkB,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AACvD,IAAA,eAAA,CAAgB,QAAQ,SAAU,CAAA,KAAA,CAAA;AAClC,IAAgB,eAAA,CAAA,MAAA,GAAS,UAAU,MAAS,GAAA,EAAA,CAAA;AAC5C,IAAA,eAAA,CAAgB,MAAM,eAAkB,GAAA,MAAA,CAAA;AAExC,IAAM,MAAA,OAAA,GAAU,eAAgB,CAAA,UAAA,CAAW,IAAI,CAAA,CAAA;AAC/C,IAAA,IAAI,CAAC,OAAS,EAAA;AACV,MAAM,MAAA,IAAI,MAAM,2CAA2C,CAAA,CAAA;AAAA,KAC/D;AAEA,IAAA,MAAM,EAAE,KAAA,EAAO,QAAS,EAAA,GAAI,KAAK,mBAAoB,EAAA,CAAA;AAErD,IAAA,OAAA,CAAQ,SAAY,GAAA,MAAA,CAAA;AACpB,IAAA,OAAA,CAAQ,SAAS,CAAG,EAAA,CAAA,EAAG,eAAgB,CAAA,KAAA,EAAO,gBAAgB,MAAM,CAAA,CAAA;AACpE,IAAA,OAAA,CAAQ,IAAO,GAAA,sBAAA,CAAA;AACf,IAAA,OAAA,CAAQ,SAAY,GAAA,QAAA,CAAA;AACpB,IAAA,OAAA,CAAQ,SAAY,GAAA,MAAA,CAAA;AAEpB,IAAM,MAAA,CAAA,GAAI,gBAAgB,KAAQ,GAAA,CAAA,CAAA;AAClC,IAAQ,OAAA,CAAA,QAAA,CAAS,KAAO,EAAA,CAAA,EAAG,EAAE,CAAA,CAAA;AAC7B,IAAQ,OAAA,CAAA,SAAA,CAAU,SAAW,EAAA,CAAA,EAAG,EAAE,CAAA,CAAA;AAElC,IAAM,MAAA,IAAA,GAAO,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA,CAAA;AACvC,IAAK,IAAA,CAAA,YAAA,CAAa,UAAY,EAAA,QAAA,GAAW,MAAM,CAAA,CAAA;AAE/C,IAAM,MAAA,OAAA,GAAU,YAAY,eAAe,CAAA,CAAA;AAC3C,IAAA,IAAI,CAAC,OAAS,EAAA;AACV,MAAM,MAAA,IAAI,MAAM,8BAA8B,CAAA,CAAA;AAAA,KAClD;AAEA,IAAA,IAAA,CAAK,IAAO,GAAA,OAAA,CAAA;AACZ,IAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,GACf;AAAA,EAEA,MAAc,eAAe,MAA2B,EAAA;AAGpD,IAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,OAAO,OAAO,CAAA,CAAA;AACtC,IAAM,MAAA,GAAA,GAAM,IAAI,KAAM,CAAA;AAAA,MAClB,WAAa,EAAA,WAAA;AAAA,MACb,IAAM,EAAA,IAAA;AAAA,MACN,MAAQ,EAAA,IAAA;AAAA,KACX,CAAA,CAAA;AAID,IAAA,MAAM,SAAY,GAAA,GAAA,CAAI,QAAS,CAAA,QAAA,CAAS,QAAS,EAAA,CAAA;AACjD,IAAA,MAAM,UAAa,GAAA,GAAA,CAAI,QAAS,CAAA,QAAA,CAAS,SAAU,EAAA,CAAA;AACnD,IAAA,MAAM,WAAc,GAAA,EAAA,CAAA;AACpB,IAAA,MAAM,SAAY,GAAA,EAAA,CAAA;AAClB,IAAA,MAAM,gBAAgB,UAAa,GAAA,SAAA,CAAA;AAGnC,IAAA,GAAA,CAAI,YAAY,EAAE,CAAA,CAAA;AAClB,IAAA,MAAM,EAAE,KAAA,EAAO,QAAS,EAAA,GAAI,KAAK,mBAAoB,EAAA,CAAA;AACrD,IAAI,GAAA,CAAA,IAAA,CAAK,OAAO,SAAY,GAAA,CAAA,EAAG,aAAa,EAAE,KAAA,EAAO,UAAU,CAAA,CAAA;AAG/D,IAAM,MAAA,gBAAA,GAAmB,MAAO,CAAA,KAAA,GAAQ,MAAO,CAAA,MAAA,CAAA;AAC/C,IAAA,IAAI,iBAAoB,GAAA,aAAA,CAAA;AACxB,IAAA,IAAI,mBAAmB,iBAAoB,GAAA,gBAAA,CAAA;AAC3C,IAAA,IAAI,oBAAoB,SAAW,EAAA;AAC/B,MAAmB,gBAAA,GAAA,SAAA,CAAA;AACnB,MAAA,iBAAA,GAAoB,gBAAmB,GAAA,gBAAA,CAAA;AAAA,KAC3C;AAGA,IAAM,MAAA,MAAA,GAAA,CAAU,YAAY,gBAAoB,IAAA,CAAA,CAAA;AAChD,IAAM,MAAA,MAAA,GAAS,SAAa,GAAA,CAAA,aAAA,GAAgB,iBAAqB,IAAA,CAAA,CAAA;AAEjE,IAAA,GAAA,CAAI,SAAS,MAAQ,EAAA,EAAA,EAAI,MAAQ,EAAA,MAAA,EAAQ,kBAAkB,iBAAiB,CAAA,CAAA;AAC5E,IAAI,GAAA,CAAA,IAAA,CAAK,WAAW,MAAM,CAAA,CAAA;AAAA,GAC9B;AACJ;;;;"}
|
package/PrintingServiceImpl.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare class PrintJob {
|
|
|
10
10
|
private olMap;
|
|
11
11
|
private blockUserInteraction;
|
|
12
12
|
private overlayText;
|
|
13
|
+
private viewPadding;
|
|
13
14
|
private running;
|
|
14
15
|
private drawInformation;
|
|
15
16
|
private scaleLine;
|
|
@@ -20,6 +21,8 @@ export declare class PrintJob {
|
|
|
20
21
|
private addScaleLine;
|
|
21
22
|
private printToCanvas;
|
|
22
23
|
private reset;
|
|
24
|
+
private removePadding;
|
|
25
|
+
private getViewPadding;
|
|
23
26
|
}
|
|
24
27
|
declare class PrintResultImpl implements PrintResult {
|
|
25
28
|
private canvas;
|
package/PrintingServiceImpl.js
CHANGED
|
@@ -14,6 +14,7 @@ class PrintingServiceImpl {
|
|
|
14
14
|
const job = new PrintJob(olMap, {
|
|
15
15
|
blockUserInteraction: true,
|
|
16
16
|
overlayText: this.defaultOverlayText,
|
|
17
|
+
viewPadding: "auto",
|
|
17
18
|
...options
|
|
18
19
|
});
|
|
19
20
|
return await job.printMap();
|
|
@@ -23,6 +24,7 @@ class PrintJob {
|
|
|
23
24
|
olMap;
|
|
24
25
|
blockUserInteraction = false;
|
|
25
26
|
overlayText;
|
|
27
|
+
viewPadding;
|
|
26
28
|
running = false;
|
|
27
29
|
drawInformation = [];
|
|
28
30
|
scaleLine = void 0;
|
|
@@ -31,6 +33,7 @@ class PrintJob {
|
|
|
31
33
|
this.olMap = olMap;
|
|
32
34
|
this.blockUserInteraction = options.blockUserInteraction;
|
|
33
35
|
this.overlayText = options.overlayText;
|
|
36
|
+
this.viewPadding = options.viewPadding;
|
|
34
37
|
}
|
|
35
38
|
async printMap() {
|
|
36
39
|
if (this.running) {
|
|
@@ -38,12 +41,14 @@ class PrintJob {
|
|
|
38
41
|
}
|
|
39
42
|
try {
|
|
40
43
|
await this.beginExport();
|
|
41
|
-
|
|
42
|
-
if (canvas) {
|
|
43
|
-
return new PrintResultImpl(canvas);
|
|
44
|
-
} else {
|
|
44
|
+
let canvas = await this.printToCanvas(this.olMap.getViewport());
|
|
45
|
+
if (!canvas) {
|
|
45
46
|
throw new Error("Canvas export failed");
|
|
46
47
|
}
|
|
48
|
+
if (this.viewPadding === "auto") {
|
|
49
|
+
canvas = this.removePadding(canvas, this.getViewPadding());
|
|
50
|
+
}
|
|
51
|
+
return new PrintResultImpl(canvas);
|
|
47
52
|
} finally {
|
|
48
53
|
this.reset();
|
|
49
54
|
}
|
|
@@ -72,12 +77,25 @@ class PrintJob {
|
|
|
72
77
|
await this.addScaleLine();
|
|
73
78
|
}
|
|
74
79
|
async addScaleLine() {
|
|
75
|
-
this.scaleLine = new ScaleLine({
|
|
80
|
+
const scaleLine = this.scaleLine = new ScaleLine({
|
|
76
81
|
className: "printing-scale-bar ol-scale-bar",
|
|
77
82
|
bar: true,
|
|
78
83
|
text: true,
|
|
79
84
|
minWidth: 125
|
|
80
85
|
});
|
|
86
|
+
const scaleLineElement = scaleLine.element;
|
|
87
|
+
if (!scaleLineElement) {
|
|
88
|
+
throw new Error("Scale line does not have an element");
|
|
89
|
+
}
|
|
90
|
+
let bottom = 50;
|
|
91
|
+
let left = 8;
|
|
92
|
+
if (this.viewPadding === "auto") {
|
|
93
|
+
const { bottom: paddingBottom, left: paddingLeft } = this.getViewPadding();
|
|
94
|
+
bottom = Math.max(paddingBottom + 8, bottom);
|
|
95
|
+
left += paddingLeft;
|
|
96
|
+
}
|
|
97
|
+
scaleLineElement.style.setProperty("--printing-scale-bar-bottom", `${bottom}px`);
|
|
98
|
+
scaleLineElement.style.setProperty("--printing-scale-bar-left", `${left}px`);
|
|
81
99
|
const renderPromise = createManualPromise();
|
|
82
100
|
const timeout = setTimeout(() => {
|
|
83
101
|
renderPromise.reject(new Error("Scale line did not render"));
|
|
@@ -126,6 +144,48 @@ class PrintJob {
|
|
|
126
144
|
drawInfo.draw.getOverlay().setStyle(drawInfo.style);
|
|
127
145
|
});
|
|
128
146
|
}
|
|
147
|
+
removePadding(canvas, rawPadding) {
|
|
148
|
+
const dpr = window.devicePixelRatio || 1;
|
|
149
|
+
const dprPadding = {
|
|
150
|
+
top: rawPadding.top * dpr,
|
|
151
|
+
right: rawPadding.right * dpr,
|
|
152
|
+
bottom: rawPadding.bottom * dpr,
|
|
153
|
+
left: rawPadding.left * dpr
|
|
154
|
+
};
|
|
155
|
+
if (dprPadding.left === 0 && dprPadding.right === 0 && dprPadding.top === 0 && dprPadding.bottom === 0) {
|
|
156
|
+
return canvas;
|
|
157
|
+
}
|
|
158
|
+
const { width, height } = canvas;
|
|
159
|
+
const newCanvas = document.createElement("canvas");
|
|
160
|
+
newCanvas.width = width - dprPadding.left - dprPadding.right;
|
|
161
|
+
newCanvas.height = height - dprPadding.top - dprPadding.bottom;
|
|
162
|
+
const newCtx = newCanvas.getContext("2d");
|
|
163
|
+
if (!newCtx) {
|
|
164
|
+
throw new Error("Failed to get a canvas context");
|
|
165
|
+
}
|
|
166
|
+
newCtx.drawImage(
|
|
167
|
+
canvas,
|
|
168
|
+
dprPadding.left,
|
|
169
|
+
dprPadding.top,
|
|
170
|
+
newCanvas.width,
|
|
171
|
+
newCanvas.height,
|
|
172
|
+
0,
|
|
173
|
+
0,
|
|
174
|
+
newCanvas.width,
|
|
175
|
+
newCanvas.height
|
|
176
|
+
);
|
|
177
|
+
return newCanvas;
|
|
178
|
+
}
|
|
179
|
+
getViewPadding() {
|
|
180
|
+
const map = this.olMap;
|
|
181
|
+
const rawPadding = map.getView().padding ?? [0, 0, 0, 0];
|
|
182
|
+
return {
|
|
183
|
+
top: rawPadding[0] ?? 0,
|
|
184
|
+
right: rawPadding[1] ?? 0,
|
|
185
|
+
bottom: rawPadding[2] ?? 0,
|
|
186
|
+
left: rawPadding[3] ?? 0
|
|
187
|
+
};
|
|
188
|
+
}
|
|
129
189
|
}
|
|
130
190
|
class PrintResultImpl {
|
|
131
191
|
canvas;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrintingServiceImpl.js","sources":["PrintingServiceImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { PrintingOptions, PrintingService, PrintResult } from \"./index\";\nimport OlMap from \"ol/Map\";\nimport Draw from \"ol/interaction/Draw\";\nimport { StyleLike } from \"ol/style/Style\";\nimport { ScaleLine } from \"ol/control\";\nimport { Interaction } from \"ol/interaction\";\nimport { createManualPromise, Resource } from \"@open-pioneer/core\";\nimport { Options } from \"html2canvas\";\nimport { canvasToPng, createBlockUserOverlay, PRINTING_HIDE_CLASS } from \"./utils\";\nimport { ServiceOptions } from \"@open-pioneer/runtime\";\n\nexport class PrintingServiceImpl implements PrintingService {\n private defaultOverlayText: string;\n\n constructor(options: ServiceOptions) {\n this.defaultOverlayText = options.intl.formatMessage({\n id: \"printingMap\"\n });\n }\n\n async printMap(olMap: OlMap, options?: PrintingOptions): Promise<PrintResultImpl> {\n const job = new PrintJob(olMap, {\n blockUserInteraction: true,\n overlayText: this.defaultOverlayText,\n ...options\n });\n return await job.printMap();\n }\n}\n\n// Exported just for test (mocking)\nexport class PrintJob {\n private olMap: OlMap;\n private blockUserInteraction: boolean = false;\n private overlayText: string;\n\n private running = false;\n private drawInformation: { draw: Draw; style: StyleLike | null | undefined }[] | undefined = [];\n private scaleLine: ScaleLine | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, options: Required<PrintingOptions>) {\n this.olMap = olMap;\n this.blockUserInteraction = options.blockUserInteraction;\n this.overlayText = options.overlayText;\n }\n\n async printMap(): Promise<PrintResultImpl> {\n if (this.running) {\n throw new Error(\"Printing already running.\");\n }\n\n try {\n await this.beginExport();\n\n const canvas = await this.printToCanvas(this.olMap.getViewport());\n if (canvas) {\n return new PrintResultImpl(canvas);\n } else {\n throw new Error(\"Canvas export failed\");\n }\n } finally {\n // Always remove scale bar\n this.reset();\n }\n }\n\n private async beginExport() {\n this.running = true;\n\n /** hides active draw interactions while printing (set feature style to null ) */\n const interactions = this.olMap\n .getInteractions()\n .getArray()\n .filter((interaction: Interaction) => {\n return interaction.getActive() && interaction instanceof Draw;\n });\n this.drawInformation = [];\n interactions?.forEach((interaction) => {\n const draw = interaction as Draw;\n const previousStyle = draw.getOverlay().getStyle();\n draw.getOverlay().setStyle(null);\n this.drawInformation?.push({\n draw: draw,\n style: previousStyle\n });\n });\n\n if (this.blockUserInteraction) {\n const container = this.olMap?.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.overlayText);\n }\n }\n await this.addScaleLine();\n }\n\n private async addScaleLine() {\n this.scaleLine = new ScaleLine({\n className: \"printing-scale-bar ol-scale-bar\",\n bar: true,\n text: true,\n minWidth: 125\n });\n\n const renderPromise = createManualPromise<void>();\n\n // We expect the scale line to be rendered by the open layers map.\n // This is a sanity check that throws an error when that either doesn't happen\n // or if it takes an extremely large time.\n const timeout = setTimeout(() => {\n renderPromise.reject(new Error(\"Scale line did not render\"));\n }, 3000);\n\n const oldRender = this.scaleLine.render;\n this.scaleLine.render = (...args) => {\n oldRender.apply(this.scaleLine, args);\n renderPromise.resolve();\n };\n this.olMap?.addControl(this.scaleLine);\n\n try {\n // Wait until render (+ one additional frame just to be sure).\n await renderPromise.promise;\n await new Promise((resolve) => {\n requestAnimationFrame(resolve);\n });\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async printToCanvas(element: HTMLElement): Promise<HTMLCanvasElement> {\n // export options for html2canvas.\n const exportOptions: Partial<Options> = {\n useCORS: true,\n ignoreElements: function (element: Element) {\n if (element.classList && typeof element.classList === \"object\") {\n const classList = element.classList;\n return (\n classList.contains(\"map-anchors\") || classList.contains(PRINTING_HIDE_CLASS)\n );\n }\n return false;\n }\n };\n\n // Lazy load html2canvas: it is a large dependency (a few hundred KiB) that is only\n // required when actually printed. This speeds up the initial page load.\n const html2canvas = (await import(\"html2canvas\")).default;\n const canvas = await html2canvas(element, exportOptions);\n\n return canvas;\n }\n\n private reset() {\n if (this.scaleLine) {\n this.olMap?.removeControl(this.scaleLine);\n this.scaleLine = undefined;\n }\n if (this.overlay) {\n this.overlay.destroy();\n this.overlay = undefined;\n }\n\n this.running = false;\n\n /** show active draw interactions after printing (reset feature style to its previous style ) */\n this.drawInformation?.length &&\n this.drawInformation.forEach((drawInfo) => {\n drawInfo.draw.getOverlay().setStyle(drawInfo.style);\n });\n }\n}\n\nclass PrintResultImpl implements PrintResult {\n private canvas: HTMLCanvasElement;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n }\n getCanvas(): HTMLCanvasElement {\n return this.canvas;\n }\n\n getPNGDataURL(quality?: number): string {\n return canvasToPng(this.canvas, quality);\n }\n}\n"],"names":["element"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PrintingServiceImpl.js","sources":["PrintingServiceImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { PrintingOptions, PrintingService, PrintResult, ViewPaddingBehavior } from \"./index\";\nimport OlMap from \"ol/Map\";\nimport Draw from \"ol/interaction/Draw\";\nimport { StyleLike } from \"ol/style/Style\";\nimport { ScaleLine } from \"ol/control\";\nimport { Interaction } from \"ol/interaction\";\nimport { createManualPromise, Resource } from \"@open-pioneer/core\";\nimport { Options } from \"html2canvas\";\nimport { canvasToPng, createBlockUserOverlay, PRINTING_HIDE_CLASS } from \"./utils\";\nimport { ServiceOptions } from \"@open-pioneer/runtime\";\n\nexport class PrintingServiceImpl implements PrintingService {\n private defaultOverlayText: string;\n\n constructor(options: ServiceOptions) {\n this.defaultOverlayText = options.intl.formatMessage({\n id: \"printingMap\"\n });\n }\n\n async printMap(olMap: OlMap, options?: PrintingOptions): Promise<PrintResultImpl> {\n const job = new PrintJob(olMap, {\n blockUserInteraction: true,\n overlayText: this.defaultOverlayText,\n viewPadding: \"auto\",\n ...options\n });\n return await job.printMap();\n }\n}\n\ninterface ViewPadding {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n// Exported just for test (mocking)\nexport class PrintJob {\n private olMap: OlMap;\n private blockUserInteraction: boolean = false;\n private overlayText: string;\n private viewPadding: ViewPaddingBehavior;\n\n private running = false;\n private drawInformation: { draw: Draw; style: StyleLike | null | undefined }[] | undefined = [];\n private scaleLine: ScaleLine | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, options: Required<PrintingOptions>) {\n this.olMap = olMap;\n this.blockUserInteraction = options.blockUserInteraction;\n this.overlayText = options.overlayText;\n this.viewPadding = options.viewPadding;\n }\n\n async printMap(): Promise<PrintResultImpl> {\n if (this.running) {\n throw new Error(\"Printing already running.\");\n }\n\n try {\n await this.beginExport();\n\n let canvas = await this.printToCanvas(this.olMap.getViewport());\n if (!canvas) {\n throw new Error(\"Canvas export failed\");\n }\n\n if (this.viewPadding === \"auto\") {\n canvas = this.removePadding(canvas, this.getViewPadding());\n }\n return new PrintResultImpl(canvas);\n } finally {\n // Always remove scale bar\n this.reset();\n }\n }\n\n private async beginExport() {\n this.running = true;\n\n /** hides active draw interactions while printing (set feature style to null ) */\n const interactions = this.olMap\n .getInteractions()\n .getArray()\n .filter((interaction: Interaction) => {\n return interaction.getActive() && interaction instanceof Draw;\n });\n this.drawInformation = [];\n interactions?.forEach((interaction) => {\n const draw = interaction as Draw;\n const previousStyle = draw.getOverlay().getStyle();\n draw.getOverlay().setStyle(null);\n this.drawInformation?.push({\n draw: draw,\n style: previousStyle\n });\n });\n\n if (this.blockUserInteraction) {\n const container = this.olMap?.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.overlayText);\n }\n }\n await this.addScaleLine();\n }\n\n private async addScaleLine() {\n const scaleLine = (this.scaleLine = new ScaleLine({\n className: \"printing-scale-bar ol-scale-bar\",\n bar: true,\n text: true,\n minWidth: 125\n }));\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const scaleLineElement = (scaleLine as any).element as HTMLElement;\n if (!scaleLineElement) {\n throw new Error(\"Scale line does not have an element\");\n }\n\n // Position the scale bar manually.\n // The 50px should be plenty to avoid overlapping with open layers attributions on most cases.\n // Additionally, take the view padding into account (if behavior is 'auto').\n let bottom = 50;\n let left = 8;\n if (this.viewPadding === \"auto\") {\n const { bottom: paddingBottom, left: paddingLeft } = this.getViewPadding();\n bottom = Math.max(paddingBottom + 8, bottom);\n left += paddingLeft;\n }\n scaleLineElement.style.setProperty(\"--printing-scale-bar-bottom\", `${bottom}px`);\n scaleLineElement.style.setProperty(\"--printing-scale-bar-left\", `${left}px`);\n\n const renderPromise = createManualPromise<void>();\n\n // We expect the scale line to be rendered by the open layers map.\n // This is a sanity check that throws an error when that either doesn't happen\n // or if it takes an extremely large time.\n const timeout = setTimeout(() => {\n renderPromise.reject(new Error(\"Scale line did not render\"));\n }, 3000);\n\n const oldRender = this.scaleLine.render;\n this.scaleLine.render = (...args) => {\n oldRender.apply(this.scaleLine, args);\n renderPromise.resolve();\n };\n this.olMap?.addControl(this.scaleLine);\n\n try {\n // Wait until render (+ one additional frame just to be sure).\n await renderPromise.promise;\n await new Promise((resolve) => {\n requestAnimationFrame(resolve);\n });\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async printToCanvas(element: HTMLElement): Promise<HTMLCanvasElement> {\n // export options for html2canvas.\n const exportOptions: Partial<Options> = {\n useCORS: true,\n ignoreElements: function (element: Element) {\n if (element.classList && typeof element.classList === \"object\") {\n const classList = element.classList;\n return (\n classList.contains(\"map-anchors\") || classList.contains(PRINTING_HIDE_CLASS)\n );\n }\n return false;\n }\n };\n\n // Lazy load html2canvas: it is a large dependency (a few hundred KiB) that is only\n // required when actually printed. This speeds up the initial page load.\n const html2canvas = (await import(\"html2canvas\")).default;\n const canvas = await html2canvas(element, exportOptions);\n return canvas;\n }\n\n private reset() {\n if (this.scaleLine) {\n this.olMap?.removeControl(this.scaleLine);\n this.scaleLine = undefined;\n }\n if (this.overlay) {\n this.overlay.destroy();\n this.overlay = undefined;\n }\n\n this.running = false;\n\n /** show active draw interactions after printing (reset feature style to its previous style ) */\n this.drawInformation?.length &&\n this.drawInformation.forEach((drawInfo) => {\n drawInfo.draw.getOverlay().setStyle(drawInfo.style);\n });\n }\n\n private removePadding(canvas: HTMLCanvasElement, rawPadding: ViewPadding): HTMLCanvasElement {\n // The canvas returned by html2canvas is scaled by the device pixel ratio.\n // The padding needs to be adjusted (because its in css pixels).\n const dpr = window.devicePixelRatio || 1;\n const dprPadding = {\n top: rawPadding.top * dpr,\n right: rawPadding.right * dpr,\n bottom: rawPadding.bottom * dpr,\n left: rawPadding.left * dpr\n };\n\n if (\n dprPadding.left === 0 &&\n dprPadding.right === 0 &&\n dprPadding.top === 0 &&\n dprPadding.bottom === 0\n ) {\n return canvas;\n }\n\n const { width, height } = canvas;\n const newCanvas = document.createElement(\"canvas\");\n newCanvas.width = width - dprPadding.left - dprPadding.right;\n newCanvas.height = height - dprPadding.top - dprPadding.bottom;\n\n const newCtx = newCanvas.getContext(\"2d\");\n if (!newCtx) {\n throw new Error(\"Failed to get a canvas context\");\n }\n\n newCtx.drawImage(\n canvas,\n dprPadding.left,\n dprPadding.top,\n newCanvas.width,\n newCanvas.height,\n 0,\n 0,\n newCanvas.width,\n newCanvas.height\n );\n return newCanvas;\n }\n\n private getViewPadding(): ViewPadding {\n const map = this.olMap;\n // top, right, bottom, left\n const rawPadding = (map.getView().padding ?? [0, 0, 0, 0]) as [\n number,\n number,\n number,\n number\n ];\n return {\n top: rawPadding[0] ?? 0,\n right: rawPadding[1] ?? 0,\n bottom: rawPadding[2] ?? 0,\n left: rawPadding[3] ?? 0\n };\n }\n}\n\nclass PrintResultImpl implements PrintResult {\n private canvas: HTMLCanvasElement;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n }\n getCanvas(): HTMLCanvasElement {\n return this.canvas;\n }\n\n getPNGDataURL(quality?: number): string {\n return canvasToPng(this.canvas, quality);\n }\n}\n"],"names":["element"],"mappings":"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"}
|
package/README.md
CHANGED
|
@@ -64,7 +64,14 @@ const printResult = await printingService.printMap(map, {
|
|
|
64
64
|
### Printed elements
|
|
65
65
|
|
|
66
66
|
The printed map contains all map elements, visible layers, scale-bar and a title. If the user does not enter a title, the map is printed without title.
|
|
67
|
-
To prevent custom elements from showing in the printed map, add the
|
|
67
|
+
To prevent custom elements from showing in the printed map, add the CSS class name `printing-hide` to the elements.
|
|
68
|
+
|
|
69
|
+
### View padding
|
|
70
|
+
|
|
71
|
+
The printing widget and the printing service will by default respect the map's current view `padding` (see OpenLayers [View class](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html)).
|
|
72
|
+
This means that padded regions (a border on every side) will _not_ be included in the printed result.
|
|
73
|
+
|
|
74
|
+
To ignore the view padding when printing the map, you can pass `viewPadding: "ignore"` to the printing service or the printing component.
|
|
68
75
|
|
|
69
76
|
## Known issues
|
|
70
77
|
|
package/i18n/de.yaml
CHANGED
package/i18n/en.yaml
CHANGED
package/index.d.ts
CHANGED
|
@@ -16,7 +16,19 @@ export interface PrintingOptions {
|
|
|
16
16
|
* This option can be used to customize the text content of the overlay (if enabled).
|
|
17
17
|
*/
|
|
18
18
|
overlayText?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Whether to respect the map view's padding when printing (default: `"auto"`).
|
|
21
|
+
*/
|
|
22
|
+
viewPadding?: ViewPaddingBehavior;
|
|
19
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Whether to respect the map view's padding when printing.
|
|
26
|
+
*
|
|
27
|
+
* - `"auto"`: Respect the map's current viewPadding.
|
|
28
|
+
* Padded regions of the map will _not_ be included in the print result.
|
|
29
|
+
* - `"ignore"`: Ignore the map's viewPadding. The entire map will be printed.
|
|
30
|
+
*/
|
|
31
|
+
export type ViewPaddingBehavior = "auto" | "ignore";
|
|
20
32
|
/**
|
|
21
33
|
* The printing service provides an image of a map as a canvas element or a data URL for a PNG image.
|
|
22
34
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/printing",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"description": "This package provides a UI component to export the current map view as a printable file.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"open-pioneer-trails"
|
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
"directory": "src/packages/printing"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@open-pioneer/chakra-integration": "^1.1.
|
|
18
|
-
"@open-pioneer/runtime": "^2.1.
|
|
19
|
-
"@open-pioneer/core": "^1.2.
|
|
20
|
-
"@open-pioneer/notifier": "^0.3.
|
|
17
|
+
"@open-pioneer/chakra-integration": "^1.1.3",
|
|
18
|
+
"@open-pioneer/runtime": "^2.1.5",
|
|
19
|
+
"@open-pioneer/core": "^1.2.3",
|
|
20
|
+
"@open-pioneer/notifier": "^0.3.4",
|
|
21
21
|
"ol": "^9.0.0",
|
|
22
|
-
"react": "^18.
|
|
22
|
+
"react": "^18.3.1",
|
|
23
23
|
"classnames": "^2.3.2",
|
|
24
24
|
"html2canvas": "^1.4.1",
|
|
25
25
|
"jspdf": "^2.5.1",
|
|
26
|
-
"@open-pioneer/map": "^0.
|
|
27
|
-
"@open-pioneer/react-utils": "^0.2.
|
|
26
|
+
"@open-pioneer/map": "^0.5.1",
|
|
27
|
+
"@open-pioneer/react-utils": "^0.2.3"
|
|
28
28
|
},
|
|
29
29
|
"exports": {
|
|
30
30
|
"./package.json": "./package.json",
|
package/styles.css
CHANGED
|
@@ -22,4 +22,12 @@
|
|
|
22
22
|
text-align: center;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* more specific than the open layers selector */
|
|
26
|
+
|
|
27
|
+
.printing-scale-bar.ol-scale-bar {
|
|
28
|
+
/* these variables are set in the PrintingService and may include the map view's padding */
|
|
29
|
+
left: var(--printing-scale-bar-left);
|
|
30
|
+
bottom: var(--printing-scale-bar-bottom);
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
/*# sourceMappingURL=styles.css.map */
|
package/styles.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["styles.css"],"names":[],"mappings":"AAAA;IACI,yEAAyE;IACzE,kBAAkB;IAClB,QAAQ;IACR,cAAc;;IAEd,4EAA4E;IAC5E,iBAAiB;IACjB,mBAAmB;IACnB,YAAY;;IAEZ,aAAa;IACb,mBAAmB;IACnB,mBAAmB;IACnB,uBAAuB;IACvB,0CAA0C;AAC9C;;AAEA;IACI,cAAc;IACd,gBAAgB;IAChB,kBAAkB;AACtB","file":"styles.css","sourcesContent":[".printing-overlay {\n /* container uses position relative, so this absolute positioning works */\n position: absolute;\n inset: 0;\n z-index: 10000;\n\n /* non-interactive: the overlay is \"in front\" of the map and blocks events */\n user-select: none;\n pointer-events: all;\n cursor: wait;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n background-color: rgba(180, 180, 180, 0.8);\n}\n\n.printing-overlay-status {\n flex: 1 1 auto;\n font-size: 1.5em;\n text-align: center;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["styles.css"],"names":[],"mappings":"AAAA;IACI,yEAAyE;IACzE,kBAAkB;IAClB,QAAQ;IACR,cAAc;;IAEd,4EAA4E;IAC5E,iBAAiB;IACjB,mBAAmB;IACnB,YAAY;;IAEZ,aAAa;IACb,mBAAmB;IACnB,mBAAmB;IACnB,uBAAuB;IACvB,0CAA0C;AAC9C;;AAEA;IACI,cAAc;IACd,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA,gDAAgD;;AAChD;IACI,0FAA0F;IAC1F,oCAAoC;IACpC,wCAAwC;AAC5C","file":"styles.css","sourcesContent":[".printing-overlay {\n /* container uses position relative, so this absolute positioning works */\n position: absolute;\n inset: 0;\n z-index: 10000;\n\n /* non-interactive: the overlay is \"in front\" of the map and blocks events */\n user-select: none;\n pointer-events: all;\n cursor: wait;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n background-color: rgba(180, 180, 180, 0.8);\n}\n\n.printing-overlay-status {\n flex: 1 1 auto;\n font-size: 1.5em;\n text-align: center;\n}\n\n/* more specific than the open layers selector */\n.printing-scale-bar.ol-scale-bar {\n /* these variables are set in the PrintingService and may include the map view's padding */\n left: var(--printing-scale-bar-left);\n bottom: var(--printing-scale-bar-bottom);\n}\n"]}
|