javascript - with - jquery svg
SVG con viewBox y ancho no está escalando la altura correctamente en IE (2)
Intento construir SVG en línea con atributos viewBox, pero sin atributos explícitos de ancho o alto. Estoy configurando el ancho del SVG al 100% usando CSS. Esto debería permitir que la escala SVG se ajuste a su contenedor de embalaje, manteniendo la relación de aspecto configurada por viewBox. ¡En Chrome y Firefox, esto funciona perfectamente!
Aquí hay un ejemplo de codepen mínimo de lo que estoy hablando: http://codepen.io/pcorey/pen/amkGl
HTML:
<div>
<svg viewBox="0 0 100 10">
<text x="1" y="9">hello</text>
</svg>
</div>
CSS:
div {
width: 400px;
}
svg {
width: 100%;
max-height: 100%;
outline: 1px solid tomato;
}
text {
font-size: 10px;
}
El viewBox es 100x10. El div externo está configurado para tener un ancho de 400px. Eso significa que la altura del SVG debe ser (y está en Chrome / Firefox) 40px. PERO, en IE 11, el ancho es SIEMPRE 150px (incluso cuando el ancho del div excede 1500px ...)
¿Hay una buena manera de arreglar esto en IE? ¿Por qué IE no puede manejar la altura desconocida correctamente? Puedo usar el truco de la " relación de aspecto intrínseco ", pero eso es súper feo, requiere otro elemento DOM, y requiere que recalcule el relleno cada vez que cambia el tamaño de la envoltura.
Para obtener más información sobre por qué quiero hacer esto, escribí una breve publicación en el blog al respecto: http://1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg-text/
¡Gracias por la ayuda!
Algunos navegadores (IE y safari) usarán un tamaño predeterminado para SVG si no colocas una altura y un ancho determinados. Eso que está pasando aquí. Tienes razón, la "ración de aspecto intrínseco" requiere otra Dom y CSS y será bueno si podemos superar esto.
Hay una solución para esto, puede calcular y poner la altura correcta en el fondo de relleno y esto le dará la "altura desconocida" correcta que desee. Puede ver una solución completa aquí: http://codepen.io/tomkarachristos/pen/GZPbgZ
<!--
xMidYMin: Align the midpoint X value of the element''s viewBox with the midpoint X value of the viewport.
slice : the entire viewport is covered by the viewBox and the viewBox is scaled down as much as possible,
height: if you dont set >= 1px some browsers will not render anything.
-->
<div>
<svg viewBox="0 0 100 10" preserveAspectRatio="xMidYMin slice"
width="100%" style="height: 1px;overflow: visible;
/*without js:padding-bottom:55%*/"><text>hello</text>
</svg>
<svg viewBox="0 0 100 10" preserveAspectRatio="xMidYMin slice"
width="100%" style="height: 1px;overflow: visible;"><text>Age</text>
</svg>
</div>
y javascript:
/*
Here we do the hack.
With the math type: percent * height/width
we are adjust the total height of an element who is depend in width using the padding-bottom.
You can put an inline padding-bottom if you want in html.
*/
$(function() {
$(''svg'').each(function() {
var svg = $(this);
var text = svg.find(''text'');
var bbox = text.get(0).getBBox();
//the hack
var calcString = "calc(100% * " + bbox.height/bbox.width + ")";
svg.css("padding-bottom",calcString);
svg.get(0).setAttribute(''viewBox'',
[bbox.x,
bbox.y,
bbox.width,
bbox.height].join('' ''));
});
});
Una solución que debería funcionar en todos los navegadores es agregar una imagen en blanco al contenedor en el que se encuentra su SVG, que tiene las mismas dimensiones que su SVG:
.wrap {
position: relative;
}
img {
width: 100%;
height: auto;
}
.viz {
position: absolute;
top: 0;
left: 0;
}
<div class="wrap">
<img src="img/blank.png" />
<div class="viz">
<svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 1000 600"></svg>
</div>
</div>
En este caso, su imagen debe tener dimensiones naturales de 1000px por 600px y ser transparente (o coincidir con el fondo de su contenedor .wrap). Esto se apropiará del tamaño del contenedor en el que se encuentra svg. La posición absoluta del elemento .viz le permitirá sentarse en la parte superior de la imagen, utilizando su altura para que no se corte nada.