¿Cómo escalo un SVG obstinado incrustado con la etiqueta <object>?

114

Tengo algunos archivos SVG que especifican widthy heightasí viewbox:

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

pero ¿cómo mostrarlos en el navegador a un tamaño que yo decida? Los quiero más pequeños y lo he probado:

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

pero luego obtengo barras de desplazamiento visibles.

Funciona si cambio los archivos SVG para configurar widthy heighten su 100%lugar, pero quiero decidir el tamaño en el HTML independientemente de los tamaños que se utilicen en el archivo SVG. Es posible ?

Zitrax
fuente
Estoy confundido, ¿la última oración se lee como la solución que estás buscando? Establecer el ancho / alto de SVG en 100% / 100% deja en manos del HTML definir el área para dibujarlo.
marca el
3
El problema es que no he encontrado forma de cambiar esto en la biblioteca que utilizo para generar los archivos svg. Y tendría sentido para mí si pudiera anular esto desde html. Básicamente, me pregunto si hay otra solución que cambiar los archivos svg.
Zitrax

Respuestas:

161

Puede agregar los atributos "preserveAspectRatio" y "viewBox" a la <svg>etiqueta para lograr esto.

Abra el archivo .svg en un editor y busque la <svg>etiqueta. en esa etiqueta, agregue los siguientes atributos:

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

Reemplaza {ancho} y {alto} con algunos valores predeterminados para viewBox. Utilicé los valores de los atributos "ancho" y "alto" de la etiqueta SVG y pareció funcionar.

Guarde el SVG y ahora debería escalar como se esperaba.

Encontré esta información aquí:

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

Jim Keller
fuente
2
#protip todo lo que necesitas para agregar este preserveAspectRatio = "xMinYMin meet"
samccone
4
@samccone: Parece que eso preserveAspectRatio="xMinYMin meet"no fue suficiente para mí. También necesitaba proporcionar un viewBoxcomo se menciona en la respuesta. ¡Lástima!
Frerich Raabe
1
También puede hacerlo preserveAspectRatio="none"si desea estirar el svg de formas arbitrarias.
Matt Crinklaw-Vogt
5
No caiga en el mismo problema que yo: "viewbox"! = "ViewBox" :)
Dr.Ü
Además, tuve que establecer los atributos de ancho y alto reales 100%como se indica en esta respuesta .
ComFreek
35

Ninguna de las respuestas dadas aquí funcionó para mí cuando pregunté esto en 2009. Como ahora tenía el mismo problema nuevamente, noté que usar la <img>etiqueta y el ancho junto con un svg funciona bien.

<img width="400" src="image.svg">
Zitrax
fuente
6
¡Esto es mucho más simple que las otras opciones! En caso de que alguien tenga curiosidad, aquí hay una tabla de los navegadores que pueden manejar SVG en etiquetas <img> .
dimo414
5
Esta puede ser la mejor ruta si no hay hipervínculos en SVG; de lo contrario, img es insuficiente y aún se debe usar una alternativa como incrustar.
sdupton
12
Cuando se utiliza <img>se pierde toda la interactividad con los enlaces, Javascript, etc
gilly3
5
Menor: el elemento img debe cerrarse automáticamente, es decir <img width="400" src="image.svg"/>.
Jan Aagaard
4
@JanAagaard: No es necesario cerrar la etiqueta img excepto en XHTML.
Peter V. Mørch
9

Puede acceder al svg incrustado usando JavaScript:

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

Dado que su svg ya tiene un viewBox, Firefox debe escalar el ancho de 576 píxeles en el viewBox al ancho de 400 píxeles en su documento. Otros svgs podrían beneficiarse de un nuevo viewBox derivado del ancho y alto anunciado (estos suelen ser los mismos números). Otros navegadores pueden beneficiarse de diferentes ajustes de svg.

joeforker
fuente
1
Esto me dio:Security error: attempted to read protected variable
Zitrax
1
¿El svg está alojado en el mismo dominio que su página web?
joeforker
1
No era (localhost a externo), así que probablemente sea así, sin embargo, terminé usando mi respuesta a continuación, ya que era más 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" />

Esta configuración funcionó para mí.

H Titán
fuente
¡Esto realmente funciona bastante bien! Lo realmente importante es definir realmente viewBox="0 0 640 80". Aparentemente, si esto no está definido, realmente no puede escalarlo o dejar que CSS lo escale por usted usando, por ejemplo, width: 100%etc.
Igor
8

Encontré un problema en el que iOS en un iPad no cambiaba correctamente el tamaño de las imágenes SVG en una <object>etiqueta.

El estilo CSS aumentaría o disminuiría el tamaño del <object>contenedor, pero la imagen dentro de él no se modificaría (en iPad, iOS 7).

Las imágenes SVG se exportaron desde Adobe Illustrator, y la solución resultó reemplazar el ancho y el alto en esto:

<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">

con:

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

Necesitaba usar la <object>etiqueta porque <img>actualmente la etiqueta no admite la incrustación de imágenes de mapa de bits en SVG.

Andrew Swift
fuente
Esta es la respuesta correcta, especialmente si tiene SVG en línea y no usa la etiqueta <img. ¡Perfecto!
Greg Ellis
5
  1. Configure el cuadro de visualización que falta y complete los valores de altura y ancho de los atributos de altura y altura establecidos en la etiqueta svg

  2. Luego escale la imagen simplemente estableciendo la altura y el ancho en los valores porcentuales deseados . Buena suerte.

  3. Puede establecer una relación de aspecto fija con preserveAspectRatio = "x200Y200 meet, pero no es necesario

p.ej

 <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
fuente
3

¡Simplemente use CSS para hacer que el navegador cambie el tamaño del SVG! Así: <object style="width:30%"> consulte http://www.vlado-do.de/svg_test/ para obtener más detalles. También lo probé localmente con un SVG que tiene su ancho y alto en "pt". Funciona bien en Firefox.

Vlado
fuente
1

Vamos a ver. Tuve que refrescar mi memoria en SVG, no lo he usado mucho estos años.

Por lo que encontré hoy, parece que si especificas la dimensión de los objetos sin unidades, tienen un tamaño fijo (en píxeles, creo). Aparentemente, entonces, no hay forma de cambiar su tamaño cuando cambia el tamaño del SVG (solo cambia el tamaño de la ventana gráfica / lienzo).

A menos que, como se señaló, especifique el tamaño del SVG en porcentaje O especifique un viewBox (por ejemplo, viewBox = "0 0 600 500").

Ahora, si no tiene forma de cambiar el SVG exportado, me temo que no tiene suerte. ¿Qué biblioteca usas?

PhiLho
fuente
El backend svg en matplotlib. He probado funciones como set_figwidth (val) pero parece que no funciona, pero no estoy muy familiarizado con esta biblioteca, por lo que podría estar viendo las funciones incorrectas.
Zitrax
1

Aquí hay una solución PHP que usa QueryPath basada en la respuesta de Jim Keller.

Una vez que QueryPath esté cargado, simplemente pase su script svg a la función.

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
fuente