SVG responsive?

Iniciado por @XSStringManolo, 23 Agosto 2019, 03:36 AM

0 Miembros y 1 Visitante están viendo este tema.

@XSStringManolo

Ando aprendiendo SVG y me encuentro haciendo una toolbar. Al hacer zoom, y dependiendo de la configuración del cliente el tamaño varía. Asique por ejemplo si se hace mucho zoom o la resolución de la pantalla es muy pequeña o muy grande va a cambiar el tamaño de la toolbar hasta el punto de que no se vea otra cosa en pantalla.

Lo que quiero es fijar el tamaño para que sea el mismo independientemente de la resolución. Podría setear el tamaño usando viewport y ajustar el tamaño trás hacer zoom a la inversa de la escala para redibujar la toolbar cada vez que se haga zoom, pero me parece una burrada de operaciones y hay que redibujar la toolbar tras cada zoom. En android es horrible como funciona porque no se redibujan los gráficos hasta que sueltas la pantalla y se ve como la toolbar desaparece un cacho hasta que le dejas redibujarse. Es una tontería pero queda muy feo. SVG no se redimensiona como un elemento HTML a pesar de poder manejarlo como tal.

Sabeis como se podría hacer:
-Que la imagen se adapte a la resolución en todo momento. (Importante para que se adapte cuando se gire la pantalla en Android)
-Que siempre ocupe lo mismo ante zooms. (Qué permaneza fija sin aumentar de tamaño)

A ver si me podeis hechar una mano que no consigo hacerlo.

El código:
Código (xml) [Seleccionar]
<div class = "RectangulosFijos">
<svg style ="display: block" width="100%" height="40">

<rect width="100%" height="42" style="fill:rgb(0,0,0);stroke-width:2;stroke:rgb(0,0,0)" id="Rectangulo1"
onclick="MatrizRectánguloCirculo();"/>
</svg>
</div>

<style>
.RectangulosFijos{
position: fixed;
left: 0;
right: 0;
bottom: 0;
}
</style>

EdePC

Saludos,

Citar-Que la imagen se adapte a la resolución en todo momento. (Importante para que se adapte cuando se gire la pantalla en Android)

- Esto no lo comprendo bien, los SVG por naturaleza son Responsive, mantienen su Aspect Ratio y ocupan todo lo que pueden de su contenedor pudiendo desbordarse.


Citar-Que siempre ocupe lo mismo ante zooms. (Qué permaneza fija sin aumentar de tamaño)

- Los SVG siempre ocupan lo mismo sin importar el Zoom, a no ser que modifiques los estilos de su contenedor.


- Me parece que quieres una barra de botones o algo así, para esto mejor usar flexbox y/o grid, ya que los contenidos de estos son bastante fluidos y se adaptan dinámicamente a su contenedor. Un SVG en contra no puede deformarse o perder su Aspec Ratio, aunque existe la opción, no suele ser buena idea deformar, estirar, aplastar un SVG salvo que sea el efecto requerido.

- Quizá si ejemplificas algo más ...

- Tienes una forma poco ortodoxa de hacer SVG XD, yo preferiría:

Código (xml) [Seleccionar]
<div class="RectangulosFijos">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 40">
    <rect x="0" y="0" width="100" height="40" fill="yellow" stroke="red" stroke-width="2" />
  </svg>
</div>
<style>
  body {
    margin: 0;
  }
  .RectangulosFijos {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
  }
</style>

@XSStringManolo

#2
Disculpa, me cuesta explicarlo con palabras.

Quiero por ejemplo el teclado en pantalla del android dibujado con SVG. Yo ahora le doy zoom a la pantalla y veo todo más grande, pero el teclado no se mueve, siempre va a estar estático haga lo que haga en la página. Eso es lo que quiero.

Si le pongo un tamaño fijo, pasa eso con SVG. Pero si le doy zoom, el "teclado" aumenta de tamaño, por lo que me tapa la pantalla y no puedo leer este texto.

Por otro lado, si pongo un tamaño fijo, por ejemplo 40px. Consigo ese efecto. Pero si lo veo en Pc resolución alta se ve super pequeño, y si lo veo en un android con 320x128 de resolución solo veo el "teclaod encima de la página.


A ver si con ese ejemplo me expliqué mejor. Puse el SVG como banner de ejemplo en el segundo link de mi firma. Fíjate que si le das mucho zoom, se tapa la web. (Pincha el svg para cambiarle el color, que está todo negro).

Y si cambias de resolución también pasa lo mismo. Cómo lo puedo fixear? Alguna idea?

http://stringmanolo.byethost12.com

engel lex

creo que la solucion (no he probado) seria usarlo con position:fixed a width:100% pero creo que te tocaría igual usar js para pegarlo a un lugar de la pantalla
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

EdePC

- Mientras tu viewBox sea dinámico/automático también lo será la escalibidad del SVG. Especifica un viewBox y el SVG se mantendrá tal cual:

Citar      <div class="BannerFijadoAbajo">
        <svg viewBox="0 0 100 10">
          <rect width="100" height="10" style="fill:rgb(0,0,0);stroke-width:2;stroke:rgb(0,0,0)" id="Rectangulo2" onclick="CambiarColorRectangulo();"/>
        </svg>
      </div>
      <div class="BannerFijado">
        <svg viewBox="0 0 100 20">
          <g>
            <rect width="100" height="20" style="fill:rgb(0,0,0);stroke-width:2;stroke:rgb(0,0,0)" id="Rectangulo1" onclick="CambiarColorRectangulo();"/>

