<?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: evanryan210</title>
    <description>The latest articles on DEV Community by evanryan210 (@evanryan210).</description>
    <link>https://dev.to/evanryan210</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%2F1071658%2Fadc8d6ec-fd61-426f-ba37-fd052b3c12ba.jpg</url>
      <title>DEV Community: evanryan210</title>
      <link>https://dev.to/evanryan210</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/evanryan210"/>
    <language>en</language>
    <item>
      <title>Making Your First Game With React Hooks</title>
      <dc:creator>evanryan210</dc:creator>
      <pubDate>Wed, 24 May 2023 18:59:25 +0000</pubDate>
      <link>https://dev.to/evanryan210/making-your-first-game-with-react-hooks-4j8p</link>
      <guid>https://dev.to/evanryan210/making-your-first-game-with-react-hooks-4j8p</guid>
      <description>&lt;h2&gt;
  
  
  I. Overview
&lt;/h2&gt;

&lt;p&gt;In this article I will being going over how to create a simple multiple choice game using React. In this walkthrough we will be creating a 'color guessing game' that can be used to familiarize yourself with the hex values of different colors. Building apps like these are a great way to solidify your understanding on the usage of React hooks as they are foundational in what makes the React framework so powerful!&lt;/p&gt;

&lt;p&gt;Take a look at the final product on CodeSandbox &lt;a href="https://codesandbox.io/p/github/evanryan210/hex-color-practice-tool/master?file=%2Fsrc%2FApp.test.tsx%3A1%2C1&amp;amp;layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522panelType%2522%253A%2522TABS%2522%252C%2522id%2522%253A%2522clhyn99zv000c356ksm08k7y8%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clhyn99zv000c356ksm08k7y8%2522%253A%257B%2522id%2522%253A%2522clhyn99zv000c356ksm08k7y8%2522%252C%2522activeTabId%2522%253A%2522clhyna10y00aq356kdc3cyq8m%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522id%2522%253A%2522clhyn9x7e005x356kxp3j5oob%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522port%2522%253A3000%252C%2522id%2522%253A%2522clhyna10y00aq356kdc3cyq8m%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.test.tsx%2522%252C%2522id%2522%253A%2522clhynb1gs00hg356kh4wta075%2522%252C%2522mode%2522%253A%2522temporary%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  II. Setup
&lt;/h2&gt;

&lt;p&gt;Here is the basic HTML that we will use for our app. We will add in the rest later.&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 style={{ display: 'flex', flexDirection: 'column' }}&amp;gt;
      &amp;lt;h1 style={{ textAlign: 'center' }}&amp;gt;Pick the Color Value&amp;lt;/h1&amp;gt;
      &amp;lt;div className={styles.container}&amp;gt;
        &amp;lt;div style={{ backgroundColor: `${divColor}` }} className={styles.colorBox}&amp;gt;
          &amp;lt;span&amp;gt;{INCORRECT/CORRECT DISPLAY GOES HERE}&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className={styles.buttonContainer}&amp;gt;
        {WHERE MULTIPLE CHOICE OPTIONS GO HERE}
      &amp;lt;/div&amp;gt;
      &amp;lt;p style={{ textAlign: 'center' }}&amp;gt;{CORRECT ANSWER COUNT GOES HERE}&amp;lt;/p&amp;gt;
      &amp;lt;p style={{ textAlign: 'center' }}&amp;gt;{INCORRECT ANSWER COUNT GOES HERE}&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  III. Generating values for initial render of our app
&lt;/h2&gt;

