50 Projects in 50 Days, Day 8: Wavy Form Animation

50 Projects in 50 Days, Day 8: Wavy Form Animation

Today's installment of 50 Projects in 50 Days takes a simple two-field sign-in form and animates the labels when the user clicks on them.

I haven't mentioned a lot of personal history yet on this blog, but suffice it to say for now that I'm just a tad more life-experienced than many coding bootcampers. My first exposure to computers was way back in the 1980s with a Texas Instruments TI-99/4A my cousins owned and a used Radio Shack TRS-80 Color Computer that I bought myself with money saved up from mowing grass. Programs for computers like these had to be compact because of memory limitations on the machines. Every now and then a computer magazine (yes, a hard-copy magazine about computers; that was "a thing" too) would sponsor a contest looking for programs that would do the greatest amount of stuff in the smallest amount of code. This project, specifically the under-the-hood JS, reminded me of that time period.

At first glance there doesn't seem to be a lot going on with this project. The labels for the two fields start out on the line, and when the user clicks the label moves up to make room for input. Only, the label doesn't move straight up (like it would with a fairly simple transform operation using translateY on the whole thing at once). Rather, each letter in the label moves up at a slightly different time, giving a cool wave-like effect. This transition is the heart of the project and the focus of the rest of this post.

The JS code is fairly short, hence it reminding me of the era of one-line program contests.

const labels = document.querySelectorAll('.form-control label');

labels.forEach(label => {
  label.innerHTML = label.innerText.split('').map((letter, idx) => `<span style="transition-delay:${idx*80}ms">${letter}</span>`).join('')
});

However there is quite a bit happening here, so let's break it down.

First, as we've seen in other projects, a variable is created that results in a node list containing the form labels. (I wrote briefly about node lists in my post about the Day 2 project in this series). Since a node list works just like an array in JS, we can use the forEach method on it:

labels.forEach(label => {

This starts a for loop stepping through each element in the node list, and 'for each' of them the following operations take place:

  1. label.innerText.split('') : Accesses the .innerText of each label and then takes each individual character of the label (by 'splitting' it at each character)
  2. map((letter, idx) : passes two parameters to a function - 'letter', which is the value of the current element, and 'idx' which is the index
  3. => : This is the 'arrow function' called by map; it takes the previously mentioned arguments of 'letter' and 'idx' and builds a string using literals (more specifically, string interpolation) as follows:
    `<span style="transition-delay:${idx*80}ms">${letter}</span>`)
    
    This creates an HTML span tag which puts a transition-delay value on each letter of its index position (which, recall, was passed in as one of the arguments from .map) multiplied by 80.
  4. .join : this method passes the newly-created span tag back to the node list being created with .map.
  5. Finally, after all that, the value is assigned to the .innerHTML property of each of the labels in the node list.

From that point, the animation is handled by CSS definitions pertaining to when the form labels are active. All in all it really is impressive that so much happens in that one line of JS.

My Project: Wavy Form Animation