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

When trying to use dimensionless SVG as icon: "Passed-in canvas is empty" #15823

Open
addiks opened this issue May 13, 2024 · 1 comment
Open
Labels

Comments

@addiks
Copy link

addiks commented May 13, 2024

I try to use a glyphicon (commercial icon set) SVG icon as an icon in a openlayer map.
This fails becuase the SVG files have no dimension data (width / height) in the file itself:

<svg id="glyphicons-basic" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  <path ... />
</svg>

Trying to load this SVG file as an icon in openlayers as such ...:

return new Style({
  image: new Icon({
    src: "glyphicons/glyphicons-basic/svg/individual-svg/glyphicons-basic-412-dice.svg",
    width: 32,
    height: 32,
  }),
});

... fails with this error:

Uncaught DOMException: CanvasRenderingContext2D.drawImage: Passed-in canvas is empty
    drawImageOrLabel canvas.js:474
    replayImageOrLabel_ Executor.js:558
    execute_ Executor.js:986
    execute Executor.js:1263
    execute ExecutorGroup.js:393
    renderWorlds VectorLayer.js:209
    renderFrame VectorLayer.js:356
    render Layer.js:372
    renderFrame Composite.js:131
    renderFrame_ Map.js:1570
    animationDelay_ Map.js:1424
    render Map.js:1457
    dispatchEvent Target.js:114
    changed Observable.js:70
    handleLayerChange_ Group.js:151
    dispatchEvent Target.js:114
    changed Observable.js:70
    renderIfReadyAndVisible Layer.js:188
    handleStyleImageChange_ VectorLayer.js:571
    renderFeature vector.js:134
    promise callback*renderFeature vector.js:134
    renderFeature VectorLayer.js:810
    render VectorLayer.js:721
    prepareFrame VectorLayer.js:741
    render Layer.js:370
    renderFrame Composite.js:131
    renderFrame_ Map.js:1570
    animationDelay_ Map.js:1424
    render Map.js:1457
    handleViewPropertyChanged_ Map.js:1354
    dispatchEvent Target.js:114
    notify Object.js:188
    set Object.js:223
    applyTargetState_ View.js:1755
    setCenterInternal View.js:1661
    setCenter View.js:1650
    complete my_map.ts:216

This error can (theoretically) be resolved if I add a width and height to the SVG file itself:

<svg 
  id="glyphicons-basic" 
  xmlns="http://www.w3.org/2000/svg" 
  viewBox="0 0 32 32" 
  width="32px"
  height="32px"
>
  <path ... />
</svg>

But this is not really feasible in my situation, because this is an external (and thus fixed) set of SVG files which I would rather not have to touch on every update. Also, adding width and height to these files degrades their usefulness since they are supposed to be used in a wide range of different sizes. They are supposed to not have any dimensions.

What I would have expected is that openlayers would use the dimensions that I have provided in the instantiation of the Icon object, but they seem to have no effect when loading the SVG file:

  image: new Icon({
    ...
    width: 32, // These dimensions should be used to create the canvas, 
    height: 32, //    instead of the (non-existing) dimensions from the SVG file.
  }),

Used openlayers versions (excerpt from yarn list):

...
├─ ol@9.1.0
│  ├─ color-rgba@^3.0.0
│  ├─ color-space@^2.0.1
│  ├─ earcut@^2.2.3
│  ├─ geotiff@^2.0.7
│  ├─ pbf@3.2.1
│  └─ rbush@^3.0.1
...

Tested in Firefox 125.0.3 (64-Bit)

@addiks addiks added the bug label May 13, 2024
@mike-000
Copy link
Contributor

That is a Firefox issue. Unsized SVGs cannot be drawn to canvas in any application. Additionally they cannot be scaled in 2 dimensions unless the preserveAspectRatio attribute is explicitly set to none. Although unsized SVGs can be drawn to canvas in other browsers the results can be inconsistent, e.g. in Chrome they may be sized based on the size of the canvas. If you must use them you will need a custom loader to inject appropriate defaults for consistent results. See #14933 for an example.

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

No branches or pull requests

2 participants