DEV Community

Cover image for JavaSpooky: Using JavaScript to revive an old horror webcomic from a flashplayer grave.
Nick Gottschlich
Nick Gottschlich

Posted on

JavaSpooky: Using JavaScript to revive an old horror webcomic from a flashplayer grave.

Back in the day, a certain internet webcomic achieved a level of infamy for it's startling twist.

However, the shocking twist that powered that comic was written with Adobe Flash Player, which will be completely deprecated from the internet on December 31, 2020.

And thus, a part of internet history was lost to the ages...

Or was it? (BE WARNED, the below link contains spooky jump scares)

https://thatspookycomic.github.io/

Were you brave enough to try it out? I decided to recreate the infamous effect using nothing but vanilla JS, HTML, and CSS along with some new-school web APIs. You can compare the results of the page above with a recording of the original effect.

So how was it done?

The Jump Scare sound

Let's start from the top of the page. You probably noticed the pumpkin emoji that the page tells you to click on, right?

Pumpkin Emoji with some text telling you to click it

Seems like a cute little innocent Halloween fun, right? Well, it actually hides a sinister purpose.

In order to play the jump scare noises on the page, I use a web API called Audio.

Now, the Audio tool is designed to prevent the annoyance of auto-playing media that starts when a webpage is opened. If the user has not interacted with the document, when you try to play a sound you get this error:

Dev Tools console error saying user has to interact with document before audio will play

So in order for us to do something like:

const spookySound = new Audio('audio/spooky-sound.mp3');
spookySound.play();
Enter fullscreen mode Exit fullscreen mode

We first have to incentive the user to click somewhere on the page! So I dropped in a little JS to update a pumpkin emoji onclick:

<span id="clickEmoji" onclick="emojiClickChange()">🎃</span>
Enter fullscreen mode Exit fullscreen mode
function emojiClickChange() {
  document.getElementById('clickEmoji').innerText = "👻";
}
Enter fullscreen mode Exit fullscreen mode

We are now ready to fire off some scary sounds!

Triggering the Jump Scare

Next up, we need to detect when the user has scrolled to a certain point on the page, where we need to fire the jump scare effect.

To do that, we use the Intersection Observer API.

I dropped an id on the two images where I wanted the jump scare to occur:

<img src="images/7.jpg" id="firstTarget" />
...
<img src="images/17.jpg" id="secondTarget" />
Enter fullscreen mode Exit fullscreen mode

and then I create an observer and observe those images:

let observer = new IntersectionObserver(handler);
observer.observe(document.getElementById('firstTarget'));
observer.observe(document.getElementById('secondTarget'));
Enter fullscreen mode Exit fullscreen mode

Now, we can create a function that will be called whenever the state of those observed items changes!

function handler(entries) {
  for (entry of entries) {
    if (
      entry.target.id === 'firstTarget'
      && entry.isIntersecting
      && !firstJumpScareActivated
    ) {
      playFirstJumpScare();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Whenever any of the observed items changes state the handler function is called. We can read entry.target.id to know what item we are dealing with, isIntersecting to know if the user has scrolled the item into view, and I use a boolean XJumpScareActivated to make sure the effect only happens once.

One last thing, if your images load in slow, the effect might be triggered if the id is briefly in frame when the page loads. The right way to fix this is to wait for all images to be loaded before starting the intersection observer, but for the sake of simplicity, a setTimeout did the job for me:

setTimeout(() => {
  observer.observe(document.getElementById('firstTarget'));
  observer.observe(document.getElementById('secondTarget'));
}, 3000)
Enter fullscreen mode Exit fullscreen mode

Great, we can now tell when the user has scrolled our target item into view, and we are ready to play sound. Last up, we need to create the rapid scrolling jump effect!

Auto scrolling the user around

In order for this jump scare to work properly, we want to rapidly scroll the user through the comic frames while playing a sound. The scariest part of this effect comes from the fact that the user thinks they have control of the pace of the comic, and we want to rapidly tear that control away from them.

The way I built this was by scrolling to each part of the page I wanted to scroll the user to, and in the dev tools console, typing window.scrollY:

Screen Shot 2020-10-31 at 2.31.09 PM

Now that I had the Y coordinate I wanted, I just trigger the scroll effect at setTimeout intervals on each Y coordinate. The code looks like this:

function playFirstJumpScare() {
  setTimeout(() => {
    clickSound.play();
    window.scrollTo(0, 8441);
  }, 800)

  setTimeout(() => {
    window.scrollTo(0, 9090);
  }, 900)

  setTimeout(() => {
    window.scrollTo(0, 9660);
  }, 1000)

  ...
}
Enter fullscreen mode Exit fullscreen mode

Future improvements could involve putting all the times and scroll positions into an array of objects and mapping through them:

[
  {
    time: 800,
    scrollPos: 8441
  },
  ...
]
Enter fullscreen mode Exit fullscreen mode

But today is Halloween already and I needed to release this thing, stat! So for now, the code stays ugly.

Once I activate the jump scare, I set a boolean to true so that it doesn't happen again:

firstJumpScareActivated = true;
Enter fullscreen mode Exit fullscreen mode

Finally, to get the website online, I created a new GitHub account and used GitHub Pages, you can see the full code of the website here.

I hope this was informative, interesting, and most importantly, terrifying. Feel free to share the comic with all your friends this spooky last night of October! Happy Halloween!

Top comments (2)

Collapse
 
raybb profile image
Ray Berger

Got a few good laughs out of this! Thanks for sharing

Collapse
 
cyril_ogoh profile image
ogoh cyril

Enjoyed the scare 😂😂

Its a nice project 🤘🏽