creating the appending text effect with javascript

Viewed 30

const alphabets = [' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

const handleClick = async () => {
  let inputVal = document.getElementById('textInput').value.toLowerCase().split('')

  if (inputVal.length <= 0) return alert('Please Type something!')

  for (val in inputVal) {
    if (alphabets.includes(inputVal[val]) === false) return alert('Use only letters and space')
  }

  let inLen = inputVal.length
  let echTxt = 0
  let runningWordsDiv = document.getElementsByClassName('runningWords')[0]

  do {
    console.log(echTxt)
    for (let letter = 0; letter <= alphabets.length; letter++) {
      setTimeout(() => {
        if (alphabets[letter] === undefined) return
        runningWordsDiv.innerHTML = alphabets[letter].toUpperCase()
      }, 200 * letter);
    }
    echTxt++
  }
  while (echTxt < inLen)
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');

* {
  margin: 0;
  padding: 0;
}

body {
  background: #333;
  font-family: 'Poppins', sans-serif;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  position: relative;
}

.container .inputs {
  display: flex;
  flex-direction: column;
}

.container .inputs input {
  width: 30em;
  height: 3em;
  margin-bottom: 1em;
  border-radius: 0.5em;
  padding-left: 1em;
  border: 0.25em solid transparent;
  transition: all 300ms ease-in-out;
}

.container .inputs input:hover,
.container .inputs input:focus {
  outline: none;
  border: 0.25em solid rgb(0, 140, 255);
}

.container .inputs button {
  width: 7em;
  height: 2.5em;
  margin: auto;
  border: 1px solid rgb(0, 140, 255);
  background-color: #333;
  color: rgb(0, 140, 255);
  border-radius: 0.5em;
  transition: all 300ms ease-in-out;
  cursor: pointer;
}

.container .inputs button:hover {
  background-color: rgb(0, 140, 255);
  color: #333;
}

.container .runningWords {
  position: absolute;
  top: 25%;
  width: 60%;
  margin: 0 20%;
  height: 80px;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: rgb(0, 140, 255);
  font-size: 3em;
  font-weight: 700;
}
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Project</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="runningWords"></div>
    <div class="inputs">
      <input type="text" name="text" id="textInput" value="test" placeholder="Enter String...">
      <button onclick="handleClick()">Go...</button>
    </div>
  </div>

  <script src="main.js"></script>
</body>
</html>

I was trying to create a text effect, where at first when we type something on input field and click on go button, whatever we type should be shown in the runningWords div, but with a effect like, if we type something as test then it should first append the alphabets when the first letter of typed word t matches the word in alphabets, then it should stop on that and then move to next append and the next word of types word is e, so the alphabets loop stop at e and move to next word of typed word. This the most i tried, but when i run the console.log(echTxt) it runs upto the types word length in an instant and then only it starts appending to the runningWords div. Please help me somebody.

Thanks in advance.

1 Answers

Did you want to achieve something like this? Check inline comments:

// Alphabet
const alphabets = [
  ' ',
  'a', 'b', 'c', 'd', 'e', 'f', 'g',
  'h', 'i', 'j', 'k', 'l', 'm', 'n',
  'o', 'p', 'q', 'r', 's', 't', 'u',
  'v', 'w', 'x', 'y', 'z'
];

// Timeout function
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));

// Handle click
const handleClick = async () => {
  // Loop visualization function
  const innerWithFx = async (letter, pre) => {
    // Loop alphabets
    for(const l of alphabets) {
      // Put letter
      runningWordsDiv.innerHTML = pre + l.toUpperCase();
      // If letters match
      if(l == letter) return l;
      // Sleep for timeout
      await timeout(100);
    }
  };
  // Target field
  const runningWordsDiv = document.getElementsByClassName('runningWords')[0];
  // Read input string and split in to the array
  const inpArr = (document.getElementById('textInput').value).toLowerCase().split('');
  // Loop input array and run fx for each letter
  for(const letter of inpArr) {
    // Search for letter with fx
    const foundLetter = await innerWithFx(letter, runningWordsDiv.textContent);
  }
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');

* {
  margin: 0;
  padding: 0;
}

body {
  background: #333;
  font-family: 'Poppins', sans-serif;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  position: relative;
}

.container .inputs {
  display: flex;
  flex-direction: column;
}

.container .inputs input {
  width: 30em;
  height: 3em;
  margin-bottom: 1em;
  border-radius: 0.5em;
  padding-left: 1em;
  border: 0.25em solid transparent;
  transition: all 300ms ease-in-out;
}

.container .inputs input:hover,
.container .inputs input:focus {
  outline: none;
  border: 0.25em solid rgb(0, 140, 255);
}

.container .inputs button {
  position: relative;
  width: 7em;
  height: 2.5em;
  margin: auto;
  border: 1px solid rgb(0, 140, 255);
  background-color: #333;
  color: rgb(0, 140, 255);
  border-radius: 0.5em;
  transition: all 300ms ease-in-out;
  cursor: pointer;
}

.container .inputs button:hover {
  background-color: rgb(0, 140, 255);
  color: #333;
}

.runningWords {
  position: relative;
  top: -10px;
  width: 60%;
  margin: 0 20%;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: rgb(0, 140, 255);
  font-size: 3em;
  font-weight: 700;
}
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Project</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="inputs">
      <div class="runningWords"></div>
      <input type="text" name="text" id="textInput" value="test" placeholder="Enter String...">
      <button onclick="handleClick()">Go...</button>
    </div>
  </div>

  <script src="main.js"></script>
</body>
</html>

Related