Skip to content

Commit

Permalink
Add "Map#addImage"
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Wojciechowski committed Mar 10, 2017
1 parent 06e2606 commit 478bbe4
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 13 deletions.
57 changes: 57 additions & 0 deletions debug/addimage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel='stylesheet' href='/dist/mapbox-gl.css' />
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>

<body>
<div id='map'></div>
<img id='kitten' src= />

<script src='/dist/mapbox-gl-dev.js'></script>
<script src='/debug/access_token_generated.js'></script>
<script>

var map = window.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10'
});

map.on('load', () => {
const img = document.createElement('img');
img.src = '/test/integration/image/marker.png';
img.onload = () => {
map.addImage('img', img);
map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.414, 37.776]
}
}]
}
},
"layout": {
"icon-image": "img"
}
});
};
});

</script>
</body>
</html>
57 changes: 44 additions & 13 deletions src/symbol/sprite_atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const ShelfPack = require('@mapbox/shelf-pack');
const browser = require('../util/browser');
const util = require('../util/util');
const window = require('../util/window');

class AtlasImage {
constructor(rect, width, height, sdf, pixelRatio) {
Expand Down Expand Up @@ -50,6 +51,37 @@ class SpriteAtlas {
return rect;
}

// pixels may be a HTMLImageElement or ImageData object or URL string
addImage(name, pixels, width, height) {
if (pixels instanceof window.HTMLImageElement) {
width = pixels.width;
height = pixels.height;
pixels = browser.getImageData(pixels);
}

if (ArrayBuffer.isView(pixels)) {
pixels = new Uint32Array(pixels.buffer);
}

if (!(pixels instanceof Uint32Array)) {
throw new Error('Image provided in an invalid format. Supported formats are HTMLImageElement, ImageData, and ArrayBufferView.');
}

if (this.images[name]) {
throw new Error('An image with this name already exists.');
}

const rect = this.allocateImage(width, height);
if (!rect) {
throw new Error('There is not enough space to add this image.');
}

const image = new AtlasImage(rect, width / this.pixelRatio, height / this.pixelRatio, false, 1);
this.images[name] = image;

this.copy(pixels, width, rect, {pixelRatio: this.pixelRatio, x: 0, y: 0, width, height}, false);
}

getImage(name, wrap) {
if (this.images[name]) {
return this.images[name];
Expand All @@ -72,7 +104,9 @@ class SpriteAtlas {
const image = new AtlasImage(rect, pos.width / pos.pixelRatio, pos.height / pos.pixelRatio, pos.sdf, pos.pixelRatio / this.pixelRatio);
this.images[name] = image;

this.copy(rect, pos, wrap);
if (!this.sprite.imgData) return null;
const srcImg = new Uint32Array(this.sprite.imgData.buffer);
this.copy(srcImg, this.sprite.width, rect, pos, wrap);

return image;
}
Expand Down Expand Up @@ -108,27 +142,24 @@ class SpriteAtlas {
}
}

copy(dst, src, wrap) {
if (!this.sprite.imgData) return;
const srcImg = new Uint32Array(this.sprite.imgData.buffer);

copy(srcImg, srcImgWidth, dstPos, srcPos, wrap) {
this.allocate();
const dstImg = this.data;

const padding = 1;

copyBitmap(
/* source buffer */ srcImg,
/* source stride */ this.sprite.width,
/* source x */ src.x,
/* source y */ src.y,
/* source stride */ srcImgWidth,
/* source x */ srcPos.x,
/* source y */ srcPos.y,
/* dest buffer */ dstImg,
/* dest stride */ this.width * this.pixelRatio,
/* dest x */ (dst.x + padding) * this.pixelRatio,
/* dest y */ (dst.y + padding) * this.pixelRatio,
/* icon dimension */ src.width,
/* icon dimension */ src.height,
/* wrap */ wrap
/* dest x */ (dstPos.x + padding) * this.pixelRatio,
/* dest y */ (dstPos.y + padding) * this.pixelRatio,
/* icon dimension */ srcPos.width,
/* icon dimension */ srcPos.height,
/* wrap */ wrap
);

this.dirty = true;
Expand Down
4 changes: 4 additions & 0 deletions src/ui/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,10 @@ class Map extends Camera {
return this.style.getSource(id);
}

addImage(name, image, width, height) {
this.style.spriteAtlas.addImage(name, image, width, height);
}

/**
* Adds a [Mapbox style layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers)
* to the map's style.
Expand Down

0 comments on commit 478bbe4

Please sign in to comment.