Skip to content
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

Remixing sprites #8

Open
orangemug opened this issue Jul 27, 2020 · 4 comments
Open

Remixing sprites #8

orangemug opened this issue Jul 27, 2020 · 4 comments

Comments

@orangemug
Copy link
Owner

A problem I'm having at the moment is reusing a base style, osm-liberty for example, while adding my own symbol layers on top. This is currently hard because I'd have to regenerate the osm-liberty stylesheet to include my images. If osm-liberty updates it's spritesheet I need to be aware of that and regenerate the spritesheet again. This is a massive pain and make reusing styles hard.

I believe this library can improve this experience by remixing stylesheets. I think we can do this by adding a type to our images definition. So where as currently we can pull in only images

[
  {"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
  {"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
  {"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]

We'd also be able to pull in any sprite. An example might be

[
  {
    "type": "spritesheet"
    "url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
  },
  {"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
  {"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
  {"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]

This would pull in all the images from https://maputnik.github.io/osm-liberty/sprites/osm-liberty repackaging them along with the other images into a new spritesheet.

The caching etag would also now be generated from both the definition (shown above) and the JSON source of the https://maputnik.github.io/osm-liberty/sprites/osm-liberty endpoint. This means that if the sprites change at the external endpoint we'll send a 304 not modified.

I think we can do this with a combined hash of all the resources, concatinating the hashes with a | char (or something better)

So we resolve definition like so

[
  {
    "type": "spritesheet"
    "url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
  },
  {"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
  {"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
  {"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]

Then we'd remove any spritesheet's from the definition so we'd now have 2 sets of resources.

[
  {"id": "red", "url": "http://example.com/images/red.jpg", "width": 20, "height": 20},
  {"id": "green", "url": "http://example.com/images/green.svg", "width": 32, "height": 32},
  {"id": "blue", "url": "http://example.com/images/blue.png", "width": 20, "height": 20}
]
{
  "type": "spritesheet"
  "url": "https://maputnik.github.io/osm-liberty/sprites/osm-liberty"
}

Now the HTTP request has passed a If-None-Match to match against our etag we'll split by our | and pass the If-None-Match to each resource on request. An example the HTTP request to our server comes with the following If-None-Match header

W/"5ed0f108-6789|6ed0f231-9271"

We make requests to each resource passing the hash via the If-None-Match which will in turn return a 304 if matched.

Although you could pull from multiple external resources that is probably unlikely. However if you do if one request 304's and the other doesn't. Then you'd need to re-request the data from the endpoint that returned 304 to get the body of the content.

The idea of all of this is that we're passing on the least work as we can to our down stream servers, letting the browser or CDN cache return the cached response.

@pathmapper
Copy link

pathmapper commented Jul 27, 2020

A problem I'm having at the moment is reusing a base style, osm-liberty for example, while adding my own symbol layers on top.

The intended way to solve this use case is to use addImage, GL JS adds your custom images to the sprite internally.
What's the use case for merging two sprites? Is it, that you can't use spriter together with a style which is already having a sprite because there is only one per style allowed?

This would pull in all the images from https://maputnik.github.io/osm-liberty/sprites/osm-liberty repackaging them along with the other images into a new spritesheet.

Which pixel ratio do you pull from https://maputnik.github.io/osm-liberty/sprites/osm-liberty:

  • Pull in the highest available and scale them down if you want to serve a lower pixel ratio with spriter?
  • Pull in all available and use them for the matching pixel ratio with spriter?

Would it be possible to serve a higher pixel ratio with spriter than available from https://maputnik.github.io/osm-liberty/sprites/osm-liberty?

@pathmapper
Copy link

OK, after re-reading it, you gave the answer for the use case with

If osm-liberty updates it's spritesheet I need to be aware of that and regenerate the spritesheet again.

@orangemug
Copy link
Owner Author

Which pixel ratio do you pull from https://maputnik.github.io/osm-liberty/sprites/osm-liberty:

So I think you'd just pull the @[pixel_ratio]x.[ext] you're currently requesting. So if you requesting @2x.json you pull the same from the remote sprite. You then wouldn't need to do any manipulation to the image, it'd literally be copying a pixel range from the remote image to the new sprite.

@orangemug
Copy link
Owner Author

Would it be possible to serve a higher pixel ratio with spriter than available from https://maputnik.github.io/osm-liberty/sprites/osm-liberty?

Hmmm that raises good point, since we're just taking the png, I guess we could be missing a ratio. I guess 2 options here we could just decrease the pixel ratio until we find one that matches. Then scale up those images, they'll be blurry (unscaled) but it's probably better that it works. I guess we could also throw an error, although then you'd get no images, so it's probably better it works poorly than not at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants