<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alfredo Moscoso</title>
    <description>The latest articles on Forem by Alfredo Moscoso (@jairdev).</description>
    <link>https://forem.com/jairdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F255767%2F1578ef54-fd42-492a-b1c9-cabbb288fb15.jpg</url>
      <title>Forem: Alfredo Moscoso</title>
      <link>https://forem.com/jairdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jairdev"/>
    <language>en</language>
    <item>
      <title>React Render props</title>
      <dc:creator>Alfredo Moscoso</dc:creator>
      <pubDate>Fri, 07 Oct 2022 19:32:37 +0000</pubDate>
      <link>https://forem.com/jairdev/react-render-props-1m7k</link>
      <guid>https://forem.com/jairdev/react-render-props-1m7k</guid>
      <description>&lt;h2&gt;
  
  
  ¿Que son las render props en React?
&lt;/h2&gt;

&lt;p&gt;Las render props son un técnica que nos permiten compartir código en React al hacer uso de un propiedad que tiene como valor una función.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Un componente con una &lt;code&gt;render prop&lt;/code&gt; recibe una función que retorna un elemento react.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Data render={(user) =&amp;gt; &amp;lt;UserData user={user} /&amp;gt;} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En React podríamos decir que hay varias maneras de compartir código entre componentes, siendo estos componentes los elementos principales de reutilización de código en React.&lt;/p&gt;

&lt;p&gt;También es cierto que no siempre tenemos claro como podríamos compartir estados, comportamientos, que un componente encapsula, con otros componentes que necesiten esos datos.&lt;/p&gt;