-- El viewBox especifica el Aspect-Ratio, sirve de máscara y sienta la base para dibujar los elementos del contenidos en el SVG, la medida es en Puntos como si fuera un plano cartesiano. El SVG se adaptará lo más posible a su contenedor manteniendo su aspect-ratio (sin deformarse, salvo que se indique lo contrario), es decir, siempre será width: 100%; height: auto;

- Con eso el SVG será siempre el mismo y no cambiará por más que se cambie el Zoom.

- Con respecto a las vistas horizontal y vertical, el SVG no puede ser el mismo ya que se tendría que deformar, lo mejor es usar un media-query para transformar el SVG o poner otro en su lugar, tal cual pasa con el teclado Android, no es el mismo cuando esta en modo Portrait (vertical) y modo Landspace (horizontal), al menos el mio no XD. A no ser que especifiques el permiso de preserveAspectRatio="none"

@XSStringManolo

Cita de: EdePC en 24 Agosto 2019, 16:57 PM
- Mientras tu viewBox sea dinámico/automático también lo será la escalibidad del SVG. Especifica un viewBox y el SVG se mantendrá tal cual:

-- El viewBox especifica el Aspect-Ratio, sirve de máscara y sienta la base para dibujar los elementos del contenidos en el SVG, la medida es en Puntos como si fuera un plano cartesiano. El SVG se adaptará lo más posible a su contenedor manteniendo su aspect-ratio (sin deformarse, salvo que se indique lo contrario), es decir, siempre será width: 100%; height: auto;

- Con eso el SVG será siempre el mismo y no cambiará por más que se cambie el Zoom.

- Con respecto a las vistas horizontal y vertical, el SVG no puede ser el mismo ya que se tendría que deformar, lo mejor es usar un media-query para transformar el SVG o poner otro en su lugar, tal cual pasa con el teclado Android, no es el mismo cuando esta en modo Portrait (vertical) y modo Landspace (horizontal), al menos el mio no XD. A no ser que especifiques el permiso de preserveAspectRatio="none"
Probé con el código que me muestras y se queda todo centrad en medio, con un tamapo enorme que no se ven ni la letras. Sigue teniendo el problema de que es distinto en cada resolución, entonces no sé para que me sirve?

Estuve mirando antes de hacer el post y había que manejar matrices y el sistema de coordenadas de viewbox me parece absurdamente complejo. Cuando por ejemplo superas el tamaño del viewbox los elementos se mueven hacia la derecha en vez de agrandarse. Quise dibujar el texto con svg y me fue totlmente imposible dibujar una M. Asique al final use la etiqueta para el texto por ese motivo con el objetivo de crear una ttf.
Puse una de prueba en la carpeta del host y no me la carga.

Vaya rollazo xD.

Buscaré ejemplos ya hechos para ver como lo manejan, porque me da a mi que esto es bastante complejo.

MinusFour

Yo creo que no estás considerando el contenedor del SVG. Cuando tu le dices al contenedor de SVG que vaya al 100% del ancho o del alto, le estás diciendo que trabaje con las dimensiones del padre. Si el padre escala, el SVG escala.

Lo que tu quieres hacer creo que tiene más sentido trabajar con vh o vw que con las unidades relativas al contenedor padre.

@XSStringManolo

Creo que eso no me lo soluciona Minusfour, porque entonces al viewport le tengo que poner tamaño y estoy en las mismas no? Ya que si se lo pongo fijo al cambiar de resolución se ve distinto.

Mira el banner de este sitio que se activa al bajar el documento. Es eso exactamente lo que busco. Voy a mirar el código a ver si consigo entender como está hecho.

https://davidwalsh.name/building-animated-svg-banners

EdePC

- Pero ese banner no es SVG, ni se ajusta a lo que has pedido al principio, si hago zoom se amplia y reduce también :xD

- Me parece que no estás poniendo la etiqueta meta viewport para que funcione correctamente en dispositivos móviles. Cuando llega a casa lo pruebo en un móvil y hago las capturas ...

MinusFour

#9
Es algo díficil de demostrar como funciona vh y zoom en linea, porque la mayoría de los sitios usan frames de alguna forma u otra. Cuando tu haces zoom con el navegador, el viewport de tu navegador no cambia. Sigue siendo el mismo. El navegador no escala unidades relativas. 50% de un contenedor sigue siendo 50% cuando haces zoom.

Si tu SVG usa unidades absolutas si las escala. Es decir, si tienes un SVG con 500px de alto o 500px de ancho, el navegador escala esas unidades.

Edit:
Mira este es un ejemplo que saque de Mozilla:

Código (html5) [Seleccionar]

<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect -->
<html>
<head>
<style>
html,body { margin: 0px; }
svg { /*max-width: 50vh;*/ height: 50vh;}
</style>
</head>
<body>
<div>
<svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Simple rectangle -->
  <rect width="100" height="100" />
  <!-- Rounded corner rectangle -->
  <rect x="120" width="100" height="100" rx="15" />
</svg>
</div>
</body>
</html>


Lo único que hice fue darle un alto de 50vh, puedes hacerle zoom y no le pasa nada al contenedor (esto sin frames). Puedes hacer lo mismo con el % siempre y cuando estés pasando el tamaño del viewport desde la etiqueta HTML (pero para que hacer eso, si puedes usar las unidades de viewport).