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://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-gl.js"></script><link href="https://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-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>var map = new trackasiagl.Map({container: 'map',style: 'https://static.track-asia.com/demotiles/styles/osm-bright-gl-style/style.json?key=public_key',zoom: 0.1}); var images = {'popup': 'https://docs.track-asia.com/assets/popup.png','popup-debug': 'https://docs.track-asia.com/assets/popup_debug.png'}; loadImages(images, function (loadedImages) {map.on('load', function () {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-overlap': 'always','text-overlap': 'always'}}); // 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-overlap': 'always','text-overlap': 'always'}});});}); function loadImages(urls, callback) {var results = {};for (var name in urls) {map.loadImage(urls[name], makeCallback(name));} function makeCallback(name) {return function (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>