Comment mettre à l'échelle un SVG têtu incorporé avec la balise <object>?

114

J'ai quelques fichiers SVG qui spécifient widthet heightainsi que viewboxceci:

<svg width="576pt" height="432pt" viewBox="0 0 576 432" > ...

mais comment les afficher dans le navigateur à une taille que je décide? Je les veux plus petits et j'ai essayé:

<object width="400" data="image.svg"></object>

mais alors j'obtiens des barres de défilement visibles.

Cela fonctionne si je change les fichiers SVG pour définir widthet heightpour à la 100%place, mais je veux décider de la taille dans le HTML quelles que soient les tailles utilisées dans le fichier SVG. Est-ce possible ?

Zitrax
la source
Je suis confus, la dernière phrase se lit comme la solution que vous recherchez? Définir la largeur / hauteur SVG sur 100% / 100% laisse au HTML le soin de définir la zone dans laquelle le dessiner?
marque
3
Le problème est que je n'ai trouvé aucun moyen de changer cela dans la bibliothèque que j'utilise pour générer les fichiers svg. Et cela aurait du sens pour moi si je pouvais remplacer cela par html. Donc, fondamentalement, je me demande s'il existe une autre solution que de changer les fichiers svg.
Zitrax

Réponses:

161

Pour ce faire, vous pouvez ajouter les attributs «preserveAspectRatio» et «viewBox» à la <svg>balise.

Ouvrez le fichier .svg dans un éditeur et recherchez la <svg>balise. dans cette balise, ajoutez les attributs suivants:

preserveAspectRatio="xMinYMin meet"
viewBox="0 0 {width} {height}"

Remplacez {width} et {height} par des valeurs par défaut pour la viewBox. J'ai utilisé les valeurs des attributs "width" et "height" de la balise SVG et cela semblait fonctionner.

Enregistrez le SVG et il devrait maintenant être mis à l'échelle comme prévu.

J'ai trouvé cette information ici:

https://blueprints.launchpad.net/inkscape/+spec/allow-browser-resizing

Jim Keller
la source
2
#protip tout ce dont vous avez besoin pour l'ajouter this preserveAspectRatio = "xMinYMin meet"
samccone
4
@samccone: Il semble que ce preserveAspectRatio="xMinYMin meet"n'était pas assez pour moi. J'avais également besoin de fournir un viewBoxcomme mentionné dans la réponse. Pitié!
Frerich Raabe
1
Vous pouvez également le faire preserveAspectRatio="none"si vous souhaitez étirer le svg de manière arbitraire.
Matt Crinklaw-Vogt
5
Ne tombez pas dans le même problème que moi: "viewbox"! = "ViewBox" :)
Dr.Ü
De plus, j'ai dû définir les attributs de largeur et de hauteur réels 100%comme indiqué dans cette réponse .
ComFreek
35

Aucune des réponses données ici n'a fonctionné pour moi lorsque j'ai posé cette question en 2009. Comme j'avais à nouveau le même problème, j'ai remarqué que l'utilisation de la <img>balise et de la largeur avec un svg fonctionne bien.

<img width="400" src="image.svg">
Zitrax
la source
6
C'est tellement plus simple que les autres options! Au cas où quelqu'un serait curieux, voici un tableau des navigateurs pouvant gérer les SVG dans les balises <img> .
dimo414
5
Cela peut être le meilleur chemin s'il n'y a pas d'hyperliens dans SVG, sinon, img est insuffisant, et il faut toujours utiliser une alternative comme embed.
sdupton
12
Lorsque vous utilisez, <img>vous perdez toute interactivité avec les liens, javascript, etc.
gilly3
5
Mineur: l'élément img doit être auto-fermé, c'est-à-dire <img width="400" src="image.svg"/>.
Jan Aagaard
4
@JanAagaard: Il n'est pas nécessaire de fermer la balise img sauf en XHTML.
Peter V.Mørch
9

Vous pouvez accéder au svg intégré en utilisant JavaScript:

var svg = document.getElementsByTagName('object')[0].\
  contentDocument.getElementsByTagName('svg')[0];
svg.removeAttribute('width');
svg.removeAttribute('height');

Puisque votre svg a déjà une viewBox, Firefox doit redimensionner la largeur de 576 pixels dans la viewBox à la largeur de 400 pixels de votre document. D'autres svgs pourraient bénéficier d'une nouvelle viewBox dérivée de la largeur et de la hauteur annoncées (ce sont souvent les mêmes nombres). D'autres navigateurs peuvent bénéficier de différents ajustements svg.

