dev-docs/RFCs/v6.4/icon-layer-dynamic-image-sources.md
This RFC proposes a way to allow IconLayer to load image sources dynamically.
IconLayer currently requires all icons pre-packed into a sprite image (iconAtlas) and a JSON descriptor (iconMapping).
In some use cases, it is not possible to know the icons that will be used. Instead, each icon needs to be fetched from
a programmatically generated URL at runtime.
getIcon API to support auto packingChange the getIcon API to allow user to return either a string or an object.
Prepacked iconAtlas, getIcon return a string:
iconMapping and then to retrieve icon from iconAtlas.IconLayer, iconMppping and iconAtlas are required as before.Auto packing iconAtlas, getIcon return an object:
IconLayer, iconMppping and iconAtlas are not needed.object should include:
url: url to fetch the iconheight: height of iconwidth: width of iconanchorX: horizontal position of icon anchor. Default: half width.anchorY: vertical position of icon anchor. Default: half height.mask: whether icon is treated as a transparency mask.
true, user defined color is applied.false, pixel color from the image is applied. User still can specify the opacity through getColor.
Default: falsegetIcon return a string, iconAtlas and iconMapping are also required when constructing IconLayerimport DeckGL, {IconLayer} from 'deck.gl';
const ICON_MAPPING = {
marker: {x: 0, y: 0, width: 32, height: 32, mask: true}
};
const App = ({data, viewport}) => {
/**
* Data format:
* [
* {name: 'Colma (COLM)', address: '365 D Street, Colma CA 94014', exits: 4214, coordinates: [-122.466233, 37.684638]},
* ...
* ]
*/
const layer = new IconLayer({
id: 'icon-layer',
data,
pickable: true,
// `iconAtlas` and `iconMapping` are required
iconAtlas: 'images/icon-atlas.png',
iconMapping: {
marker: {
x: 0,
y: 0,
width: 128,
height: 128,
anchorY: 128,
mask: true
}
},
// return a string
getIcon: d => 'marker',
sizeScale: 15,
getPosition: d => d.coordinates,
getSize: d => 5,
getColor: d => [Math.sqrt(d.exits), 140, 0]
});
return (<DeckGL {...viewport} layers={[layer]} />);
};
getIcon return an objectimport DeckGL, {IconLayer} from 'deck.gl';
const ICON_MAPPING = {
marker: {x: 0, y: 0, width: 32, height: 32, mask: true}
};
const App = ({data, viewport}) => {
/**
* Data format:
* [
* {name: 'Colma (COLM)', avatar_url: 'https://data/colma_avatar.png', address: '365 D Street, Colma CA 94014', exits: 4214, coordinates: [-122.466233, 37.684638]},
* ...
* ]
*/
const layer = new IconLayer({
id: 'icon-layer',
data,
pickable: true,
sizeScale: 15,
getPosition: d => d.coordinates,
// `iconAtlas` and `iconMapping` are not needed
// return an object
getIcon: d => ({
url: d.avatar_url,
width: 128,
height: 128,
anchorY: 128,
mask: true
}),
getSize: d => 5,
getColor: d => [Math.sqrt(d.exits), 140, 0]
});
return (<DeckGL {...viewport} layers={[layer]} />);
};
The proposal will require the following changes:
IconManager class: add a new class to help fetch icons and manage iconMapping and iconAltas from
dynamically fetched icons.IconLayer needs update to handle both pre-packed sprite image and auto packing icons.If implemented:
iconMapping
and update texture data when each icon fetched.For the same IconLayer, getIcon could return string (name used to retrieve icon from pre-packed iconAtlas)
for some data points, but return object (containing a url to fetch the icon) for others.