Hi everyone - below is some code that shows off a typewriter effect to make an input more appealing/informative for someone to use
Example with video here:
Full HTML, CSS, and JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Foodoogle</title>
<style>
body {
background-color: gold;
display: grid;
align-items: center;
justify-items: center;
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
}
body {
background-image: url("https://www.kirupa.com/images/yellowblob.svg");
background-repeat: no-repeat;
background-size: cover;
}
h1 {
font-family: sans-serif;
font-size: 72px;
font-weight: bold;
text-align: center;
color: #5d4e00;
margin-bottom: 60px;
}
#search {
font-family: sans-serif;
font-size: 20px;
font-weight: bold;
padding: 30px;
padding-left: 70px;
background-image: url(https://www.kirupa.com/icon/1f50d.svg);
background-repeat: no-repeat;
background-size: 30px;
background-position: 20px center;
border: none;
box-shadow: #c5c5c5 0px 0px 10px;
width: 300px;
transition: box-shadow .2s ease-out;
}
#search:hover {
box-shadow: #858585 0px 0px 20px;
}
#search:focus {
box-shadow: #858585 0px 0px 40px;
}
#search::placeholder {
color: #8c8c8c;
font-weight: lighter;
}
.orange img {
width: 50px;
display: block;
margin: 0 auto;
margin-top: 100px;
}
</style>
</head>
<body>
<div>
<h1>Foodoogle</h1>
<form id="infoForm">
<input id="search" autocomplete="off" type="text">
</form>
<a class="orange" href="https://www.kirupa.com">
<img src="https://www.kirupa.com/images/orange.png">
</a>
</div>
<script>
let words = ["pizza", "cheeseburger", "salad", "fried rice", "burrito", "spaghetti", "pho"];
let wordToPrint = "";
let letter = 0;
let count = 0;
let direction = "forward";
let intervalID = null;
let timeoutID = null;
let placeholder = "Looking for something?";
let inputField = document.querySelector("#search");
inputField.addEventListener("focus", checkFocus, false);
inputField.addEventListener("blur", checkFocus, false);
function checkFocus(e) {
if (e.type == "focus") {
stopCycle();
} else if (e.type == "blur") {
startCycle();
}
}
function cycle() {
let word = words[count];
if (direction == "forward") {
if (letter < word.length) {
wordToPrint += word[letter];
updatePlaceholder(wordToPrint);
letter++;
} else {
direction = "backward";
clearInterval(intervalID);
intervalID = setInterval(cycle, 100);
}
} else {
if (wordToPrint.length > 0) {
wordToPrint = wordToPrint.slice(0, -1);
updatePlaceholder(wordToPrint);
} else {
startOver();
}
}
}
function startOver() {
resetState();
// start from the beginning of array if at the end
if (count < words.length - 1) {
count++;
} else {
count = 0;
}
intervalID = setInterval(cycle, 200);
}
function resetState() {
letter = 0;
wordToPrint = "";
direction = "forward";
clearTimeout(timeoutID);
clearInterval(intervalID);
}
function startCycle() {
if (inputField.value === "") {
resetState();
updatePlaceholder(placeholder);
timeoutID = setTimeout(() => {
intervalID = setInterval(cycle, 200);
}, 3000);
}
}
function stopCycle() {
resetState();
updatePlaceholder(placeholder);
}
function updatePlaceholder(text) {
inputField.setAttribute("placeholder", text);
}
startCycle();
</script>
</body>
</html>
There will be a more detailed tutorial on this in the future, but until then, consider this a temporary placeholder
Cheers,
Kirupa