Joeforker
la source
1
Cela m'a donné:Security error: attempted to read protected variable
Zitrax
1
Le svg est-il hébergé sur le même domaine que votre page Web?
joeforker
1
Ce n'était pas (localhost à externe), donc c'est probablement ça, mais j'ai fini par utiliser ma réponse ci-dessous car c'était plus simple.
Zitrax
9
<body>

<div>
<object type="image/svg+xml" data="img/logo.svg">
   <img src="img/logo.svg" alt="Browser fail" />
</object>
</div>

img / logo.svg ...

<svg
   width="100%" 
   height="100%"
   viewBox="0 0 640 80"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1" />

Cette configuration a fonctionné pour moi.

H Titan
la source
Cela fonctionne plutôt bien! La chose vraiment importante est de définir réellement viewBox="0 0 640 80". Apparemment, si cela n'est pas défini, vous ne pouvez pas vraiment le mettre à l'échelle ou laisser CSS le mettre à l'échelle pour vous en utilisant par exemple, width: 100%etc.
Igor
8

J'ai rencontré un problème où iOS sur un iPad ne redimensionnait pas correctement les images SVG dans une <object>balise.

Le style CSS augmenterait ou diminuerait la taille du <object>conteneur, mais l'image à l'intérieur ne serait pas modifiée (sur iPad, iOS 7).

Les images SVG ont été exportées à partir d'Adobe Illustrator, et la solution s'est avérée être de remplacer la largeur et la hauteur dans ceci:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="481.89px" height="294.843px" viewBox="0 0 481.89 294.843" 
enable-background="new 0 0 481.89 294.843"
xml:space="preserve">

avec:

width="100%" height="100%"

J'avais besoin d'utiliser la <object>balise car la <img>balise ne prend actuellement pas en charge l'incorporation d'images bitmap dans les SVG.

Andrew Swift
la source
C'est la bonne réponse, surtout si vous avez un SVG en ligne et n'utilisez pas la balise <img! Parfait!
Greg Ellis
5
  1. Définissez la zone de visualisation manquante et remplissez les valeurs de hauteur et de largeur des attributs de hauteur et de hauteur définis dans la balise svg

  2. Mettez ensuite l'image à l'échelle en réglant simplement la hauteur et la largeur sur les valeurs de pourcentage souhaitées . Bonne chance.

  3. Vous pouvez définir un rapport hauteur / largeur fixe avec preserveAspectRatio = "x200Y200 meet, mais ce n'est pas nécessaire

par exemple

 <svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="10%" 
   height="10%"
   preserveAspectRatio="x200Y200 meet"
   viewBox="0 0 350 350"
   id="svg2"
   version="1.1"
   inkscape:version="0.48.0 r9654"
   sodipodi:docname="namesvg.svg">
Lorenz Lo Sauer
la source
3

Utilisez simplement CSS pour que le navigateur redimensionne le SVG! Comme ceci: <object style="width:30%"> Voir http://www.vlado-do.de/svg_test/ pour plus de détails. Je l'ai juste essayé aussi localement avec un SVG dont la largeur et la hauteur sont données en "pt". Cela fonctionne bien dans Firefox.

Vlado
la source
1

Laisse voir. J'ai dû me rafraîchir la mémoire sur SVG, je ne l'ai pas beaucoup utilisé ces années-ci.

D'après ce que j'ai trouvé aujourd'hui, il semble que si vous spécifiez la dimension des objets sans unités, ils ont une taille fixe (en pixels, je pense). Apparemment, alors, il n'y a aucun moyen de les redimensionner lorsque vous redimensionnez le SVG (cela ne change que la taille de la fenêtre / du canevas).

Sauf, comme indiqué, vous spécifiez la taille du SVG en pourcentage OU spécifiez une viewBox (par exemple. ViewBox = "0 0 600 500").

Maintenant, si vous n'avez aucun moyen de changer le SVG exporté, vous n'avez pas de chance, je le crains. Quelle bibliothèque utilisez-vous?

PhiLho
la source
Le backend svg dans matplotlib. J'ai essayé des fonctions comme set_figwidth (val) mais cela ne semble pas fonctionner, mais je ne suis pas très familier avec cette bibliothèque, donc je regarde peut-être les mauvaises fonctions.
Zitrax
1

Voici une solution PHP utilisant QueryPath basée sur la réponse de Jim Keller.

Une fois QueryPath chargé, passez simplement votre script svg à la fonction.

function scaleableSVG($svg){
    $qp = qp($svg, 'svg');
    $width = $qp->attr('width');
    $height = $qp->attr('height');
    $qp->removeAttr('width')->removeAttr('height');                       
    $qp->attr('preserveAspectRatio', "xMinYMin meet");
    $qp->attr('viewBox', "0 0 $width $height");
    return $qp->html();
}
Dieter Gribnitz
la source