Since it has spread so far into the "geek culture", why not incorporating it into your next website?
In today's article, we are going to see how to detect the Konami Code in Svelte by leveraging the concept of stores in order to create a small easter egg 🥚.
However, we might have the key but we do not have any way to access the current value held by the store.
For that, the function used in readable takes two additional parameters:
A set function that can be used to set the value of the store
An update function that uses a callback to modify the current value of the store
While set would not help in appending a value, update definitely will, let's grab it:
constlastKeyPressed=readable(newArray<KeyCode>(),(_set,update)=>{consthandleKeyDown=(event:KeyboardEvent):void=>{constkeyPressed=keyMap[event.key];update((currentSequence:KeyCode[])=>{constnext=currentSequence.concat(keyPressed);// 👇 Discards the oldest value if the sequence is too longif (next.length>konamiCode.length){next.splice(0,1);}returnnext;});};window.addEventListener('keydown',handleKeyDown);return ()=>window.removeEventListener('keydown',handleKeyDown);});
We now have a store that is storing the latest pressed keys and exposes them as sequence of the Konami Code.
Now onward to detecting it!
Detecting the Konami Code
We have several ways of signaling to a consumer when the Konami Code has been entered.
However, as I'm thinking of stores as a kind of RxJS's Observables, I tend to prefer deriving a value from it to keep my code as declarative as possible.
If the concept of "declarative code" is not something you are familiar with, Joshua Morony has some wonderful videos on that subject:
Hopefully, it seems to also be the case for the Svelte core dev team as it is possible to derive a store from another one by using derived.
To derive a store, the syntax is pretty straightforward:
As a first parameter, the derived function is expecting the store to derive its value from
As a second parameter, we should define a function that takes the value emitted by the store we derived from and infer the value of the current store
In our case, the inferred value will simply be a boolean evaluated to true if the current sequence matches the Konami Code:
// 👇 Don't forget to export this store!exportconstisKonamiCodePressed:Readable<boolean>=derived(lastKeyPressed,($pressedKeys:KeyCode[])=>JSON.stringify($pressedKeys)===JSON.stringify(konamiCode));
We could have computed the value of JSON.stringify(konamiCode) instead of recomputing it everytime but for the sake of this tutorial I will spare you some additional code
Reacting to Its Detection
With our Konami Code detection store, we can now use it in our Svelte app to add a small easter egg.
In a new Svelte component, all we have to do is to subscribe to the store and react to whenever it has been entered:
<script lang="ts">import{onDestroy,onMount}from'svelte';importtype{Unsubscriber}from'svelte/store';import{isKonamiCodePressed}from'$lib/stores/konami';letunsubscribe:Unsubscriber=()=>{};onMount(()=>{unsubscribe=isKonamiCodePressed.subscribe((isKonamiCodePressed:boolean):void=>{if (!isKonamiCodePressed)return;console.log('Konami Code detected!');});});// 👇 Don't forget to remove the event listeneronDestroy(unsubscribe);</script>
While it works, a console.log might not be the most funny thing we can do with that.
Let's build something visual and unexpected, like confetti 🎊!
This project was generated with Analog, the fullstack meta-framework for Angular.
Setup
Run npm install to install the application dependencies.
Development
Run npm start for a dev server. Navigate to http://localhost:5173/. The application automatically reloads if you change any of the source files.
Build
Run npm run build to build the client/server project. The client build artifacts are located in the dist/analog/public directory. The server for the API build artifacts are located in the dist/analog/server directory.