Making Magic with WebSockets and CSS3
“Any sufficiently advanced technology is indistinguishable from magic.”
― Arthur C. Clarke
Magic has a way of captivating attention and interest, and you can’t go wrong with magic tricks if you want to amaze people.
When I started programming, impressing people was easy to do with just a few lines of code. However, nowadays technology plays such a big role in our lives that we need to push ourselves constantly. And, we have to be really creative to amaze people.
Fortunately, the Internet of Things creates a world of opportunities to bring this kind of magic back.
You have the most unexpected objects getting connected to the internet, as well as a plethora of interactions with users and between… things.
Bringing the Magic Back with … a Shopping App? Seriously?
Just a few months ago, a few colleagues and I participated in a hackathon. The goal was to reinvent the way people shop for clothing.
We designed an application that would help a shopping assistant search for items the customers requested inside the store. The assistant could just easily swipe those clothing items onto a much bigger screen, so the customer would get a visual of what those items would look like.
Even though we didn’t win that particular competition — a different group of colleagues did and brilliantly — we noticed that particular kind of interaction, the swiping, had a big wow effect.
The audience saw images being pushed from a tablet and projected on a much bigger screen (that’s a little bit IoT). They appeared to travel by air, from starting point to destination. It was magically awesome.
Unveiling the Magic Trick
I’m going to show you how we did this. And I’ll be using a very appropriate, classic magician’s tool: a deck of playing cards:
There are two main factors in this interaction: real-time communication with WebSockets and optical illusions with CSS3. The devices synchronize the animation of the two different cards so the audience believes they’re the same instance.
So, let’s dive into the deets of how this magic really happens.
Real-time Communication with WebSockets
The internet we know was mainly built using the HTTP protocol, which relies on a simple request-response paradigm. This means that a typical web application won’t receive any information it did not explicitly request.
In my card example, I really need to inform the page that a card was thrown by the user on the phone. The most efficient way to do this is by opening a real-time communication channel both applications can access — the one running on the phone and the one displaying the card table.
I’ll show you how to build a simple real-time service that provides this capability. It requires running node.js on a server.
The following code delivers a simple web server that listens to WebSocket connections. The logic is simple. When it receives a message called table-connect it stores the device socket to redirect any message called phone-throw-card from a mobile phone socket.
Once the server is running the WebSocket service, it’s time to connect applications to it.
For this example, I used a library called socket.io. This library does more than just simplify the way I deal with WebSockets. It also creates a nice fallback for older versions of browsers that do not support the WebSocket protocol.
The card table application must connect to the real-time server and send (emit) a message for the server to identify and store the socket (table-connect).
It also registers a callback to deal with the arrival of the new card event (phone-throw-card) that will animate the entry of that card.
On the phone side, the code is also very simple. I just need to store the socket for use when I want to throw a new card on the table.
Optical Illusions with CSS3
We can make animations smooth as butter with CSS3 by following the best practices. For this simple trick and illusion, both devices have the same animation effect, but they are moving in opposite directions.
For the card to appear as if it landed on the table from the bottom of the phone, I created the element outside the viewport. Then, I animated it with a simple translateY transition so that it appears to slide into view.
I changed the table script (phone-throw-card event) to call a function that injects an HTML element on the page, outside the viewport, and after that I added a CSS class to trigger the animation.
You can check the codepen here for an example and — who knows? — maybe get some inspiration.
Going the Extra Mile
After everything’s up and running, it’s time to do some tweaking. The video showed the cards appearing to drop on the table from the bottom. By animating a reduction of size (scale) and using a shadow, it’s possible to get this more realistic effect.
As for the card dropping in the direction you set from the phone, most browsers already implement an API to read those values from mobile devices. If you add it, along with swipe intensity, to your previous phone-throw-card event, you should be able to make this example work on your side.
For help with these animations, check out this codepen:
Now that I’ve shared this trick with you, I really hope you’ll be inspired to make some magic of your own.