<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «imágenes»</title><description>Feed RSS de publicaciones etiquetadas con imágenes</description><link>https://javguerra.github.io/</link><item><title>Conocer el ancho y alto de una imagen con JavaScript antes de usarla en HTML</title><link>https://javguerra.github.io/blog/ancho-alto</link><guid isPermaLink="true">https://javguerra.github.io/blog/ancho-alto</guid><description>Ideas para evitar el «FOUC» de contenido cuando desconocemos las medidas de las imágenes</description><pubDate>Mon, 01 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/img.BrQ752_Z_Z2rMVCO.webp&quot; alt=&quot;Imagen&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando una web está cargando, se producen cambios en el diseño conocidos como &lt;em&gt;Flash Of Unestiled Content&lt;/em&gt; (FOUC) que son visualmente molestos para el usuario y le hacen perder su punto de referencia en la página. Las imágenes son uno de los principales causantes de estos cambios. Hasta que no son cargadas no se conoce su ancho y alto, por lo que es un buen criterio de diseño indicar el ancho y alto de la imagen en el HTML. Pero ¿qué ocurre cuando no conocemos las medidas de las imágenes que vamos a cargar? Pongamos como ejemplo una galería de fotos que tomamos mediante fetch. En esta entrada veremos como afrontarlo.&lt;/p&gt;
&lt;h1 id=&quot;el-código&quot;&gt;El código&lt;/h1&gt;
&lt;p&gt;Pongamos que tenemos un arreglo con un listado de URLs de fotos de adorables perritos que queremos mostrar en una galería de fotos. Este arreglo podemos definirlo u obtenerlo mediante &lt;code&gt;fetch&lt;/code&gt; desde una API u otro lugar. Cada imagen tiene un tamaño distinto, osea, unas medidas para los valores &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; diferentes. Nuestro objetivo es conocer estos valores antes de mostrar las fotos en la galería, para asignarles su ancho y alto correctos y evitar de esa manera el FUOC. De otra forma, a medida que se carguen las imágenes en la galería, estas irán abriéndose hueco para ocupar su espacio «empujando» el diseño.&lt;/p&gt;
&lt;p&gt;Con este código que seguramente encontré y adapté de StackOverflow o un sitio similar podemos hacerlo. Lo describo más abajo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; galeria&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;galeria&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; fotos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/Stretched_Dachshund.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/cattledog-australian/IMG_1211.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/dachshund-7.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; img&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onload&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({ ancho: img.width, alto: img.height });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Imagen no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.src &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlFoto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fotos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlFoto)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para usar este código, debemos tener algo como esto en el HTML:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;galeria&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos con JavaScript. Primero defino las variables con las que voy a trabajar. La referencia al elemento del DOM y el arreglo de URLs de fotos de perritos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; galeria&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;galeria&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; fotos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/Stretched_Dachshund.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/cattledog-australian/IMG_1211.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/dachshund-7.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;obtener-las-medidas&quot;&gt;Obtener las medidas&lt;/h2&gt;
&lt;p&gt;Aquí es donde se produce la magia. Veamos como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; img&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onload&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({ ancho: img.width, alto: img.height });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Imagen no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.src &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlFoto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función recibe como parámetro la URL de la imagen a calcular y envuelve una promesa que resolverá un objeto con las medidas &lt;code&gt;ancho&lt;/code&gt; y &lt;code&gt;alto&lt;/code&gt; o bien un error.&lt;/p&gt;
&lt;p&gt;Para hacerlo, instancio una nueva imagen con &lt;code&gt;const img = new Image();&lt;/code&gt; y declaro dos eventos asociados a &lt;code&gt;img&lt;/code&gt;, un evento que se disparará cuando se cargue la imagen en &lt;code&gt;img&lt;/code&gt; con &lt;code&gt;img.src = urlFoto;&lt;/code&gt; (&lt;code&gt;img.onload&lt;/code&gt;), y otro que se disparará si se produce un error al cargar la imagen (&lt;code&gt;img.onerror&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Es decir, cuando cargo la imagen con &lt;code&gt;img.src = urlFoto;&lt;/code&gt; pueden pasar dos cosas, que se lance el evento &lt;code&gt;onload&lt;/code&gt; si todo fue bien, o el evento &lt;code&gt;onerror&lt;/code&gt; si algo falló.&lt;/p&gt;
&lt;p&gt;Si todo fue bien, la imagen estará «cargada» en &lt;code&gt;img&lt;/code&gt;, y podemos obtener su ancho y alto. Mediante &lt;code&gt;resolve({ ancho: img.width, alto: img.height });&lt;/code&gt; devuelvo estos valores dentro de un objeto.&lt;/p&gt;
&lt;p&gt;Si algo falló, devuelvo un error con &lt;code&gt;reject(new Error(&apos;Imagen no encontrada.&apos;));&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;poner-las-imágenes-en-la-galería&quot;&gt;Poner las imágenes en la galería&lt;/h2&gt;
&lt;p&gt;Si tenemos la función &lt;code&gt;medidas()&lt;/code&gt; a la que podemos pasarle una URL, podemos recorrer el arreglo &lt;code&gt;fotos&lt;/code&gt; y poner en nuestro HTML cada foto con sus medidas exactas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fotos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlFoto)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mediante un &lt;code&gt;.forEach()&lt;/code&gt; recorro cada elemento del arreglo. De él obtengo dos valores, cada una de las URLs y el índice que ocupa en el arreglo cada URL.&lt;/p&gt;
&lt;p&gt;Llamo a la función &lt;code&gt;medidas()&lt;/code&gt; a la que le paso como parámetro la URL de una foto (&lt;code&gt;urlFoto&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;La función devuelve una promesa que debe ser resuelta. Así mediante &lt;code&gt;.then()&lt;/code&gt; obtengo el objeto &lt;code&gt;mide&lt;/code&gt; que contiene el ancho y el alto de la imagen que indiqué mediante la URL, que es el resultado del &lt;code&gt;resolve&lt;/code&gt; de la promesa. De otra forma, con &lt;code&gt;.catch()&lt;/code&gt; se captura el error resultante del &lt;code&gt;reject&lt;/code&gt; de la promesa.&lt;/p&gt;
&lt;p&gt;Si tenemos las medidas de ancho y alto de la imagen a mostrar, ya podemos conectarla al DOM con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto insertará en el elemento del DOM identificado con &lt;code&gt;#galeria&lt;/code&gt; una imagen (&lt;code&gt;img&lt;/code&gt;) con el enlace a la foto (&lt;code&gt;src&lt;/code&gt;), su ancho (&lt;code&gt;width&lt;/code&gt;), alto (&lt;code&gt;height&lt;/code&gt;) y una etiqueta &lt;code&gt;alt&lt;/code&gt; que «describe» (vagamente) la foto. Con &lt;code&gt;title&lt;/code&gt; podemos obtener la misma descripción al pasar con el ratón sobre la imagen.&lt;/p&gt;
&lt;p&gt;Por supuesto a la imagen podemos aplicarle las clases CSS que deseemos para, por ejemplo, que aparezca correctamente si usamos flexbox o similar para mostrar la galería…&lt;/p&gt;
&lt;h1 id=&quot;el-módulo-image-size&quot;&gt;El módulo image-size&lt;/h1&gt;
&lt;p&gt;Si realizamos el test &lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;Page Speed de Google&lt;/a&gt; a nuestra página y no indicamos el ancho y alto de las imágenes, esto nos penalizará en la puntuación de viabilidad en el apartado &lt;em&gt;&lt;code&gt;Cumulative Layout Shift&lt;/code&gt;&lt;/em&gt; o &lt;code&gt;CLS&lt;/code&gt;. El «movimiento inesperado de contenido» en español, mide la estabilidad visual cuantificando la frecuencia con la que los usuarios experimentan cambios de diseño inesperados. Así pues, cuanto más bajo sea el CLS, mejor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manz&lt;/strong&gt;, de &lt;a href=&quot;https://manz.dev/&quot;&gt;manz.dev&lt;/a&gt;, en su canal de &lt;a href=&quot;https://discord.manz.dev/&quot;&gt;Discord&lt;/a&gt;, cuenta lo siguiente:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;El navegador nunca va a saber las dimensiones (ancho y alto) de la imagen hasta descargar la imagen. Si la imagen es pesada va a tardar un rato y no es posible “reservar” ese espacio en la web porque no lo conoce. La única forma de evitar el CLS es indicarle tú previamente el tamaño para que no haya “salto”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mediante la opción propuesta, podemos resolver este problema si somos nosotros los que desarrollamos todo el código, pero si estamos trabajando con &lt;em&gt;frameworks&lt;/em&gt;, también hay soluciones disponibles. &lt;strong&gt;Manz&lt;/strong&gt; sigue diciendo:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hay una forma de evitarlo, si estás usando SSG (eleventy, astro, next, etc…) y es que en la fase de “compilación” le pases algún plugin que vaya mirando las imágenes y sacando sus dimensiones con node y añadiendo automáticamente el width y height. Yo, por ejemplo, uso este: &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Como indica &lt;strong&gt;Manz&lt;/strong&gt;, &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt; es una opción que permite obtener las dimensiones de una imagen y que podemos instalar con npm.&lt;/p&gt;
&lt;h1 id=&quot;un-truco&quot;&gt;Un truco&lt;/h1&gt;
&lt;p&gt;Em Twitter &lt;strong&gt;Manz&lt;/strong&gt; contaba:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Otras soluciones más simples e ingeniosas pueden ser establecer un alto máximo para el contenedor, de modo que no haga reflow de elementos inferiores, y los items del interior (galería) los vas haciendo aparecer a medida que se carguen con CSS/JS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Esta, sin duda, es otra opción.&lt;/p&gt;
&lt;h1 id=&quot;resumen&quot;&gt;Resumen&lt;/h1&gt;
&lt;p&gt;En Twitter, &lt;strong&gt;Manz&lt;/strong&gt; proponía también estas tres opciones para evitar el &lt;em&gt;reflow&lt;/em&gt; que podemos tomar a modo de resumen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Establecer siempre el width y height (tedioso)&lt;/li&gt;
&lt;li&gt;Usar aspect-ratio de CSS (&lt;a href=&quot;https://caniuse.com/mdn-css_properties_aspect-ratio&quot;&gt;https://caniuse.com/mdn-css_properties_aspect-ratio&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Automatizar con alguna herramienta de preprocesado. Yo en 11ty uso image-size o soluciones parecidas&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Ejemplo de uso de la solución propuesta: &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/17-fetch.html&quot;&gt;Galería de perritos&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Módulo &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;Page Speed de Google&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itdo.com/blog/que-es-el-cumulative-layout-shift-cls/&quot;&gt;¿Qué es el Cumulative Layout Shift (CLS)?&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Twitter de @Manz: &lt;a href=&quot;https://twitter.com/Manz/status/1527681719964512256&quot;&gt;¿Qué es «FUOC»?&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Web de @Manz: &lt;a href=&quot;https://manz.dev/&quot;&gt;manz.dev&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/img.BrQ752_Z_Z2rMVCO.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>imágenes</category><author>JavGuerra</author></item><item><title>Cliparts</title><link>https://javguerra.github.io/blog/cliparts</link><guid isPermaLink="true">https://javguerra.github.io/blog/cliparts</guid><description>Colaboraciones de arte libre</description><pubDate>Sat, 13 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/pajarita.B-3AlwvO_ZOqjgl.webp&quot; alt=&quot;Pajarita de papel&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#clipart&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;, &lt;em&gt;#inkscape&lt;/em&gt;, &lt;em&gt;#pro-bono&lt;/em&gt;, &lt;em&gt;#diseño&lt;/em&gt;, &lt;em&gt;#arte&lt;/em&gt;, &lt;em&gt;#svg&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Hace tiempo creé una serie de cliparts básicos elaborados con &lt;a href=&quot;https://inkscape.org/es/&quot;&gt;Inkscape&lt;/a&gt; que subí a la plataforma &lt;a href=&quot;https://openclipart.org/&quot;&gt;OpenClipArt.org&lt;/a&gt; Aquí puedes acceder a estos recursos.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Cliparts&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/cliparts.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://openclipart.org/search/?query=badaman&quot;&gt;&lt;button&gt;Ir a galería de ClipArts&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Algunos diseños los puedes pedir en &lt;a href=&quot;https://www.redbubble.com/es/people/javguerra/shop&quot;&gt;RedBubble&lt;/a&gt;.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/pajarita.B-3AlwvO_ZOqjgl.webp"/><category>clipart</category><category>imágenes</category><category>inkscape</category><category>pro-bono</category><category>diseño</category><category>arte</category><category>svg</category><author>JavGuerra</author></item><item><title>Generar enlaces dinámicos de imágenes almacenadas en MongoDB</title><link>https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</link><guid isPermaLink="true">https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</guid><description>Conseguir que nuestros datos no dependan de una ubicación estática</description><pubDate>Sun, 06 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp&quot; alt=&quot;Enlaces dinámicos&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las bases de datos a menudo contienen referencias a recursos que no son almacenados en su misma estructura. Un claro ejemplo de ello son las fotografías o imágenes que acompañan a los productos de un catálogo. En tal caso, guardar la información es sencillo, es suficiente con almacenar la ruta completa al recurso en un campo de tipo &lt;em&gt;String&lt;/em&gt;, pero, ¿que ocurre si, presumiblemente, nuestros datos van a cambiar de ubicación, o van a correr en distintas instancias o en diferentes hospedajes? En ese caso, lo recomendable es almacenar la información del nombre del recurso en la BBDD, y entonces tendremos dos alternativas para generar el enlace completo: modificar los datos de la BBDD mediante un &lt;em&gt;script&lt;/em&gt; para que la url al recurso sea la adecuada cada vez que cambiamos de ubicación los datos, o bien generar la ruta al recurso de forma dinámica, al vuelo, cuando se realizan las consultas. Vamos a ver aquí la segunda.&lt;/p&gt;
&lt;h1 id=&quot;el-ejemplo&quot;&gt;El ejemplo&lt;/h1&gt;
&lt;p&gt;Partimos de la siguiente premisa. En las variables globales del sistema tenemos almacenadas la ruta y el puerto del servidor donde están ubicadas las imágenes, que es la información susceptible de cambiar de lugar. Tal vez estos datos estén disponibles mediante &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot;&gt;dotenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tomemos como referencia el ejemplo de la &lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;entrada anterior&lt;/a&gt;. Dos colecciones relacionadas, &lt;code&gt;libros&lt;/code&gt; y &lt;code&gt;autores&lt;/code&gt;, y en las que queremos incluir un dato en cada documento de la colección libros con la foto de portada del libro, y un dato con la foto del autor en cada documento de la colección autores. Algo como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;libro&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    portada&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;don-quijote.png&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    foto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;cervantes.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;obviamente, tanto la colección libros como la conección autores tendrán otros datos, no sólo la portada o la foto.&lt;/p&gt;
&lt;h1 id=&quot;la-ruta&quot;&gt;La ruta&lt;/h1&gt;
&lt;p&gt;Para poder acceder a la portada del libro, necesitamos completar la ruta a la imagen. En este ejemplo usaremos el dominio &lt;code&gt;lalibreria2022.com&lt;/code&gt; al que se accede por el porto &lt;code&gt;80&lt;/code&gt;. Esta información la tenemos almacenada en un fichero &lt;code&gt;.env&lt;/code&gt; de nuestra aplicación de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST=&apos;https://lalibreria2022.com&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;PORT=80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y asumo que las portadas se almacenan en una carpeta llamada &lt;code&gt;portadas&lt;/code&gt;, y las fotos en otra llamada &lt;code&gt;fotos&lt;/code&gt;.
De esta forma, para acceder a la imagen &lt;code&gt;don-quijote.png&lt;/code&gt; debemos completar la siguiente ruta:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST + &apos;:&apos; + PORT + &apos;/&apos; + &apos;portadas&apos; + &apos;/&apos; + &apos;don-quijote.png&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y obtendríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/portadas/don-quijote.png&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;alterando-los-resultados&quot;&gt;Alterando los resultados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo las búsquedas de información sobre la BBDD, esta nos devolverá, como ya sabemos, el nombre del recurso (‘don-quijote.png’), pero queremos que la BBDD devuelva dinámicamente la ruta antes mencionada. Para ello hay que recorrer el resultado obtenido y hacer cambios sobre los datos. Un &lt;code&gt;forEach()&lt;/code&gt; es suficiente.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tras cada búsqueda, aplicando esta función al resultado, recorro todos los documentos de la colección (&lt;code&gt;datos&lt;/code&gt;) y cambio el valor del dato &lt;code&gt;portada&lt;/code&gt; en cada documento.&lt;/p&gt;
&lt;h1 id=&quot;también-con-resultados-agregados&quot;&gt;También con resultados agregados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo consultas agregadas, el proceso es similar. En una consulta donde obtenemos los libros y las referencias a sus respectivos autores, debemos repetir el proceso también para el dato &lt;code&gt;foto&lt;/code&gt; de la colección &lt;code&gt;autores&lt;/code&gt;, pero hay que tener en cuenta lo siguiente:&lt;/p&gt;
&lt;p&gt;{: .box-note}
&lt;strong&gt;Nota:&lt;/strong&gt; Cuando recorremos una colección agregada lo hacemos sobre una colección y sobre referencias a otra colección, es decir, si hay varios libros de un mismo autor, aunque los datos del autor se muestren en varios libros agregados, solo están almacenados una vez.&lt;/p&gt;
&lt;p&gt;Esto tiene importancia porque, al realizar el cambio de la ruta de la foto del autor, estaríamos cambiándola tantas veces como libros existan, y generando entonces una url errónea con rutas repetidas. Si tenemos dos libros de Cervantes, la ruta a la foto podría verse así:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/fotos/https://lalibreria2022.com:80/fotos/cervantes.jpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para evitar esto, debemos implementar el siguiente código, en el que se incluyen ambos casos, el de la portada del libro y el de la foto del autor:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elemento.autor.ref.foto.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url)) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;             elemento.autor.ref.foto &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;fotos/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.autor.ref.foto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con el condicional (&lt;code&gt;if&lt;/code&gt;) me aseguro de que la foto no contiene ya la ruta completa, y si no es así, la completa.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;Usando populate con paginate y filtrando los resultados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mongodb</category><category>imágenes</category><author>JavGuerra</author></item><item><title>Logotipos</title><link>https://javguerra.github.io/blog/logos</link><guid isPermaLink="true">https://javguerra.github.io/blog/logos</guid><description>Donaciones realizadas</description><pubDate>Sun, 14 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/monograma_jg.D85Slumc_jqG57.webp&quot; alt=&quot;Logo&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#imágenes&lt;/em&gt;, &lt;em&gt;#diseño&lt;/em&gt;, &lt;em&gt;#inkscape&lt;/em&gt;, &lt;em&gt;#pro-bono&lt;/em&gt;, &lt;em&gt;#arte&lt;/em&gt;, &lt;em&gt;#svg&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En ocasiones realizo logotipos e imagen corporativa para entidades sin ánimo de lucro con las que me relaciono. En esta entrada muestro una pequeña galería de esos trabajos elaborados con &lt;a href=&quot;https://inkscape.org/es/&quot;&gt;Inkscape&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Esta entrada se actualizará cuando se produzcan novedades.&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;galería&quot;&gt;Galería&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left&quot;&gt;&lt;/th&gt;
&lt;th style=&quot;text-align: left&quot;&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/alapsa_logo.jpg&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://es-la.facebook.com/ALAPSAVenezuela/&quot;&gt;Alapsa Venezuela&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/bienestar-logo.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://psicologiaparatusalud.wordpress.com/acerca-de/&quot;&gt;BienEstar psicológico&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/elhogardealba.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://es-es.facebook.com/elhogardealba2015/&quot;&gt;El hogar de Alba&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/logo-fevepof-color.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://www.instagram.com/fevepof/&quot;&gt;FEVEPOF&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/tortugafeliz-final.jpg&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://conectivaorg.wordpress.com/about/miembros/mei/&quot;&gt;Madurez Escolar Integral&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/marfan-venezuela.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://conectivaorg.wordpress.com/about/miembros/marfan-venezuela/&quot;&gt;Marfan Venezuela&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/mml-logo.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://mundomarfan.org&quot;&gt;Mundo Marfan Latino&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/monograma_jg.jpg&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; Monograma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/interaccion-y-perspectiva.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://produccioncientificaluz.org/index.php/interaccion/issue/archive&quot;&gt;Interacción y perspectiva&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/top_fb.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://conectiva.lat&quot;&gt;Conectiva&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/qlis25.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://sinclairql.es/&quot;&gt;QL is 25&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Logo&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/logos/4ql.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt; &lt;a href=&quot;https://sinclairqles.wordpress.com/2024/01/17/recursos-40-aniversario-del-ql/&quot;&gt;Recursos 40 aniversario del QL&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/monograma_jg.D85Slumc_jqG57.webp"/><category>imágenes</category><category>diseño</category><category>inkscape</category><category>pro-bono</category><category>arte</category><category>svg</category><author>JavGuerra</author></item></channel></rss>