Skip to content

Commit 38774e9

Browse files
Fix park/art icons using canvas-rendered emoji images
MapLibre SDF fonts don't support emoji in text-field. Render emoji to canvas and register via addImage() + icon-image instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent aa43d73 commit 38774e9

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

js/map.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,30 @@ export function initMap() {
5151

5252
map.addControl(new maplibregl.NavigationControl(), 'top-left');
5353

54-
map.on('load', () => resolve(map));
54+
map.on('load', () => {
55+
// Register emoji icons rendered via canvas
56+
addEmojiImage(map, 'park-icon', '🌳', 40);
57+
addEmojiImage(map, 'art-icon', '🎨', 36);
58+
resolve(map);
59+
});
5560
});
5661
}
5762

63+
/**
64+
* Render an emoji to a canvas and add it as a map image.
65+
*/
66+
function addEmojiImage(map, id, emoji, size) {
67+
const canvas = document.createElement('canvas');
68+
canvas.width = size;
69+
canvas.height = size;
70+
const ctx = canvas.getContext('2d');
71+
ctx.font = `${size - 4}px serif`;
72+
ctx.textAlign = 'center';
73+
ctx.textBaseline = 'middle';
74+
ctx.fillText(emoji, size / 2, size / 2);
75+
map.addImage(id, { width: size, height: size, data: ctx.getImageData(0, 0, size, size).data });
76+
}
77+
5878
/**
5979
* Add or replace the trails layer with scored data.
6080
*/
@@ -125,13 +145,13 @@ export function setParksLayer(geojson) {
125145
type: 'symbol',
126146
source: 'parks',
127147
layout: {
128-
'text-field': '🌳',
129-
'text-size': [
148+
'icon-image': 'park-icon',
149+
'icon-size': [
130150
'interpolate', ['linear'], ['zoom'],
131-
10, 12,
132-
14, 20
151+
10, 0.4,
152+
14, 0.8
133153
],
134-
'text-allow-overlap': true,
154+
'icon-allow-overlap': true,
135155
},
136156
});
137157

@@ -170,13 +190,13 @@ export function setArtLayer(geojson) {
170190
type: 'symbol',
171191
source: 'art',
172192
layout: {
173-
'text-field': '🎨',
174-
'text-size': [
193+
'icon-image': 'art-icon',
194+
'icon-size': [
175195
'interpolate', ['linear'], ['zoom'],
176-
10, 10,
177-
14, 18
196+
10, 0.35,
197+
14, 0.7
178198
],
179-
'text-allow-overlap': true,
199+
'icon-allow-overlap': true,
180200
},
181201
});
182202

0 commit comments

Comments
 (0)