Add a stretchable image to the map
Use a stretchable image as a background for text. Stretchable images allow some parts of the image to stretch while keeping other parts, such as corners, at a constant size. Set the layout
property 'icon-text-fit': 'both'
to use the image as background for the text.
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Add a stretchable image to the map</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><script src="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.js"></script><link href="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.css" rel="stylesheet" /><style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><div id="map"></div> <script> // TO MAKE THE MAP APPEAR YOU MUST ADD YOUR ACCESS TOKEN nmapsgl.accessToken = '<your access token here>'; const map = new nmapsgl.Map({container: 'map',style: 'Streets',zoom: 0.1}); const images = {'popup': 'https://nmaps-gl.ndrive.com/nmaps-gl-js/assets/popup.png','popup-debug':'https://nmaps-gl.ndrive.com/nmaps-gl-js/assets/popup_debug.png'}; loadImages(images, (loadedImages) => {map.on('load', () => {map.addImage('popup-debug', loadedImages['popup-debug'], {// The two (blue) columns of pixels that can be stretched horizontally:// - the pixels between x: 25 and x: 55 can be stretched// - the pixels between x: 85 and x: 115 can be stretched.stretchX: [[25, 55],[85, 115]],// The one (red) row of pixels that can be stretched vertically:// - the pixels between y: 25 and y: 100 can be stretchedstretchY: [[25, 100]],// This part of the image that can contain text ([x1, y1, x2, y2]):content: [25, 25, 115, 100],// This is a high-dpi image:pixelRatio: 2});map.addImage('popup', loadedImages['popup'], {stretchX: [[25, 55],[85, 115]],stretchY: [[25, 100]],content: [25, 25, 115, 100],pixelRatio: 2}); map.addSource('points', {'type': 'geojson','data': {'type': 'FeatureCollection','features': [{'type': 'Feature','geometry': {'type': 'Point','coordinates': [40, -30]},'properties': {'image-name': 'popup-debug','name': 'Line 1\nLine 2\nLine 3'}},{'type': 'Feature','geometry': {'type': 'Point','coordinates': [40, 30]},'properties': {'image-name': 'popup','name': 'Line 1\nLine 2\nLine 3'}},{'type': 'Feature','geometry': {'type': 'Point','coordinates': [-40, -30]},'properties': {'image-name': 'popup-debug','name': 'One longer line'}},{'type': 'Feature','geometry': {'type': 'Point','coordinates': [-40, 30]},'properties': {'image-name': 'popup','name': 'One longer line'}}]}});map.addLayer({'id': 'points','type': 'symbol','source': 'points','layout': {'text-field': ['get', 'name'],'icon-text-fit': 'both','icon-image': ['get', 'image-name'],'icon-allow-overlap': true,'text-allow-overlap': true}}); // the original, unstretched image for comparisonmap.addSource('original', {'type': 'geojson','data': {'type': 'FeatureCollection','features': [{'type': 'Feature','geometry': {'type': 'Point','coordinates': [0, -70]}}]}});map.addLayer({'id': 'original','type': 'symbol','source': 'original','layout': {'text-field': 'unstretched image','icon-image': 'popup-debug','icon-allow-overlap': true,'text-allow-overlap': true}});});}); function loadImages(urls, callback) {const results = {};for (const name in urls) {map.loadImage(urls[name], makeCallback(name));} function makeCallback(name) {return (err, image) => {results[name] = err ? null : image; // if all images are loaded, call the callbackif (Object.keys(results).length === Object.keys(urls).length) {callback(results);}};}}</script> </body></html>