&lt;p&gt;Lets start by initializing the random color that will be displayed in our container box. We will do this by using the &lt;code&gt;'useState'&lt;/code&gt; hook, and giving it an initial value. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a function that return 3 random hex values in an array &lt;code&gt;getRandomHexArray()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getRandomHexArray = () =&amp;gt; {
    const value1 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    const value2 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    const value3 = ('#' + Math.floor(Math.random() * 16777215).toString(16))
    return [value1, value2, value3]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now we want to create a variable &lt;code&gt;initialRandomArray&lt;/code&gt; that will call the function we just created on each render, so we will have a new random array of hex values every time there is a state change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;let initialRandomArray = getRandomHexArray();&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We also need a state that holds a random value of range 0-initialRandomArray.length. This will decide which color code is "Correct" for each question. And we will create another state to hold our &lt;code&gt;initialRandomArray&lt;/code&gt;as well.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;const [answerIndex, setAnswerIndex] = useState(Math.floor(Math.random()*3))&lt;br&gt;
const [hexArray, setHexArray] = useState(initialRandomArray);&lt;/p&gt;


&lt;h2&gt;
  
  
  IV. Displaying buttons using map()
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;div className={styles.buttonContainer}&amp;gt;
        {WHERE MULTIPLE CHOICE OPTIONS GO HERE}
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we will finish this code to properly display our multiple choice options that the user will be clicking on.&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 className={styles.buttonContainer}&amp;gt;
        {hexArray.map((button, index) =&amp;gt; {
          return (
            &amp;lt;button key={index} className={styles.button} onClick={()=&amp;gt;{handleSubmit(index)}}&amp;gt;{hexArray[index].toUpperCase()}&amp;lt;/button&amp;gt;
          )
        })}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code returns a  element for every value we have inside &lt;code&gt;hexArray&lt;/code&gt;. We pass a child to the  element of &lt;code&gt;{hexArray[index].toUpperCase()}&lt;/code&gt; which displays the hex code on each of our buttons. We also pass to our onClick property a arrow function that runs our submission handler function which we will create now.&lt;/p&gt;




&lt;h2&gt;
  
  
  V. Handling submissions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSubmit = (index: any) =&amp;gt;{
    hexArray[index] == hexArray[answerIndex] ? handleCorrect() : handleIncorrect()
    let newRandomArray = getRandomHexArray()
    setHexArray(newRandomArray)
    setAnswerIndex(Math.floor(Math.random() * 3))
    setIsOpen(true)
    setTimeout(()=&amp;gt; setIsOpen(false), 1000)
  }

const handleCorrect = () =&amp;gt;{
    setIsCorrect(true)
  }

  const handleIncorrect = () =&amp;gt;{
    setIsCorrect(false)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function does a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It checks to see if the answer was correct by passing on index of the click event and comparing that to the hexArray at the answerIndex variable we store.&lt;/li&gt;
&lt;li&gt;Generates a new random array &lt;code&gt;newRandomArray&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sets isOpen to true, which lets us conditionally render feedback for the user to display 'Correct' or 'Incorrect' on each question as shown below.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div style={{ backgroundColor: `${hexArray[answerIndex]}` }} className={styles.colorBox}&amp;gt;
     &amp;lt;span className={styles.colorBoxText}&amp;gt;&amp;amp;nbsp;{isOpen ? isCorrect ? 'Correct!' : 'Incorrect' : ''}&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The setTimeout allows us to only display the 'Correct/Incorrect' text briefly for 1000 milliseconds by running an arrow function to set our &lt;code&gt;isOpen&lt;/code&gt; variable back to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&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%2Fbit6zmamkbsepo080o5o.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%2Fbit6zmamkbsepo080o5o.png" alt="Image description"&gt;&lt;/a&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%2F4uu00wm3tgb17ez1o8a8.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%2F4uu00wm3tgb17ez1o8a8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  There you go! Your first React game using hooks.
&lt;/h4&gt;

&lt;p&gt;Extra Credit: Add a count for incorrect and correct answers using useRef&lt;/p&gt;




&lt;p&gt;Author: Evan Ryan&lt;br&gt;
&lt;em&gt;OrangeSpark Solutions&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sharp Resizer: A CLI App For Resizing Images in Bulk</title>
      <dc:creator>evanryan210</dc:creator>
      <pubDate>Tue, 25 Apr 2023 22:48:17 +0000</pubDate>
      <link>https://dev.to/evanryan210/sharp-resizer-a-cli-app-for-resizing-images-in-bulk-4mo8</link>
      <guid>https://dev.to/evanryan210/sharp-resizer-a-cli-app-for-resizing-images-in-bulk-4mo8</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;In this article, we will be building a command line interface (CLI) application to assist in creating copies of an image to any number of specified sizes. This tool can be super useful and save you a lot of time, especially when building mobile apps that require different image sizes to display in different parts of the app.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
You can download the code through GitHub here: &lt;a href="https://github.com/evanryan210/sharp-resize"&gt;https://github.com/evanryan210/sharp-resize&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7tiVgWWt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hx04x7n9hh8ehnkp68z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7tiVgWWt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hx04x7n9hh8ehnkp68z5.png" alt="Final result: A set of resized images in your folder ready to use!" width="800" height="354"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;For this CLI app we will need to install a few node packages. We will be using node package manager so make sure you have that installed at this point. If you do not have it installed you can download it here: &lt;a href="https://nodejs.org/en/download"&gt;https://nodejs.org/en/download&lt;/a&gt;. The commands to install the packages we will be using are listed below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install sharp
npm install fs
npm install path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sharp&lt;/strong&gt;: A high-speed Node.js module that converts large images to varying dimensions.&lt;br&gt;
&lt;strong&gt;Fs&lt;/strong&gt;: A module that allows you to work with the file system on your computer.&lt;br&gt;
&lt;strong&gt;Path&lt;/strong&gt;: The Path module provides a way of working with directories and file paths.&lt;/p&gt;

&lt;p&gt;In our project folder, lets make a json file and name it &lt;code&gt;resize.json&lt;/code&gt;. This is where we will store our path to the image we want to resize, our path to the destination we want to save our resized images to, and an array of our desired sizes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "imagePath" : "[IMAGE PATH TO BE RESIZED]",
    "outputPath": "[DESTINATION FOLDER PATH TO STORE IMAGES]",
    "settings": {
        "ios": [20,29,40,40,58,60,60,76,80,87,120,120,152,167,180,1024],
        "android": [36,48,64,72,96,144,192,512]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You can add however many &lt;code&gt;'settings'&lt;/code&gt; values you need. For this example, I did two since I wanted two sets of resized images in their own respective folder.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Setting Up a Watcher
&lt;/h1&gt;

&lt;p&gt;If you are not aware, since we are using Typescript we must compile our code before we run it in node. To avoid having to compile each time we make changes to our app, I prefer to run a watcher in the terminal to save some time. This watcher will look for changes in our file and compile instantly. The command to run the watcher 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;tsc -w
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your terminal should display something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[5:05:25 PM] Starting compilation in watch mode...

[5:05:27 PM] Found 0 errors. Watching for file changes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(P.S. Make sure not to accidentally close this terminal)&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Index.ts
&lt;/h1&gt;

&lt;p&gt;Now we will be working in the root &lt;code&gt;index.ts&lt;/code&gt; file of the project. Lets start by defining a 'type', &lt;code&gt;PlatformData&lt;/code&gt;, for our json object we just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type PlatformData = {
    imagePath: string,
    outputPath: string,
    settings: Record&amp;lt;string, number[]&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going to use the &lt;code&gt;fs&lt;/code&gt; module we installed to get the data from our &lt;code&gt;resize.json&lt;/code&gt; file using the &lt;code&gt;fs.readFileSync()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = fs.readFileSync(path.join(`resize.json`), 'utf8');
const parsedData: PlatformData = JSON.parse(data);
const imgPath = parsedData.imagePath //"[IMAGE PATH]"
const folderPath = parsedData.outputPath //"[DESTINATION FOLDER PATH]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are then going to parse that data and store it in a variable, &lt;code&gt;parsedData&lt;/code&gt;. Now we can use this parsed data and also create &lt;code&gt;imgPath&lt;/code&gt; and &lt;code&gt;folderPath&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now lets make the actual function that is going to take the image size and platform as arguments, and give us a file from the resized image data at the specified path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const resize = (imgSize: number, platform: string) =&amp;gt;{
    sharp(imgPath)
        .resize(imgSize)
        .toFile(`${folderPath}/${platform}/sample_${imgSize}.jpg`, function (err) {
        });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our function to resize our image is done, lets make sure there is a directory to store our new set of resized images by checking if it exists using &lt;code&gt;fs.existsSync(folderPath)&lt;/code&gt;. If it does not exist, we can use &lt;code&gt;fs.mkdirSync(folderPath)&lt;/code&gt; to create a folder as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!fs.existsSync(folderPath)){
    fs.mkdirSync(folderPath)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we need to do a &lt;code&gt;try...catch&lt;/code&gt; that will use a &lt;code&gt;forEach()&lt;/code&gt; loop to iterate through the values in our array(s) and resize the image to each size being passed. After this stage you have a completed resizing app!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
    const platforms = parsedData.settings
    Object.keys(platforms).forEach(platform =&amp;gt; {
        if (!fs.existsSync(`${folderPath}/${platform}`)) {
            fs.mkdirSync(`${folderPath}/${platform}`)
            //Only if you want platform specific folders
        }
        const platformSizes = platforms[platform]
        platformSizes.forEach(size =&amp;gt; {
            resize(size, platform)
        })
    })
    console.log(`Resizer has loaded images here: ${folderPath} `)
} catch (err) {
    console.error(err);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;p&gt;To use the app we just created, make sure the &lt;code&gt;resize.json&lt;/code&gt; has the proper values for &lt;code&gt;imagePath&lt;/code&gt;and &lt;code&gt;outputPath&lt;/code&gt;, and simply run the following command in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;&lt;br&gt;
I hoped you enjoyed this walkthrough! Best of luck in your coding endeavors :D&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Author,&lt;br&gt;
Evan Ryan, OrangeSpark Solutions&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sharp</category>
      <category>typescript</category>
      <category>cli</category>
      <category>node</category>
    </item>
  </channel>
</rss>