&lt;p&gt;Digamos que tenemos un componente que simplemente encapsula los datos de un usuario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function UserData() {
  const user = {
    name: "Alfredo",
    lastName: "Moscoso",
    rol: "Frontend Developer",
  };

  return (
    //user...
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora supongamos que queremos mostrar estos datos como una &lt;code&gt;table&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aquí nos preguntamos, ¿Como podríamos compartir esos datos con otros componentes?&lt;/p&gt;

&lt;p&gt;Creamos un componente que renderice un &lt;code&gt;table&lt;/code&gt; y acepte un &lt;code&gt;prop&lt;/code&gt; user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Table({ user }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;table&amp;gt;
        &amp;lt;thead&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Lastname&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Rol&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;{user.name}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{user.lastName}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{user.rol}&amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
      &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactorizamos nuestro componente &lt;code&gt;&amp;lt;UserData /&amp;gt;&lt;/code&gt; para que renderice el componente &lt;code&gt;&amp;lt;Table /&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function UserData() {
  const user = {
    name: "Alfredo",
    lastName: "Moscoso",
    rol: "Frontend Developer",
  };

  return (
    &amp;lt;Table user={user}/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pero ahora también queremos mostrar esos datos mediante un componente &lt;code&gt;&amp;lt;Card /&amp;gt;&lt;/code&gt; en otro lugar de nuestra App, entonces podríamos pasar esos datos a &lt;code&gt;&amp;lt;Card user={user} /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tendríamos que crear por ejemplo otro componente &lt;code&gt;UserDataCard&lt;/code&gt;, para mostrar una salida diferente o transmitir los datos desde un contexto global.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function UserDataCard() {
  const user = {
    name: "Alfredo",
    lastName: "Moscoso",
    rol: "Frontend Developer",
  };

  return (
    &amp;lt;Card user={user}/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto funciona pero el objetivo de encapsular datos, hacerlos portables y reutilizables no se ha logrado.&lt;/p&gt;




&lt;p&gt;En este caso podemos recurrir al uso de render props, ya que esta técnica nos permite encapsular y hacer portables datos o comportamientos que queramos compartir entre componentes.&lt;/p&gt;

&lt;p&gt;En el componente &lt;code&gt;&amp;lt;UserData /&amp;gt;&lt;/code&gt; encapsularíamos nuestros datos y le proporcionaríamos una función por medio de &lt;code&gt;props&lt;/code&gt; para que determine que renderizar de forma dinámica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function UserData({ render }) {
  const user = {
    name: "Alfredo",
    lastName: "Moscoso",
    rol: "Frontend Developer",
  };
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;User Data&amp;lt;/h1&amp;gt;
      //renderiza una salida dinámicamente 
      {render(user)}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En algún lugar de nuestra App donde necesitemos mostrar esos datos como un &lt;code&gt;table&lt;/code&gt; llamaríamos a nuestro componente de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;UserData render={(user) =&amp;gt; &amp;lt;Table user={user} /&amp;gt;} /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O si necesitamos renderizar una &lt;code&gt;&amp;lt;Card&amp;gt;&lt;/code&gt; ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;UserData render={(user) =&amp;gt; &amp;lt;Card user={user} /&amp;gt;} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como puedes ver, esta técnica hace a nuestros componentes muy portátiles y reutilizables.&lt;/p&gt;

&lt;p&gt;Recuerda que esta es otra técnica mas que podemos usar en React, y tal vez no se adapte a tus requerimientos al desarrollar una aplicación o una web, pero es importante conocer diferentes patrones que nos ayuden a decidir cual es el mejor para nuestro caso de uso.&lt;/p&gt;

&lt;p&gt;Tu feedback es de ayuda para mi 🙏&lt;/p&gt;

&lt;p&gt;Conectemos 😎&lt;br&gt;
&lt;a href="https://twitter.com/JairDevep"&gt;https://twitter.com/JairDevep&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/"&gt;https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Nos vemos pronto! 👊&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Funciones de flecha en JavaScript + this</title>
      <dc:creator>Alfredo Moscoso</dc:creator>
      <pubDate>Mon, 13 Jun 2022 21:54:22 +0000</pubDate>
      <link>https://forem.com/jairdev/funciones-de-flecha-en-javascript-this-480a</link>
      <guid>https://forem.com/jairdev/funciones-de-flecha-en-javascript-this-480a</guid>
      <description>&lt;p&gt;Las funciones de flecha en JavaScript nos brindan la posibilidad de escribir funciones sin utilizar la palabra clave &lt;code&gt;function&lt;/code&gt;, pero mas allá de la sintaxis, las funciones de flecha o arrow functions tienen algunas particularidades y diferencias de cuando creamos funciones de manera "tradicional".&lt;/p&gt;

&lt;h3&gt;
  
  
  Sintaxis
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Declaración de función
function sayHello() {
  console.log("Hi")
}

//Expresión de función
const sayHello = function() {
  console.log("Hi")
}

//Función de flecha
const sayHello = () =&amp;gt; console.log("Hi")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como mencioné al inicio de este artículo, las funciones de flecha nos permiten crear funciones de una manera mas compacta en algunos casos, ahora hablemos de sus diferencias y algunas limitaciones.&lt;/p&gt;




&lt;h3&gt;
  
  
  This y Funciones de flecha
&lt;/h3&gt;

&lt;p&gt;Una de las diferencias mas llamativas es cuando asociamos el concepto de &lt;code&gt;this&lt;/code&gt; en JavaScript con las funciones de flecha.&lt;/p&gt;

&lt;h4&gt;
  
  
  Como this determina su valor?.
&lt;/h4&gt;

&lt;p&gt;La palabra clave &lt;code&gt;this&lt;/code&gt; y su valor dependen del &lt;strong&gt;contexto de ejecución&lt;/strong&gt; o como se invoca determinada función o método en JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8jQG4YzM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saw45gak7ej3jqs9e3d6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8jQG4YzM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saw45gak7ej3jqs9e3d6.gif" alt="Image description" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aprendiendo este concepto (this keyword) yo también estaba confundido como la imagen mas arriba 😆, pero no te preocupes espero que con este artículo despejes tus dudas.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;En los navegadores el valor de &lt;code&gt;this&lt;/code&gt; ejecutándose en un contexto global es el objeto window.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;console.log(this === window) // true&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  En una función
&lt;/h3&gt;

&lt;p&gt;Cuando utilizamos &lt;code&gt;this&lt;/code&gt; dentro de una función, su valor depende del contexto de ejecución de la función.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function sayHello() {
  console.log(this)
}
sayHello() *contexto de ejecución global

// Window {...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  En un objeto declarado
&lt;/h3&gt;

&lt;p&gt;Al utilizar &lt;code&gt;this&lt;/code&gt; dentro de un método en un objeto declarado, el valor de &lt;code&gt;this&lt;/code&gt; será el del objeto en el que se está llamando el método.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj = {
  name: "Alfredo",
  getUserName: function () {
    console.log(this)
  }
}

nameObj.getUserName()

// {name: 'Alfredo', ...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo a continuación, el valor de this se determina de acuerdo a su referencia mas cercana.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj = {
  name: "Alfredo",
  nested : {
    lastName: "Moscoso",
    getUserName: function () {
      console.log(this);
    },
  }
};

nameObj.nested.getUserName()

//{lastName: 'Moscoso', ...}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos ver su valor depende del contexto de ejecución del método.&lt;/p&gt;




&lt;h3&gt;
  
  
  En una función constructora
&lt;/h3&gt;

&lt;p&gt;Si trabajamos con una función constructora y la palabra clave &lt;code&gt;new&lt;/code&gt; su valor está vinculado al nuevo objeto que se está creando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Car(model, year) {
  this.model = model;
  this.year = year;
}

const ford = new Car("Ford", "1970")
console.log(ford.year) // 1970

const chevrolet = new Car("Chevrolet", "1956")
console.log(chevrolet.year) // 1956
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  En los métodos call, apply y bind
&lt;/h3&gt;

&lt;p&gt;Con los métodos de funciones &lt;code&gt;call&lt;/code&gt; y &lt;code&gt;apply&lt;/code&gt; podemos enlazar el valor de &lt;code&gt;this&lt;/code&gt; dentro de una función a un objeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;call()&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

getUserName.call(nameObj, "Moscoso")

//Alfredo Moscoso

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;apply()&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

getUserName.apply(nameObj, ["Moscoso"])

//Alfredo Moscoso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;bind()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;En el método &lt;code&gt;bind&lt;/code&gt; también podemos enlazar un valor de &lt;code&gt;this&lt;/code&gt; con un objeto, la diferencia es que el método &lt;code&gt;bind&lt;/code&gt; crea una nueva función que podemos llamar luego.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

const user = getUserName.bind(nameObj, "Moscoso")
user()

//Alfredo Moscoso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Más información sobre estos métodos.&lt;br&gt;
&lt;a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Function/call"&gt;https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Function/call&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora que ya vimos algunos ejemplos y como &lt;code&gt;this&lt;/code&gt; modifica su valor, veamos como se comportan las funciones de flecha y la palabra clave &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  This en una función de flecha
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj = {
  name: "Alfredo",
  getUserName: () =&amp;gt; console.log(this)
}

nameObj.getUserName() // ???
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Cual crees será la salida del código ?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4AEaTc29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7bnwn4nrceoruketjj3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4AEaTc29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7bnwn4nrceoruketjj3.gif" alt="Image description" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;La salida de este código es la siguiente, el window object. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;// Window {...}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Esto ocurre porque las funciones de flecha no tienen un &lt;code&gt;this&lt;/code&gt; atado a ellas o no predeterminan &lt;code&gt;this&lt;/code&gt; al alcance de Window, estas se ejecutan en el alcance en que fueron creadas.&lt;/p&gt;

&lt;p&gt;En este ejemplo el método getUserName() está retornando una función de flecha, como estas funciones no tienen su propio &lt;code&gt;this&lt;/code&gt;, el valor de &lt;code&gt;this&lt;/code&gt; es el del ámbito adjunto, el del método getUserName() y como estamos utilizando una función "tradicional" en el método getUserName(), this tendrá el valor del objeto &lt;code&gt;nameObj&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nameObj = {
  name: "Alfredo",
  getUserName: function () {
    return () =&amp;gt; console.log(this)
  }
}
const inside = nameObj.getUserName()

inside() 

//{name: 'Alfredo', ..}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O con este ejemplo, donde la función de flecha del método &lt;code&gt;setInterval&lt;/code&gt; se está ejecutando en el contexto de la instancia count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function IncreaseCount(count) {
  this.count = count
  setInterval(() =&amp;gt; {
    console.log(this.count += 1)
  }, 1000);
}

const count = new IncreaseCount(30)

//31
//32
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A diferencia de este caso donde se utiliza una función "tradicional" dentro del método setInterval() y como esta se ejecuta en el ámbito global, la salida no es la esperada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function IncreaseCount(count) {
  this.count = count
  setInterval(function () {
    console.log(this.count)
  }, 1000);
}


const count = new IncreaseCount(30)

// undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Como te habrás dado cuenta las funciones de flecha no es solo una sintaxis mas corta sino que su comportamiento es diferente a una función tradicional.&lt;/p&gt;

&lt;p&gt;Algunas consideraciones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No utilices funciones de flecha en métodos de objeto.&lt;/li&gt;
&lt;li&gt;No utilices funciones de flecha como constructores. &lt;/li&gt;
&lt;li&gt;No utilices funciones de flecha con los métodos call, apply o bind.&lt;/li&gt;
&lt;li&gt;Las funciones de flecha no tienen una propiedad prototype.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero este post haya aclarado tus dudas sobre como funciona &lt;code&gt;this&lt;/code&gt; en JavaScript y las funciones de flecha.&lt;/p&gt;

&lt;p&gt;Tu feedback es de mucha ayuda para mi 🙏&lt;/p&gt;

&lt;p&gt;Conectemos 😎&lt;br&gt;
&lt;a href="https://twitter.com/JairDevep"&gt;https://twitter.com/JairDevep&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/"&gt;https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Nos vemos pronto! 👊&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Animación de máscaras CSS.</title>
      <dc:creator>Alfredo Moscoso</dc:creator>
      <pubDate>Tue, 07 Jun 2022 21:13:55 +0000</pubDate>
      <link>https://forem.com/jairdev/animacion-de-mascaras-css-15p2</link>
      <guid>https://forem.com/jairdev/animacion-de-mascaras-css-15p2</guid>
      <description>&lt;p&gt;Hoy aprenderemos a animar máscaras css, apoyándonos en la posición del cursor para crear un efecto único para tu próximo proyecto web.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgit711shkw0e6hssbkfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgit711shkw0e6hssbkfh.png" alt="Imagen de una mujer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo&lt;br&gt;
&lt;a href="https://css-mask-effect.netlify.app/" rel="noopener noreferrer"&gt;https://css-mask-effect.netlify.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github&lt;br&gt;
&lt;a href="https://github.com/JairDev/css-mask-effect" rel="noopener noreferrer"&gt;https://github.com/JairDev/css-mask-effect&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;El enmascaramiento en css, nos permite “cortar” (enmascarar ) un elemento, ya sea a través de una imagen, un svg o un degradado pudiendo establecer que parte serán o no visibles de ese elemento de acuerdo a la transparencia en la imagen, svg o degradado.&lt;/p&gt;

&lt;p&gt;Como podemos ver en este ejemplo, nuestra imagen que servirá de máscara es el logo de apple, es totalmente negra con un fondo transparente y nuestro elemento a enmascarar tiene un fondo de color rosa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k8tkbgc2t2slzslq6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k8tkbgc2t2slzslq6s.png" alt="tres imágenes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*La imagen se aplica como máscara al elemento rosa, lo ilustré de esta manera para ver como actúa el fondo transparente de la imagen, solo serían dos elementos, mas adelante lo veremos.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Máscara aplicada&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frio8cij0k1tayeutn7j9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frio8cij0k1tayeutn7j9.png" alt="imagen de manzana sobre imagen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La parte mas oscura de nuestra imagen, svg o degradado hacen visible el elemento mientras que la parte mas trasparente ocultan el elemento.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkbjg8h1f1y2wqwpn2s5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkbjg8h1f1y2wqwpn2s5.gif" alt="gif de asombro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/black-hill-9pkco7"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Propiedad css mask:
&lt;/h3&gt;

&lt;p&gt;La propiedad css mask es un shorthand para mask-image, mask-repeat, mask-position entre otras propiedades, &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/mask" rel="noopener noreferrer"&gt;https://developer.mozilla.org/es/docs/Web/CSS/mask&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.element {
  mask-image: url("image-link");
  mask-repeat: no-repeat;
  mask-position: center;
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Funciona parecido a la propiedad background de css, podemos establecer una imagen mediante una url, si queremos que se repita o no la máscara, de esta manera tenemos mas control sobre los efectos de nuestra máscara.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Ahora a ensuciarnos las manos ...&lt;/strong&gt; 😎&lt;/p&gt;

&lt;p&gt;Para nuestro efecto vamos a duplicar nuestro elemento &lt;code&gt;.hero&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffttqub0t4d7pnliqv00g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffttqub0t4d7pnliqv00g.png" alt="capas duplicadas"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container"&amp;gt;
 &amp;lt;div class="hero"&amp;gt;
  &amp;lt;div class="contain-name"&amp;gt;
    &amp;lt;h1&amp;gt;Hi, I am Kim,&amp;lt;/h1&amp;gt;
    &amp;lt;span&amp;gt;I am a&amp;lt;/span&amp;gt;
    &amp;lt;span&amp;gt;web developer.&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  ...
 &amp;lt;/div&amp;gt;

 &amp;lt;div class="hero copy" aria-hidden="true"&amp;gt;
  &amp;lt;div class="contain-name"&amp;gt;
    &amp;lt;p&amp;gt;Hi, I am Kim,&amp;lt;/p&amp;gt;
    &amp;lt;span&amp;gt;I am a&amp;lt;/span&amp;gt;
    &amp;lt;span class="span web-developer"&amp;gt;web developer.&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  ...
 &amp;lt;/div&amp;gt;
&amp;lt;/container

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para mejorar la accesibilidad de nuestro contenido, hemos establecido el elemento duplicado en &lt;code&gt;aria-hidden="true"&lt;/code&gt; para evitar que sea mencionado dos veces por lectores de pantalla.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enmascaramiento del elemento duplicado.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.hero.copy {
 --mask: radial-gradient(
    circle at 15% 50%,
    black 25%,
    transparent 0%
  );
  -webkit-mask: var(--mask);
  mask: var(--mask);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estilos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
.container {
  background: #18191c;
}

.hero {
  opacity: 0.6;
}

.hero.copy {
  background: #7f8189af;
  filter: brightness(1.5);
  opacity: 1;
}

.span.web-developer {
  color: #ff03a0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En el elemento &lt;code&gt;.container&lt;/code&gt; utilizamos un fondo oscuro y en nuestro elemento base &lt;code&gt;.hero&lt;/code&gt; establecemos una opacidad de 0.6 para dar una sensación de oscuridad.&lt;/p&gt;

&lt;p&gt;Para la máscara utilizaremos un radial gradient, estableciendo el circulo que vemos a continuación, el fondo será de un color grisáceo para dar el efecto de un foco de luz blanca, aumentaremos un poco el brillo y resaltaremos el texto web developer con un color intenso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F223cchv5b2n0kizgh6dp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F223cchv5b2n0kizgh6dp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como puedes ver, la máscara que es un circulo se está aplicando a nuestro elemento, vamos a difuminar un poco el circulo asignando un 4% al inicio del gradiente y un 25% al final.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.hero.copy {
 --mask: radial-gradient(
    circle at 15% 50%,
    black 4%,
    transparent 25%
  );
  -webkit-mask: var(--mask);
  mask: var(--mask);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El resultado ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floissrtwa6x42677tguo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floissrtwa6x42677tguo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rastrear la posición del cursor
&lt;/h3&gt;

&lt;p&gt;Para lograr nuestro efecto de "movimiento de la luz", necesitamos rastrear el cursor de acuerdo al movimiento del usuario, JavaScript al rescate 💪&lt;/p&gt;

&lt;p&gt;Primero definamos unas propiedades personalizadas "--x", "--y", y establezcamos una posición inicial para la máscara, 15% y 50% respectivamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--mask: radial-gradient(
  circle at var(--x, 15%) var(--y, 50%),
  black 4%,
  transparent 25%
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En nuestro archivo JS llamamos al evento "mousemove", obtenemos la posición del mouse y hacemos el cálculo para luego asignar ese valor porcentual a nuestras propiedades personalizadas --x y --y.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hero = document.querySelector(".hero.copy");

window.addEventListener("mousemove", (e) =&amp;gt; {
  const x = Math.round((e.clientX / window.innerWidth) * 100);
  const y = Math.round((e.clientY / window.innerHeight) * 100);
  hero.style.setProperty("--x", `${x}%` )
  hero.style.setProperty("--y", `${y}%`)
}); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/funny-night-vebz5t"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Al movimiento de nuestro "foco de luz" le falta un poco de suavidad para que no se sienta tenso. Para lograr esto utilizaré una biblioteca js de animaciones llamada gsap &lt;a href="https://greensock.com/docs/" rel="noopener noreferrer"&gt;https://greensock.com/docs/&lt;/a&gt;, esta biblioteca nos permite establecer una transición de manera sencilla a nuestra máscara ya que estamos utilizando propiedades personalizadas.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install gsap&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import gsap from "gsap";

const hero = document.querySelector(".hero.copy");

window.addEventListener("mousemove", (e) =&amp;gt; {
  const x = Math.round((e.clientX / window.innerWidth) * 100);
  const y = Math.round((e.clientY / window.innerHeight) * 100);
  gsap.to(hero, {
    "--x": `${x}%`,
    "--y": `${y}%`,
    duration: 0.4,
    ease: "sine.out",
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/dry-tdd-3f7jiy"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Ahora nuestro movimiento se siente mas natural 😁&lt;/p&gt;

&lt;p&gt;¡Espero este post haya sido de tu agrado!&lt;/p&gt;

&lt;p&gt;Te invito a que juegues con las máscaras css y me enseñes ese próximo proyecto donde incluyas grandiosos efectos con esta propiedad.&lt;/p&gt;

&lt;p&gt;Tu feedback es de mucha ayuda para mi 🙏&lt;/p&gt;

&lt;p&gt;Conectemos 😎&lt;br&gt;
&lt;a href="https://twitter.com/JairDevep" rel="noopener noreferrer"&gt;https://twitter.com/JairDevep&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Nos vemos pronto! 👊&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
