web-dev-qa-db-fra.com

Comment puis-je créer une échelle svg avec son conteneur parent?

Je souhaite disposer d'une échelle de contenu d'élément svg en ligne lorsque la taille n'est pas native. Bien sûr, je pourrais l'avoir dans un fichier séparé et le redimensionner comme ça.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

Cependant, je souhaite ajouter des styles supplémentaires au SVG via CSS. Par conséquent, la liaison d'un style externe n'est pas une option. Comment créer une échelle SVG intégrée?

180
bjb568

Pour spécifier les coordonnées dans l'image SVG indépendamment de la taille mise à l'échelle de l'image, utilisez l'attribut viewBox sur l'élément SVG pour définir le cadre de sélection de l'image dans le système de coordonnées, puis utilisez les attributs width et height. définir quelle est la largeur ou la hauteur par rapport à la page contenant.

Par exemple, si vous avez les éléments suivants:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Il sera rendu comme un triangle de 10px par 20px:

10x20 triangle

Maintenant, si vous définissez uniquement la largeur et la hauteur, cela modifiera la taille de l'élément SVG, mais pas l'échelle du triangle:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

10x20 triangle

Si vous définissez la zone de vue, elle est transformée en image de sorte que la zone donnée (dans le système de coordonnées de l'image) soit redimensionnée pour s'adapter à la largeur et à la hauteur données (dans le système de coordonnées de la page). Par exemple, pour que le triangle atteigne 100 pixels de 50 pixels:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 triangle

Si vous souhaitez le redimensionner à la largeur de la fenêtre HTML:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x150 triangle

Notez que par défaut, le rapport de format est préservé. Donc, si vous spécifiez que l'élément doit avoir une largeur de 100%, mais une hauteur de 50px, il ne sera en réalité redimensionné qu'à une hauteur de 50px (sauf si vous avez une fenêtre très étroite):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 triangle

Si vous souhaitez réellement l'étirer horizontalement, désactivez la conservation des proportions avec preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x50 triangle

(notez que, même si dans mes exemples, j'utilise une syntaxe qui fonctionne pour l'intégration HTML, pour inclure les exemples sous forme d'image dans StackOverflow, je les incorpore dans un autre fichier SVG, de sorte que je dois utiliser une syntaxe XML valide.)

365
Brian Campbell

Vous voudrez faire une transformation en tant que telle:

avec JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

Avec CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Enveloppez votre page SVG dans une étiquette de groupe en tant que telle et ciblez-la pour manipuler toute la page

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Note : L'échelle 1.0 est 100%

17
Gary Hayes

Après environ 48 heures de recherche, j'ai fini par le faire pour obtenir une mise à l'échelle proportionnelle:

REMARQUE: cet exemple est écrit avec React. Si vous ne l'utilisez pas, remplacez le contenu de l'affaire du chameau par des traits d'union (par exemple, changez backgroundColor en background-color et changez le style Object en String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Voici ce qui se passe dans l'exemple de code ci-dessus:

VIEWBOX

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, largeur et hauteur

ie: viewbox = "0 0 1000 1000"

Viewbox est un attribut important car il indique au SVG quelle taille dessiner et où. Si vous utilisiez CSS pour créer le format SVG 1000x1000 px mais que votre zone de visualisation était en 2000x2000, vous verriez le quart supérieur gauche de votre fichier SVG.

Les deux premiers chiffres, min-x et min-y, déterminent si le SVG doit être décalé dans la vue.

Mon SVG doit décaler vers le haut ou vers le bas ou gauche/droite

Examinez ceci: viewbox = "50 50 450 450"

Les deux premiers chiffres décaleront votre SVG de 50px à gauche et 50px vers le haut, et les deux autres chiffres correspondent à la taille de la zone de visualisation: 450x450 px. Si votre fichier SVG est 500x500 mais qu'il comporte un remplissage supplémentaire, vous pouvez manipuler ces chiffres pour le déplacer dans la "zone de visualisation".

Votre objectif à ce stade est de changer l’un de ces chiffres et de voir ce qui se passe.

Vous pouvez également omettre complètement la zone d'affichage, mais votre kilométrage variera en fonction de tous les autres paramètres que vous avez à la fois. D'après mon expérience, vous rencontrerez des problèmes de conservation des proportions, car la zone de visualisation vous aide à définir les proportions.

CONSERVER LES PROPORTIONS

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

D'après mes recherches, il existe de nombreux paramètres de rapport d'aspect différents, mais celui par défaut est appelé xMidYMid meet. Je le mets sur le mien pour me rappeler explicitement. xMidYMid meet la met à l'échelle proportionnellement en fonction du point médian X et Y. Cela signifie qu'elle reste centrée dans la zone de visualisation.

LARGEUR

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

Regardez mon exemple de code ci-dessus. Remarquez comment je règle uniquement la largeur, pas la hauteur. Je l'ai réglé à 100% pour qu'il remplisse le conteneur dans lequel il se trouve. C'est ce qui contribue probablement le plus à répondre à cette question.

Vous pouvez le remplacer par la valeur de pixel de votre choix, mais je vous conseillerais d'utiliser 100%, comme je l'ai fait, pour l'agrandir à la taille maximale, puis de le contrôler avec CSS via le conteneur parent. Je le recommande car vous obtiendrez un contrôle "correct". Vous pouvez utiliser des requêtes de médias et vous pouvez contrôler la taille sans JavaScript fou.

SCALING AVEC CSS

Regardez à nouveau mon exemple de code ci-dessus. Remarquez comment j'ai ces propriétés:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

Ceci est supplémentaire, mais cela montre comment permettre à l'utilisateur de redimensionner le SVG tout en conservant le rapport hauteur/largeur approprié. Étant donné que le SVG conserve ses propres proportions, il vous suffit de rendre la largeur redimensionnable sur le conteneur parent.

On laisse la hauteur seul et/ou on le règle sur auto, et on contrôle le redimensionnement avec la largeur. J'ai choisi la largeur car elle est souvent plus significative en raison de la réactivité des conceptions.

Voici une image de ces paramètres utilisés:

 enter image description here

Si vous lisez toutes les solutions de cette question et que vous êtes toujours confus ou que vous ne voyez pas très bien ce dont vous avez besoin, consultez ce lien ici. Je l'ai trouvé très utile:

https://css-tricks.com/scale-svg/

C'est un article volumineux, mais il décrit pratiquement tous les moyens de manipuler un SVG, avec ou sans CSS. Je vous recommande de le lire tout en buvant un café ou votre choix de liquides choisis.

15
agm1984

Il semble que ce CSS contienne le navigateur SVG dans Chrome jusqu'au point où le conteneur est plus grand que l'image:

div.inserted-svg-logo svg { max-width:100%; }

Semble également fonctionner dans FF + IE 11.

11
Kerry7777

Le réglage de l'attribut currentScale fonctionne dans IE (j'ai testé avec IE 11), mais pas dans Chrome.

0
Fabian Madurai