<?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>DEV Community: Gabriel Fleury</title>
    <description>The latest articles on DEV Community by Gabriel Fleury (@ga-fleury).</description>
    <link>https://dev.to/ga-fleury</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%2F1816704%2Fe872f842-dd4f-45f2-94f9-3d9df134ba68.png</url>
      <title>DEV Community: Gabriel Fleury</title>
      <link>https://dev.to/ga-fleury</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ga-fleury"/>
    <language>en</language>
    <item>
      <title>Valorant Character Selection Character Reveal Effect</title>
      <dc:creator>Gabriel Fleury</dc:creator>
      <pubDate>Mon, 22 Jul 2024 09:13:00 +0000</pubDate>
      <link>https://dev.to/ga-fleury/valorant-character-selection-character-reveal-effect-26hp</link>
      <guid>https://dev.to/ga-fleury/valorant-character-selection-character-reveal-effect-26hp</guid>
      <description>&lt;p&gt;I was inspired by Valorant's character selection screen to create this reveal effect. Click the character portraits or use your arrow keys to interact!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ga-fleury/embed/eYwZPEp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup
&lt;/h3&gt;

&lt;p&gt;To achieve this effect, we are going to use &lt;a href="https://animejs.com/" rel="noopener noreferrer"&gt;AnimeJS&lt;/a&gt; for the image animations and &lt;a href="https://sarcadass.github.io/granim.js/" rel="noopener noreferrer"&gt;Granim.js&lt;/a&gt; for the background gradient transitions&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgcv7b42ynwvggdqtp9f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgcv7b42ynwvggdqtp9f.jpg" alt="three images of Omen, a valorant Agent" width="700" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are using three images total: the main character PNG cutout and two colored overlay versions. One of these colored cutouts will lag behind the main image, and the other will shoot just slightly forward, giving us this springy effect. The background is just a &lt;code&gt;canvas&lt;/code&gt; element that Granim.js will target.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;First, we are going to create an event listener that will move our agent's image when we press the right arrow key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.addEventListener("keydown", function (event) {
  if (event.key === "ArrowRight") {
    animationRight();
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside our &lt;code&gt;animationRight()&lt;/code&gt; function, we are going to use AnimeJS to target our agent's three-image stack container and move it from &lt;strong&gt;&lt;u&gt;right to left&lt;/u&gt;&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;anime({
        targets: ".agent-container",
        translateX: [
          "250px", // Initial state
          "0px" // Final state
        ],
        easing: "easeOutCubic",
        duration: 250
      });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we target the color we want to lag behind and animate it. Keep in mind that all images have &lt;code&gt;position: absolute&lt;/code&gt; and &lt;code&gt;transform: translateX(-50%)&lt;/code&gt; in order to be stacked and centered, so their final &lt;code&gt;translateX&lt;/code&gt; value should be -50%, not 0. Since we are moving from &lt;strong&gt;&lt;u&gt;right to left&lt;/u&gt;&lt;/strong&gt;, this means the image has to start at a bigger value than -50%.&lt;/p&gt;

&lt;p&gt;You can mess around with the easing, but I find it best to keep this first tracer from bouncing around; otherwise, the animation looks a little bit messy. We'll use the other tracer to sell the 'recoil'. In both instances, we are using AnimeJS's incredible &lt;code&gt;spring()&lt;/code&gt; easing, which makes it easy to achieve 'weighty' results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      anime({
        targets: ".agent-fb-B",
        translateX: [
          "-32%", // Initial state
          "-50%" // Final state
        ],
        easing: "spring(1, 100, 40, 0)",
        duration: 100
      });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To finish it off, we do the same thing to the other image, but we make it go 'faster' than the main image before coming to the same position, giving it a 'recoily' feeling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  anime({
        targets: ".agent-fb-S",
        translateX: [
          "-46%", // Initial state
          "-50%" // Final state
        ],
        easing: "spring(1, 100, 10, 20)",
        duration: 150
      });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gradients!
&lt;/h3&gt;

&lt;p&gt;Using Granim.js, you can set up a neat gradient background, and it'll handle the gradient transitions or any animations that you want to use for your background&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var granimInstance = new Granim({
    element: '#canvas-interactive',
    direction: 'diagonal',
    states : {
        "default-state": {
            gradients: [
                ['#B3FFAB', '#12FFF7'],
            ]
        },
        ...
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically all you need is to define different 'states' and when you want to change colors (for example when picking a new agent) you just have to call &lt;code&gt;granimInstance.changeState('new-state');&lt;/code&gt; and that's it!&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>interaction</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
