-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Map#addImage" / "Map#removeImage" #4404
Conversation
4473cd3
to
c1b0972
Compare
3c3df32
to
e555657
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 This is exciting! Couple questions/comments, mostly around documentation.
src/symbol/sprite_atlas.js
Outdated
|
||
const rect = this.allocateImage(width, height); | ||
if (!rect) { | ||
this.fire('error', {error: new Error('There is not enough space to add this image.')}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this return early?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! 😰
src/symbol/sprite_atlas.js
Outdated
delete this.images[name]; | ||
|
||
if (!image) { | ||
this.fire('error', {error: new Error('No image with this name exists.')}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! 😰
src/symbol/sprite_atlas.js
Outdated
rect, | ||
{pixelRatio: pixelRatio, x: 0, y: 0, width: image.width * pixelRatio, height: image.width * pixelRatio}, | ||
false | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to overwrite the existing image data with an empty image? If so, then it might be good to leave a one-line comment here noting why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this code out of fear of edge cases with semitransparent images & linear interpolation. Testing suggests these concerns are unwarranted. Removing it for now.
src/symbol/sprite_atlas.js
Outdated
@@ -14,9 +16,11 @@ class AtlasImage { | |||
} | |||
} | |||
|
|||
class SpriteAtlas { | |||
class SpriteAtlas extends Evented { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a comment about the changes in this PR, but just noting while I'm here: having never worked in this code before, I found it confusing, at first, to make sense of how/why SpriteAtlas
works. E.g., "what's with the this.copy()
?", "what's a rect
?", "why does AtlasImage
not have a reference to the underlying data?"
Reading more widely through the codebase, I think I've satisfied my questions, but this might be a nice time to add a brief, high-level description of what SpriteAtlas
is/does. OTOH ticketing that separately is also totally fair 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All fair points!
I lost about a week trying to refactor, simplify, and document our whole style image subsystem and eventually decided that the minimal patch to add this feature was worth executing.
I'll push another commit with some targeted renames & comments to better explain SpriteAtlas
until we get around to a bigger cleanup.
src/ui/map.js
Outdated
* @param {number} options.width The pixel width of the `ArrayBufferView` image | ||
* @param {number} options.height The pixel height of the `ArrayBufferView` image | ||
* @param {Object} options.pixelRatio The ratio of pixels in the `ArrayBufferView` image to physical pixels on the screen | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this could result in an error when there isn't enough space for a new image, should we document that possibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM other than a few minor documentation adjustments.
src/ui/map.js
Outdated
@@ -818,6 +818,30 @@ class Map extends Camera { | |||
} | |||
|
|||
/** | |||
* Add an image to the style. This image can be used in `icon-image`, | |||
* `background-pattern`, `fill-patern`, and `line-pattern`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fill-patern
⇢ fill-pattern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/ui/map.js
Outdated
* @param {Object} [options] Only required if passing an `ArrayBufferView` | ||
* @param {number} options.width The pixel width of the `ArrayBufferView` image | ||
* @param {number} options.height The pixel height of the `ArrayBufferView` image | ||
* @param {Object} options.pixelRatio The ratio of pixels in the `ArrayBufferView` image to physical pixels on the screen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{Object}
⇢ {number}
. Also, should this be marked as optional? It looks like the implementation will default to screen pixelRatio if it's not provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I think this is ready to go. How does it look @anandthakker? |
this.width = width; | ||
this.height = height; | ||
|
||
this.atlas = new ShelfPack(width, height); | ||
this.shelfPack = new ShelfPack(width, height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this rename. ShelfPack
is more of an algorithm name than a name that describes an instance. atlas
is better IMO, and consistent with the class name (SpriteAtlas
) since the latter is a wrapper around a generic atlas for image sprites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point and agree that the semantics of the name are questionable. My intent was to reduce the size of the vocabulary and amount of indirection in this class.
SpriteAtlas
has ashelfPack
SpriteAtlas#shelfPack
is an instance ofShelfPack
SpriteAtlas#shelfPack
hasbins
SpriteAtlas
has aatlas
SpriteAtlas#atlas
is an instance ofShelfPack
SpriteAtlas#atlas
hasbins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a wrapper around a generic atlas for image sprites.
If SpriteAtlas#atlas
were a generic texture atlas, I'd be keen on calling it such. As it stands, this member only provides the "shelf pack" algorithm and not the rest of the texture atlas functionality.
LGTM @lucaswoj |
Merging and working on an example / demo as a follow-up 😄 |
@lucaswoj - thank you so much, this looks awesome, and is so exciting for us. No more flickering maps for us! |
* Update yarn.lock files * Add "Map#addImage" * Make `SpriteAtlas` fire `error` and `data` events * Add "Map#removeImage" * Relax requirement that styles using "icon-image" must have a "sprite" * Add "pixelRatio" parameter to "Map#addImage" * Enable "runtime-styling/image-add" integration test * Add "runtime-styling/image-remove" integration test * Add "runtime-styling/image-add-pattern" integration test * Add docs for `Map#addImage` and `Map#removeImage` * Add explanatory comment to `SpriteAtlas` * Rename SpriteAtlas#atlas to SpriteAtlas#shelfPack * Eliminate `AtlasImage` * Moar comments * Ensure `SpriteAtlas#addImage` returns early after an error * Misc docs improvements * Remove logic that clears texture when image is removed * fixup! Eliminate `AtlasImage` * Remove addImage debug page
I'm way late to this party, but how do we handle stale |
This PR adds the
Map#addImage
andMap#removeImage
methods which give users the ability to modify their sprite at runtime.Fixes #2059
Launch Checklist
shelf-pack
versionSpriteAtlas
fireerror
eventsSpriteAtlas
firedata
eventsMap#removeImage
Map#removeImage
Map#addImage
to create a repeating patternMap#addImage
andMap#removeImage