Skip to content

Commit

Permalink
Rd 286: screenshots (#107)
Browse files Browse the repository at this point in the history
* Updated MapLibre version and adjusted MaptilerGeolocateControl

* removed the zoomAdjust unnecesary value in minimap

* Adding sky examples

* Now passing the options to the control

* Updated xmldom dep

* Add screenshot helper

* adding screenshot helper and readme

* Adding whole page screenshot

* removed an old async keyword

* removed an old async keyword

* removed an old async keyword

* linting

* adapt UMD bundle name to prod or dev mode

* removing whole page screenshot
  • Loading branch information
jonathanlurie authored Aug 29, 2024
1 parent faf96b1 commit e42ebb3
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 4 deletions.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
"doc": "rm -rf docs/* && typedoc --out docs && cp -r images docs/",
"test": "vitest run",
"build-css": "node scripts/replace-path-with-content.js src/style/style_template.css dist/tmp_maptiler-sdk.css && cat node_modules/maplibre-gl/dist/maplibre-gl.css dist/tmp_maptiler-sdk.css > dist/maptiler-sdk.css && rm dist/tmp_maptiler-sdk.css && cp dist/maptiler-sdk.css build/maptiler-sdk.css",
"build-umd": "NODE_ENV=production tsc && vite build -c vite.config-umd.ts",
"build-es": "NODE_ENV=production tsc && vite build -c vite.config-es.ts",
"build-umd": "tsc && NODE_ENV=production vite build -c vite.config-umd.ts",
"build-es": "tsc && NODE_ENV=production vite build -c vite.config-es.ts",
"build": "npm run build-es; npm run build-umd; npm run build-css",
"make": "npm run biome:fix && npm run build"
"make": "npm run biome:fix && npm run build",
"dev-umd": "npm run build-css && tsc && NODE_ENV=dev vite build -w -c vite.config-umd.ts",
"help": "vite build --help"
},
"author": "MapTiler",
"devDependencies": {
Expand Down
31 changes: 31 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,37 @@ Turning off *zoom compensation* allows for more accurate adjustments to the visu

All the other options are documented on [our reference page](https://docs.maptiler.com/sdk-js/api/helpers/#heatmap) and more examples are available [here](https://docs.maptiler.com/sdk-js/examples/?q=heatmap+helper).

# Other helper
## Take Screenshots, programmatically
There are two different ways to create screenshot, corresponding to two very different usecases. Note that screenshots will not contain *DOM elements* such as `Marker` and `Popup`, since those are not part of the rendering context.

**1. Get a `blob` of a screenshot, PNG encoded:**
```ts
import { Map, helpers } from "@maptiler/sdk";

// ... initialize a Map instance, wait for the "load" or "ready" event ...

// Inside an async function, or with using .then()
const blob = await helpers.takeScreenshot(map);
```
The returned `Blob` of a PNG image file can be very handy if the goal is to programmatically further manipulate the screenshot, such as sending it to some feedback endpoint with a POST request.

**2. Download a PNG file:**
```ts
import { Map, helpers } from "@maptiler/sdk";

// ... initialize a Map instance, wait for the "load" or "ready" event ...

// No need to be inside an async function, the download will be triggered when the file is ready
maptilersdk.helpers.takeScreenshot(map, {
download: true,
filename: "map_screenshot.png"
});
```
Getting a file directly is a nice option that can be useful to share some debugging context with colleagues, compare multiple styles, or share your creation on social media.

> 📣 *__Note:__* Keep in mind that MapTiler Cloud data are copyrighted and their usage is restricted. This include MapTiler built-in styles and tilesets, among others. In case of doubt, do not hesitate to read our [terms](https://www.maptiler.com/terms/) or to ask our [support team](https://www.maptiler.com/contacts/).
# Caching
Starting from v2, MapTiler SDK introduced the **caching** of tiles and fonts served by MapTiler Cloud, which can represent a large chunk of the data being fetched when browsing a map. This caching leverages modern browsers caching API so it's well-managed and there is no risk of bloating! When we update **MapTiler Planet** or our **official styles**, the caching logic will detect it and automatically invalidate older versions of the tiles that were previously cached.

Expand Down
2 changes: 2 additions & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { takeScreenshot } from "./screenshot";
import { addPolyline, addPolygon, addPoint, addHeatmap } from "./vectorlayerhelpers";

export type {
Expand All @@ -19,4 +20,5 @@ export const helpers = {
addPolygon,
addPoint,
addHeatmap,
takeScreenshot,
};
61 changes: 61 additions & 0 deletions src/helpers/screenshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Map as MapSDK } from "../Map";

/**
* Takes a screenshot (PNG file) of the curent map view.
* Depending on the options, this function can automatically trigger a download of te file.
*/
export async function takeScreenshot(
map: MapSDK,
options: {
/**
* If `true`, this function will trigger a download in addition to returning a blob.
* Default: `false`
*/
download?: boolean;

/**
* Only if `options.download` is `true`. Indicates the filename under which
* the file will be downloaded.
* Default: `"maptiler_screenshot.png"`
*/
filename?: string;
} = {},
): Promise<Blob> {
const download = options.download ?? false;
const blob = await getMapScreenshotBlob(map);

if (download) {
const filename = options.filename ?? "maptiler_screenshot.png";

const link = document.createElement("a");
link.style.display = "none";
document.body.appendChild(link);
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();

// Cleaning after event loop
setTimeout(() => {
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
}, 0);
}

return blob;
}

function getMapScreenshotBlob(map: MapSDK): Promise<Blob> {
return new Promise((resolve, reject) => {
map.redraw();

map.once("idle", () => {
map.getCanvas().toBlob((blob) => {
if (!blob) {
return reject(Error("Screenshot could not be created."));
}

resolve(blob);
}, "image/png");
});
});
}
1 change: 1 addition & 0 deletions vite.config-es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default defineConfig({
mode: isProduction ? "production" : "development",
build: {
minify: isProduction,
emptyOutDir: isProduction,
outDir: "dist",
sourcemap: true,
lib: {
Expand Down
4 changes: 3 additions & 1 deletion vite.config-umd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { resolve } from 'path';
import { defineConfig } from 'vite';

const isProduction = process.env.NODE_ENV === "production";
const bundleFilename = isProduction ? "maptiler-sdk.umd.min.js" : "maptiler-sdk.umd.js"

const plugins = [];

Expand All @@ -11,13 +12,14 @@ export default defineConfig({
build: {
outDir: "build",
minify: isProduction,
emptyOutDir: isProduction,
sourcemap: true,
lib: {
// Could also be a dictionary or array of multiple entry points
entry: resolve(__dirname, 'src/index.ts'),
name: 'maptilersdk',
// the proper extensions will be added
fileName: (format, entryName) => "maptiler-sdk.umd.js",
fileName: (format, entryName) => bundleFilename,
formats: ['umd'],
}
},
Expand Down

0 comments on commit e42ebb3

Please sign in to comment.