Stranger Things alphabet wall scene using vanilla JavaScript

Recreate your own version of the spooky alphabet wall scene using HTML5, CSS3 and JavaScript

Suchandra Datta
Nov 7 · 5 min read
Image for post
Image for post
Stranger Things alphabet wall scene Season 1 episode 3

If you’re a Stranger Things fan like me then I need explain no further, you understand exactly what we are trying to make here right ? Recall Season One, Will vanishes but remains near his house in the other dimension, uses the Christmas lights set up at his house by his mother to warn her of the demons and tells her to RUN. If you’re not a Stranger Things fan, no matter how lucidly I strive to explain, you will not be able comprehend what’s so exciting about an alphabet wall. We shall try to recreate this wall using HTML5 and CSS3 to simulate as closely as possible the lights shown in the picture; we’ll have a text input field which takes a message as input, let’s say RUN and displays it on the alphabet wall as it occurred in the Stranger Things scene, that is, the light above R shines momentarily and goes out, then the light above U shines and stops, finally the light above N. JavaScript timers will be used to achieve such functionality.

Image for post
Image for post
Screenshot of my Codepen featuring the alphabet wall we’re trying to build

For ease of display in Codepen, the alphabets from S to Z are not shown but commented out in code. To start constructing the alphabet wall, we need some Christmas lights. The lights need a wire on which to be strung.

<ul class="wire" id="setOne">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>

This ul list of 8 li elements will be styled to look like lights hanging above the alphabets A to H. Next define the styles for the wire and for each list item.

            .wire
{
text-align: center;
white-space: nowrap;
position: absolute;
padding: 0;
width: 100%;
top: -80px;
border-bottom: 1px solid black;
height: 100px;
}
.wire li
{
position: relative;
list-style: none;
margin: 0 15px;
padding: 0;
display: inline-block;
width: 15px;
height: 25px;
border-radius: 50%;
top: 102px;
background: white;
}

The entire styling for Christmas lights is learnt from an awesome video on the same (after a whole lot of searching online)from the Net Ninja YouTube channel linked as follows https://youtu.be/B9OZkATMbag The steps are described in great detail in an engaging manner, it helped me a lot and hopefully you’ll enjoy the video too!

Once the lights are set up, we need the alphabets.

.eachKey
{
height: 30px;
width: 30px;
background-color: rgba(0,0,0,0.7);
color: white;
font-size: 1rem;
border-radius: 50%;
text-align: center;
float: left;
margin: 2%;
box-shadow: 0.25rem 0.25rem 0.5rem 0.75rem rgba(255,255,255,0.2);
}
.keypad
{
position: relative;
margin-top: 20vh;
margin-left: 5vw;
height: auto;
width: 100%;

text-align: center;
color: white;
background-color: rgba(0,0,0,0.5);
}

The styles for each key and the container for the keys is very simple. The HTML structure for the same is as follows

<div class="keypad">
<div class="eachKey">
A
</div>
<div class="eachKey">
B
</div>
<div class="eachKey">
C
</div>
<div class="eachKey">
D
</div>
<div class="eachKey">
E
</div>
<div class="eachKey">
F
</div>
<div class="eachKey">
G
</div>
<div class="eachKey">
H
</div>
</div>

This forms the first row of the alphabet wall with the lights above it. Repeat it for more rows till all 26 alphabets are covered. Next we set up a text field and obtain a message from the user.

message=document.getElementById("message").value;
message=message.toLocaleUpperCase();

We loop over the message length. For each character at position i, do the following

index=message.charCodeAt(i)-65;

The ASCII values of alphabets are mapped from 0 to 25 from their expected range 65 to 90 so that the index helps to access the required light(or list item). Depending on structure of the rows, the index will be the light number to be turned on. Specific to my example, the required code is

if(index>=0 && index<=7)
{
ele=document.getElementById("setOne").getElementsByTagName("li")
}

Similarly for other values of index, the correct id setTwo or setThree is to be applied. To give the effect that lights are turned on, we add a box-shadow to it. For instance, to turn on the blue lights, we need the following code

//BLUE
ele[index].style.backgroundColor='aqua';
colorValue='rgba(0,153,255,0.8)'
ele[index].style.boxShadow='0px 2px 20px 4px #ffff00';

Once the light is turned on, we wait for one second before turning it off and turning on the next light. setTimeout does not provide this facility by itself given how the code is structured. It is non-blocking, so it just puts the callback function on the queue and goes on to execute the next statements.

A setTimeout call after applying box shadow and defining the callback function to reset the light back to original colors doesn’t work. A Promise based approach is adopted.

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
//Inspired from an example on MDN

A Promise object as defined in the MDN docs is a proxy for a value that isn’t known when the promise is created. It holds the eventual state or outcome of asynchronous events when the event completes. If the event is successful, the Promise is said to be resolved or its state is fulfilled and it returns a value. If the event is unsuccessful, it is rejected and the error object is returned. The resolve function sets the value of the Promise on successful termination.

We await completion of sleep function, thus ensuring that program control waits till timeout returns, instead of just going on to the next line of code spoiling the overall effect.

And functions which wait for promises to be returned must be async themselves, we declare our driver function as async too. Once the time stipulated for delay elapses, we reset the bulb to it’s original color.

We’ve just made our very own alphabet wall we can play around with and even show our Stranger Things loving friends who’ll love it too! Full code available at my Codepen linked as follows: https://codepen.io/Suchandra_Datta/pen/xxbEQdJ

Thanks for reading this far I hope you liked it. Eagerly waiting for your advice on improvement, best practices, any tips you wanted to share. Once again thanks for your time I wish you a good day. Stay safe and take care. Happy coding!

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Suchandra Datta

Written by

Interested in machine learning, web development. Sharing experiences of my coding journey, one byte at a time. Currently pursuing Masters in Computer Science.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Suchandra Datta

Written by

Interested in machine learning, web development. Sharing experiences of my coding journey, one byte at a time. Currently pursuing Masters in Computer Science.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store