Basic Coder
Basic Coder

Reputation: 11422

Display SVG in its ViewBox size

I am using the img-Tag to display SVG images which my users uplaoded to my Amazon S3 bucket.

<img src="http://testbucket.s3.amazonaws.com/mysvg.svg" />

The problem is that, once the image is loaded and shown, it's not the size it was constructed for. For example a test image is displayed with a size of 1920x1920px but its ViewBox is 0 0 128 128. However, I would like to display the image in the size of its ViewBox. In this case 128x128px.

The only idea I came up with is downloading the image with an ajax request and parse the ViewBox attribute out of the svg source. Than I adjust the size. However, I do not want to make any unnecessary http requests and I am looking for a solution to read the images ViewBox dimensions. I could use the <object>-Tag to load the image but since it's hosted on Amazon I get a cross domain issue and cannot read the svgs source. Even when adding CORS rules to my bucket.

Ideas?

Upvotes: 1

Views: 808

Answers (2)

Kaiido
Kaiido

Reputation: 136627

You could try this approach :

  • Download the svg file with an Ajax request.
  • Parse the viewbox of that svg from the response.
  • Create a new Image();
  • Set the image's src to "data:image/svg+xml; charset =utf8,"+encodeURIComponent(the ajax response).
  • Set the image width/height from the viewBox infos you grabbed step 2 (via css or in its attributes).

That should work for all majors browsers supporting svg in <img>, and since you just appended the response string into the image src, you only make one single request to Amazon's servers.

So, e.g, it could give you a function like so :

function viewBoxedImgSVG(container, url){
    //There might be a better way to parse it...
    var parseViewBox = function(data){
        var parsed = data.match(/viewBox="(.*?)."/);
        if(parsed) return parsed[1].split(' ');
        }
    var xhr= new XMLHttpRequest();
    xhr.onload = function(){
        var img = new Image();
        // responseText for IE, but doesn't support SMIL in img tag anyway
        img.src = "data:image/svg+xml; charset=utf8,"+encodeURIComponent(xhr.responseText);
        var vB = parseViewBox(xhr.responseText);
        if(vB){
            img.width = vB[2];
            img.height = vB[3];
            }
        container.appendChild(img);
        }
    xhr.open('GET', url);
    xhr.send();
}

Upvotes: 2

Paul LeBeau
Paul LeBeau

Reputation: 101800

I have a couple of suggestions:

  1. I am not sure if this works - in general, or with AWS - but you could try doing an AJAX request with "Range" HTTP request header. The idea being that you only fetch the first few hundred bytes of the SVG file.

  2. Assuming you are in control of the uploading, you could add the dimensions to the file name. Ie. "mysvg_128x128.svg" and parse the values from the name.

Upvotes: 1

Related Questions