<?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: Stiaan Wolfaardt</title>
    <description>The latest articles on DEV Community by Stiaan Wolfaardt (@stiaanwol).</description>
    <link>https://dev.to/stiaanwol</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%2F1059646%2F1620a14b-6df2-4700-9c60-b9d65ef9eee1.jpeg</url>
      <title>DEV Community: Stiaan Wolfaardt</title>
      <link>https://dev.to/stiaanwol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stiaanwol"/>
    <language>en</language>
    <item>
      <title>How to build the ChatGPT typing animation in React</title>
      <dc:creator>Stiaan Wolfaardt</dc:creator>
      <pubDate>Mon, 10 Apr 2023 13:37:45 +0000</pubDate>
      <link>https://dev.to/stiaanwol/how-to-build-the-chatgpt-typing-animation-in-react-2cca</link>
      <guid>https://dev.to/stiaanwol/how-to-build-the-chatgpt-typing-animation-in-react-2cca</guid>
      <description>&lt;p&gt;ChatGPT utilizes a typing animation that emulates the appearance of typing on old-fashioned computer screens.&lt;/p&gt;

&lt;p&gt;This animation is achieved through two important concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The text is displayed one character at a time, creating the illusion of typing.&lt;/li&gt;
&lt;li&gt;A flashing cursor indicates the location of the character currently being typed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Let's start by examining how to display the text one character at a time:&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;useEffect(() =&amp;gt; {
  setCompletedTyping(false);

  let i = 0;
  const stringResponse = chatHistory[chatHistory.length - 1].content

  const intervalId = setInterval(() =&amp;gt; {
    setDisplayResponse(stringResponse.slice(0, i));

    i++;

    if (i &amp;gt; stringResponse.length) {
      clearInterval(intervalId);
      setCompletedTyping(true);
    }
  }, 20);

  return () =&amp;gt; clearInterval(intervalId);
}, [chatHistory]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To display the text character by character, use a simple &lt;code&gt;setInterval&lt;/code&gt; function that sets a state variable at each interval. This state variable is then displayed to the user. The &lt;code&gt;setInterval&lt;/code&gt; function continues calling the specified function until &lt;code&gt;clearInterval&lt;/code&gt; is called. In our case, we call &lt;code&gt;clearInterval&lt;/code&gt; when we have finished typing the entire string. &lt;/p&gt;

&lt;p&gt;The source of the string that will be displayed to the user depends on your app. We use a &lt;code&gt;useEffect&lt;/code&gt; hook that triggers each time ChatGPT sends a new response to a prompt. We store each response in an array of objects called &lt;code&gt;chatHistory&lt;/code&gt;. To display only the last response in the array, we use &lt;code&gt;chatHistory[chatHistory.length - 1].content&lt;/code&gt;. This retrieves the last object in the array.&lt;/p&gt;

&lt;p&gt;I set the intervals to 20 milliseconds, but you can adjust this to fit your app. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, let's move on to creating the flashing cursor. We use an &lt;code&gt;SVG&lt;/code&gt; and &lt;code&gt;CSS&lt;/code&gt; keyframes to achieve this effect:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This is achieved using a &lt;code&gt;SVG&lt;/code&gt; and &lt;code&gt;CSS&lt;/code&gt; keyframes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SVG&lt;/code&gt; we used for this purpose is the following:&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;svg
  viewBox="8 4 8 16"
  xmlns="http://www.w3.org/2000/svg"
  className="cursor"
&amp;gt;
  &amp;lt;rect x="10" y="6" width="4" height="12" fill="#fff" /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;cursor&lt;/code&gt; &lt;code&gt;className&lt;/code&gt;. Here's what it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.cursor {
  display: inline-block;
  width: 1ch;
  animation: flicker 0.5s infinite;
  margin-bottom: 4px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add the &lt;code&gt;flicker&lt;/code&gt; animation to the &lt;code&gt;SVG&lt;/code&gt; and ensure that it is properly aligned with the text being typed, appearing &lt;code&gt;inline&lt;/code&gt; with it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;flicker&lt;/code&gt; animation referenced here is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@keyframes flicker {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You then have to include the &lt;code&gt;SVG&lt;/code&gt; in your &lt;code&gt;JSX&lt;/code&gt;. This will ensure that the &lt;code&gt;SVG&lt;/code&gt; is only visible when typing is in progress and has not yet been completed.&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;span&amp;gt;
  {displayResponse}
  {!completedTyping &amp;amp;&amp;amp; &amp;lt;CursorSVG /&amp;gt;}
&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these steps in place, you'll be able to achieve the iconic ChatGPT typing animation!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMWIwOGUwM2NiNmU5YTNlYTViOTdjMjJhZTgxMWMzZjQxYmNiNWQyYyZjdD1n/QVwUihf1gqiBCGuGAX/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMWIwOGUwM2NiNmU5YTNlYTViOTdjMjJhZTgxMWMzZjQxYmNiNWQyYyZjdD1n/QVwUihf1gqiBCGuGAX/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you'd like to view the source code I used to achieve this effect, you can follow this link to my GitHub repository:&lt;br&gt;
&lt;a href="https://github.com/STIAANWOL/therapistgpt"&gt;https://github.com/STIAANWOL/therapistgpt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you'd like to see this effect in action with a live demo, you can follow this link: &lt;br&gt;
&lt;a href="https://therapistgpt-stiaanwol.vercel.app/"&gt;https://therapistgpt-stiaanwol.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this has been helpful to you, and happy coding!&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>css</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
