Recientemente creé un patrón de pared de ladrillos como parte de mi #PatronesPequeños serie, un desafío en el que creo patrones o texturas de aspecto orgánico en SVG dentro de 560 bytes (o aproximadamente el tamaño de dos tweets). Para ajustarme a esta restricción, he realizado un viaje que me ha enseñado algunas formas radicales de optimizar los patrones SVG para que contengan la menor cantidad de código posible sin afectar la calidad general de la imagen.
Quiero guiarlo a través del proceso y mostrarle cómo podemos tomar un patrón SVG que comienza en 197 bytes hasta solo 44 bytes: ¡una enorme reducción del 77.7 %!
El patrón SVG
Esto es lo que se llama un patrón de ladrillos de "enlace en funcionamiento". Es el patrón de ladrillos más común que existe, y uno que seguramente hayas visto antes: cada fila de ladrillos está compensada por la mitad de la longitud de un ladrillo, creando un patrón escalonado repetitivo. El arreglo es bastante simple, haciendo SVG <pattern>
elemento un ajuste perfecto para reproducirlo en código.
El SVG <pattern>
elemento utiliza un objeto gráfico predefinido que se puede replicar (o "mosaico") a intervalos fijos a lo largo de los ejes horizontal y vertical. Esencialmente, definimos un patrón de mosaico rectangular y se repite para pintar el área de relleno.
Primero, establezcamos las dimensiones de un ladrillo y el espacio entre cada ladrillo. En aras de la simplicidad, usemos números limpios y redondos: un ancho de 100
y una altura de 30
para el ladrillo, y 10
para los espacios horizontales y verticales entre ellos.
A continuación, tenemos que identificar nuestro mosaico "base". Y por "mosaico" me refiero a mosaicos de patrones en lugar de mosaicos físicos, que no deben confundirse con los ladrillos. Usemos la parte resaltada de la imagen de arriba como nuestro mosaico de patrón: dos ladrillos enteros en la primera fila y uno entero intercalado entre dos medios ladrillos en la segunda fila. Observe cómo y dónde se incluyen los espacios, ya que deben incluirse en el mosaico de patrón repetido.
Cuando usas <pattern>
, tenemos que definir el patrón width
y height
, que corresponden al ancho y alto de la tesela base. Para obtener las dimensiones, necesitamos un poco de matemática:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
Muy bien, entonces nuestro mosaico de patrón es 220✕80
. También tenemos que configurar el patternUnits
atributo, donde el valor userSpaceOnUse
esencialmente significa píxeles. Finalmente, agregando un id
al patrón es necesario para que pueda ser referenciado cuando estemos pintando otro elemento con él.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Ahora que hemos establecido las dimensiones del mosaico, el desafío es crear el código para el mosaico de manera que represente el gráfico con la menor cantidad de bytes posible. Esto es con lo que esperamos terminar al final:
Marcado inicial (197 bytes)
El enfoque más simple y declarativo para recrear este patrón que me viene a la mente es dibujar cinco rectángulos. Por defecto, el fill
de un elemento SVG es negro y el stroke
es transparente Esto funciona bien para optimizar patrones SVG, ya que no tenemos que declararlos explícitamente en el código.
Cada línea del siguiente código define un rectángulo. los width
y height
siempre están configurados, y el x
y y
Las posiciones solo se establecen si un rectángulo está desplazado desde el 0
larga.
<rect width="100" height="30"/>
<rect x="110" width="100" height="30"/>
<rect y="40" width="45" height="30"/>
<rect x="55" y="40" width="100" height="30"/>
<rect x="165" y="40" width="55" height="30"/>
La fila superior del azulejo contenía dos ladrillos de ancho completo, el segundo ladrillo se coloca para x="110"
logrará una rápida implementación 10
píxeles de espacio antes del ladrillo. Del mismo modo hay 10
píxeles de espacio después, porque el ladrillo termina en 210
píxeles (110 + 100 = 210
) en el eje horizontal aunque el <pattern>
el ancho es 220
píxeles Necesitamos ese poco de espacio extra; de lo contrario, el segundo ladrillo se fusionaría con el primer ladrillo en el mosaico adyacente.
Los ladrillos de la segunda fila (inferior) están desplazados, por lo que la fila contiene dos medios ladrillos y un ladrillo completo. En este caso, queremos que los ladrillos de medio ancho se fusionen para que no haya espacios al principio o al final, lo que les permite fluir sin problemas con los ladrillos en mosaicos de patrón contiguos. Al compensar estos ladrillos, también tenemos que incluir medios huecos, por lo que el x
los valores son 55
y 165
, respectivamente.
Reutilización de elementos, (-43B, 154B en total)
Parece ineficiente definir cada ladrillo tan explícitamente. ¿No hay alguna forma de optimizar los patrones SVG reutilizando las formas?
No creo que sea muy conocido que SVG tiene un <use>
elemento. Puede hacer referencia a otro elemento con él y representar ese elemento referenciado donde sea <use>
se usa Esto ahorra bastantes bytes porque podemos omitir especificar los anchos y altos de cada ladrillo, excepto el primero.
Dicho esto, las <use>
viene con un pequeño precio. Es decir, tenemos que agregar un id
para el elemento que queremos reutilizar.
<rect id="b" width="100" height="30"/>
<use href="#b" x="110"/>
<use href="#b" x="-55" y="40"/>
<use href="#b" x="55" y="40"/>
<use href="#b" x="165" y="40"/>
El más corto id
posible es un carácter, así que elegí "b" para ladrillo. los <use>
elemento se puede colocar de manera similar a <rect>
, Con el x
y y
atributos como compensaciones. Dado que cada bloque tiene el ancho completo ahora que hemos cambiado a <use>
(recuerde, explícitamente reducimos a la mitad los ladrillos en la segunda fila del mosaico del patrón), tenemos que usar un negativo x
valor en la segunda fila, luego asegúrese de que el último ladrillo se desborde del mosaico para esa conexión perfecta entre los ladrillos. Sin embargo, están bien, porque cualquier cosa que quede fuera del mosaico del patrón se corta automáticamente.
¿Puedes identificar algunas cadenas repetitivas que se pueden escribir de manera más eficiente? Trabajemos en los siguientes.
Reescritura en la ruta (-54B, 100B en total)
<path>
es probablemente el elemento más poderoso en SVG. Puede dibujar casi cualquier forma con "comandos" en su d
atributo. Hay 20 comandos disponibles, pero solo necesitamos los más simples para los rectángulos.
Aquí es donde aterricé con eso:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
¡Lo sé, números y letras súper raros! todos tienen un significado, por supuesto. Esto es lo que está sucediendo en este caso específico:
M{x} {y}
: Se mueve a un punto basado en coordenadas.z
: Cierra el segmento actual.h{x}
: Dibuja una línea horizontal desde el punto actual, con la longitud dex
en la dirección definida por el signo dex
. Minúsculasx
indica una coordenada relativa.v{y}
: Dibuja una línea vertical desde el punto actual, con la longitud dey
en la dirección definida por el signo dey
. Minúsculasy
indica una coordenada relativa.
Este marcado es mucho más conciso que el anterior (los saltos de línea y los espacios en blanco de sangría son solo para facilitar la lectura). Y, bueno, hemos logrado reducir la mitad del tamaño inicial, llegando a 100 bytes. Aún así, algo me hace sentir que esto podría ser más pequeño...
Revisión de baldosas (-38B, 62B en total)
¿Nuestro mosaico de patrón no tiene partes repetitivas? Está claro que en la primera fila se repite todo un ladrillo, pero ¿y en la segunda fila? Es un poco más difícil de ver, pero si cortamos el ladrillo del medio por la mitad, se vuelve obvio.
Bueno, el ladrillo del medio no está exactamente cortado por la mitad. Hay una ligera compensación porque también tenemos que tener en cuenta la brecha. De todos modos, acabamos de encontrar un patrón de mosaico base más simple, ¡lo que significa menos bytes! Esto también significa que tenemos que reducir a la mitad el width
de nuestra <pattern>
elemento de 220 a 110.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
Ahora veamos cómo se dibuja el mosaico simplificado con <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
El tamaño se reduce a 62 bytes, ¡que ya es menos de un tercio del tamaño original! Pero, ¿por qué detenerse aquí cuando aún hay más que podemos hacer?
Comandos de ruta de acortamiento (-9B, 53B en total)
Vale la pena profundizar un poco más en el <path>
elemento porque proporciona más sugerencias para optimizar los patrones SVG. Un concepto erróneo que he tenido al trabajar con <path>
se trata de cómo el fill
el atributo funciona. Habiendo jugado mucho con MS Paint en mi infancia, he aprendido que cualquier forma que quiera rellenar con un color sólido tiene que estar cerrada, es decir, no tener puntos abiertos. De lo contrario, la pintura se saldrá de la forma y se derramará sobre todo.
En SVG, sin embargo, esto no es cierto. déjame citar la especificación en sí:
La operación de relleno rellena los subtrayectos abiertos realizando la operación de llenado como si se agregara un comando adicional de "cerrartrayecto" al trayecto para conectar el último punto del subtrayecto con el primer punto del subtrayecto.
Esto significa que podemos omitir los comandos de cerrar ruta (z
), porque los subtrayectos se consideran automáticamente cerrados cuando se rellenan.
Otra cosa útil que debe saber acerca de los comandos de ruta es que vienen en variaciones de mayúsculas y minúsculas. Las letras minúsculas significan que se utilizan coordenadas relativas; las letras mayúsculas significan que se usan coordenadas absolutas en su lugar.
Es un poco más complicado que eso con el H
y V
comandos porque solo incluyen una coordenada. Así es como describiría estos dos comandos:
H{x}
: Dibuja una línea horizontal desde el punto actual para coordinarx
.V{y}
: Dibuja una línea vertical desde el punto actual para coordinary
.
Cuando estamos dibujando el primer ladrillo en el patrón de mosaico, comenzamos desde el (0,0)
coordenadas Luego trazamos una línea horizontal para (100,0)
y una línea vertical para (100,30)
, y finalmente, dibuje una línea horizontal para (0,30)
. usamos el h-100
comando en la última línea, pero es el equivalente de H0
, que es de dos bytes en lugar de cinco. Podemos reemplazar dos ocurrencias similares y reducir el código de nuestro <path>
hasta esto:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
Se eliminaron otros 9 bytes: ¿cuánto más pequeños podemos reducir?
Puente (-5B, 48B en total)
Los comandos más largos que se interponen en nuestro camino hacia un patrón SVG totalmente optimizado son los comandos "mover a" que ocupan 4, 5 y 6 bytes, respectivamente. Una restricción que tenemos es que:
Un segmento de datos de ruta (si lo hay) debe comenzar con un comando "mover".
Pero eso está bien. El primero es el más corto de todos modos. Si intercambiamos las filas, podemos llegar a una definición de ruta en la que solo tenemos que movernos horizontal o verticalmente entre los ladrillos. ¿Qué pasaría si pudiéramos usar el h
y v
comandos allí en lugar de M
?
El diagrama anterior muestra cómo se pueden dibujar las tres formas con una sola ruta. Tenga en cuenta que estamos aprovechando el hecho de que el fill
operación cierra automáticamente la parte abierta entre (110,0)
y (0,0)
. Con esta reorganización, también movimos el espacio a la izquierda del ladrillo de ancho completo en la segunda fila. Así es como se ve el código, aún dividido en un bloque por línea:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
Seguramente, hemos encontrado la solución absoluta más pequeña ahora que estamos en 48 bytes, ¿verdad? Bien…
Recorte de dígitos (-4B, 44B en total)
Si puede ser un poco flexible con las dimensiones, hay otra pequeña forma en que podemos optimizar los patrones SVG. Hemos estado trabajando con un ancho de ladrillo de 100
píxeles, pero eso es tres bytes. cambiándolo a 90
significa un byte menos cada vez que necesitamos escribirlo. Del mismo modo, utilizamos una brecha de 10
píxeles, pero si lo cambiamos a 8
en cambio, guardamos un byte en cada una de esas ocurrencias.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
Por supuesto, esto también significa que tenemos que ajustar las dimensiones del patrón en consecuencia. Aquí está el código de patrón SVG optimizado final:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
La segunda línea en el fragmento anterior, sin contar las sangrías, es Bytes 44. Llegamos aquí desde 197 bytes en seis iteraciones. eso es un grueso 77.7% de reducción de tamaño!
Sin embargo, me pregunto... ¿es este realmente el tamaño más pequeño posible? ¿Hemos analizado todas las formas posibles de optimizar los patrones SVG?
Lo invito a probar y minimizar aún más este código, o incluso experimentar con métodos alternativos para optimizar patrones SVG. ¡Me encantaría ver si podemos encontrar el verdadero mínimo global con la sabiduría de la multitud!
Más sobre la creación y optimización de patrones SVG
Si está interesado en obtener más información sobre cómo crear y optimizar patrones SVG, lea mi artículo sobre crear patrones con filtros SVG. O, si desea ver una galería de más de 60 patrones, puede ver la Colección CodePen de PetitePatterns. Por último, le invitamos a ver mis tutoriales en youtube para ayudarlo a profundizar aún más en los patrones SVG.
Optimización de patrones SVG a su tamaño más pequeño publicado originalmente el Trucos CSS. Debieras obtener el boletín.
- "
- 10
- 100
- 77
- 9
- 98
- Nuestra Empresa
- Absoluto
- Mi Cuenta
- Adicionales
- Todos
- Permitir
- ya haya utilizado
- Otra
- enfoque
- Reservada
- artículo
- atributos
- Hoy Disponibles
- EJES
- Poco
- Negro
- Reto
- el cambio
- cerrado
- código
- Algunos
- conexión
- contiene
- contenido
- coordinar
- podría
- Creamos
- Current
- datos
- más profundo
- DE INSCRIPCIÓN
- termina
- se establece
- todo
- ejemplo
- Excepto
- experimento
- Finalmente
- Nombre
- cómodo
- de tus señales
- encontrado
- promover
- brecha
- conseguir
- Buscar
- es
- altura
- ayuda
- esta página
- Destacado
- Cómo
- HTTPS
- Identifique
- imagen
- incluir
- incluido
- IT
- sí mismo
- conocido
- fuga
- APRENDE:
- aprendido
- aprovechando
- línea
- pequeño
- miró
- amar
- HACE
- Realizar
- gestionado
- las matemáticas
- mente
- más,
- MEJOR DE TU
- movimiento
- MS
- número
- números
- compensar
- Bueno
- habiertos
- optimizado
- de otra manera
- Patrón de Costura
- los libros físicos
- punto
- posicionado
- posible
- poderoso
- bastante
- precio
- proporciona un
- calidad
- redondo
- correr
- Said
- sin costura
- Serie
- set
- formas
- similares
- sencillos
- SEIS
- Tamaño
- So
- a medida
- algo
- Espacio
- Spot
- comienzo
- comienza
- Soportado
- hablar
- A través de esta formación, el personal docente y administrativo de escuelas y universidades estará preparado para manejar los recursos disponibles que derivan de la diversidad cultural de sus estudiantes. Además, un mejor y mayor entendimiento sobre estas diferencias y similitudes culturales permitirá alcanzar los objetivos de inclusión previstos.
- parte superior
- transparente
- Tutoriales
- utilizan el
- propuesta de
- Ver
- W3
- Ver ahora
- bienvenido
- ¿
- dentro de
- sin
- Actividades:
- trabajando
- funciona
- valor
- Youtube