question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Img with svg src with no dimensions renders only a part

See original GitHub issue

Describe the bug When rendering an svg which has no dimension attributes via src, and applying imgSize, the size does not apply to the resulting image. The same occurs when creating an <img> with that same src and applying width/height on the image. The image appears cropped, with a crop box on the given dimensions, but only part of the original svg is rendered. Scaling also affects its entire container, not just the svg.

Rendering the same <img> on a template works fine if width and height are supplied.

Expected behavior The icon should be rendered in the given imgSize, and not exceed those dimensions.

Details I saw that applying color, e.g. color: 'transparent' to the Icon resolves the issue. It seems that when a color is set, the image is redrawn on canvas using the correct scale. I managed to find the problem here: https://github.com/openlayers/openlayers/blob/3b5e95b6c1f790c24ad1d632b3cba4202f26eb1c/src/ol/style/IconImage.js#L244-L251

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
mike-000commented, Oct 17, 2022

There are still some SVGs where browsers return the wrong image size, e.g. for https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg Chrome returns width and height as 150 x 150, which is too small, but it can be drawn and scaled correctly to a canvas of that size. By trial and error you can find a workable imgSize such as [400, 400] but is is easier to let OpenLayers use a canvas by specifying color: 'transparent',. However neither approach works with Firefox.

0reactions
mike-000commented, Oct 26, 2022

In Firefox image.naturalWidth and image.naturalHeight are also zero and drawImage() does nothing even if image.width and image.height are set or reset in the code.

I have checked how Chrome handles these images.

context.drawImage(image, dx, dy);

is supposed to be equivalent to

context.drawImage(image, dx, dy, image.width, image.height);

but for unsized SVGs the image default width and height (which reflect the naturalWidth and naturalHeight) provide the aspect ratio, and the drawn image is sized to fit the canvas while maintaining aspect ratio, so is equivalent to

const imageRatio = image.width / image.height;
const contextRatio = context.canvas.width / context.canvas.height;
const width = imageRatio > contextRatio ? context.canvas.width : context.canvas.height * imageRatio;
const height = imageRatio > contextRatio ? context.canvas.width / imageRatio : context.canvas.height;
context.drawImage(image, dx, dy, width, height);

The syntax

context.drawImage(image, 0, 0, image.width, image.height, dx, dy, dWidth, dHeight);

only draws part of the image because Chrome considers the image to have dimensions as calculated above, so

const imageRatio = image.width / image.height;
const contextRatio = context.canvas.width / context.canvas.height;
const width = imageRatio > contextRatio ? context.canvas.width : context.canvas.height * imageRatio;
const height = imageRatio > contextRatio ? context.canvas.width / imageRatio : context.canvas.height;
context.drawImage(image, 0, 0, width, height, dx, dy, dWidth, dHeight);

does draw the whole image. But there seems to be nothing in the image properties to indicate whether it will be drawn in a normal way or whether this workaround is needed. So the only safe option is to draw to a canvas with dimensions matching the image width and height, and even that does not work in Firefox.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Chrome not rendering SVG referenced via <img> element
This happens when refreshing the page and initial page load. I can get the image to show up by "Inspecting Element" then right...
Read more >
Using SVG | CSS-Tricks
SVG is an image format for vector graphics. It literally means Scalable Vector Graphics. Basically, what you work with in Adobe Illustrator.
Read more >
<image> - SVG: Scalable Vector Graphics - MDN Web Docs
The <image> SVG element includes images inside SVG documents. It can display raster image files or other SVG files. The only image formats ......
Read more >
The Best Way to Embed SVG on HTML (2021) - Vecta.io
How does embedding SVGs using Img tags, Object tags, Inline SVG ... It is not part of HTML specifications but widely supported on...
Read more >
React SVG: How to use SVGs best in React - CopyCat Blog
The file extension of an SVG image is .svg and they do not lose ... of SVG icons but unlike Heroicon, you can...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found