It’s been a week since we launched our quick Code Challenge #1, which means it’s time to announce a winner! It was tricky. While the quantity of entries wasn’t high, there’s no questioning the quality of our winning entries.
But first, let’s run through a few different approaches to the challenge we supplied.
My turn first!
As I set the rules for this challenge, I thought it was only fair that I take the challenge on first.
(* And no, I can’t award the prize to myself… well, I’m pretty sure I can’t… right?!? ).
I played around with both a CSS and SVG solution – two of my stronger suits – and decided to not use any scripting. As there’s no true random function available in either CSS or SVG, the trick was always to make regular animation loops appear more random than they actually are. Here’s my solution.
See the Pen
Pure CSS ‘organic-looking’ EKG Animation by Alex (@alexmwalker)
on CodePen.
Feel free to pick through the code, but the main points of interest are:
- The EKG line animation only uses one external SVG and two separate animation loops.
- One CSS animation (travel) loops the green gradient from left to right. An overlaying mask shapes the EKG line.
- I created 6 unique ‘EKG heartbeats’ on the SVG graphic and set them up as sprite keyframes. I’m switching these keyframes to make them look randomized (I’ve added tiny numbers at the bottom to make the keyframe switching more obvious).
- The second animation treats each ‘heartbeat’ as a separate sprite and switches to a new one on each pass – but this is timed to only take place in the dark section of the loop when it can’t be seen.
- Of course, as each ‘heartbeat unit’ uses exactly the same CSS animation, we would normally expect them all to show the same keyframes. The trick to make them all appear different is to offset their starting times using
animation-delay
. And if we use negative delays (e.g.animation-delay: -9s
) we can jump immediately to any mid-point in an animation loop. That’s a really useful performance trick. - All animation is controlled by a single Sass variable at the top of the CSS window –
$animation-time: 5s;
. Changing that number will alter the big readout number and the EKG speed. - It’s built for Chome and not widely tested but should work anywhere.
There are some limitations to a purely CSS approach, but I’m fairly happy with the overall effect. I’d need JS to improve the elements I don’t like.
Third Prize: PaulOB
We’ve been very lucky to have Paul as a longtime contributor, mentor and advisor to SitePoint users for well over a decade (possibly approaching two?). In this case, he sacrificed precious holiday time in the sun to produce a tasty SVG solution.
See the Pen Machine that goes Ping! by Paul O’Brien (@paulobrien) on CodePen.
Paul said:
It’s just an SVG for the graph and an animated linear gradient to provide the motion effect. If I had time I would draw it properly and make it responsive and not just repeat the same svg each time to make it look a little bit random.
Must get back to the swimming pool now :)
Paul, we salute you, sir!
(Also, we’ll work out which SitePoint t-shirt, can holder or assorted SitePoint shwag we can send you.)
Equal First prize: nickwatton
While there weren’t a huge quantity of entries for this first code challenge, there was certainly no lack of quality with the top two entries. In fact, we thought the best 2 entries were so worthy of reward that we decided to award them both $200 Amazon Gift Card prizes.
Nickwatton’s entry was exactly the kind of thing I had in mind.
See the Pen Machine that goes Ping! by Nick Watton (@2Mogs) on CodePen.
As Nick explains, his solution:
Uses particle systems, because I like them.
Also, you can get a very cheap trail effect with canvas by filling the drawing context with a nearly transparent black, which makes the fading trail for my ‘ping’ line.
RAF keeps the whole animation running smoothly, with the heartbeat animations controlled with a recursive setTimeout(). I am using the setTimeout() to drive effects that are not per-frame, and it also means I can fire this at slightly random intervals, for an organic feel.
The heartBeat() method controls and lightly randomizes the pulse rate, seen in the heart and pulse line.
Nick’s JS and Canvas approach offers flexibility that is hard to match with other approaches. I can’t imagine how you could begin to mimic those particle effects with an SVG based method.
It’s also relatively easy to slightly randomize the speed of the animation. This is tough to fake without JS but really sells the plausibility of this animation.
Equal First prize: davidomarfch
David submitted his entry just before the cut-off time – and we’re so glad he made it. I have to admit this one had me grinning from ear to ear.
See the Pen
Machine that goes Ping! by David Omar Flores Chávez (@davidomarf)
on CodePen.
Firstly, David started out with some serious research into how a real ECG machine produces its output and built that knowledge into his animation. He’s also added ebbing and flowing blood pressure, temperature, oxygen saturation readings, and even hemoglobin count. This thing feels legit.
But David also added two killer X-factor elements.
- Audio: The classic machine ‘boop…boop…boop…’ adds so much drama when the heart rate increases.
- Interactivity: Beside some automatic ‘passive randomness’, David lets the user control the heart rate via the cursor position. Move to the far left to put your patient to sleep – move to the right to give your patient an adrenalin shot to the heart.
That finite control of the ECG speed makes this unit potentially genuinely useful in a movie/TV set scenario.
Like Nick’s solution, the ECG unit is written to canvas with JavaScript but David uses the P5.js library. I haven’t used P5 before, but with modules for drawing, animation, and audio, it seems like a great foundation to base a project like this on.
All up, a super impressive contribution.
Both thanks and congrats to David, Nick, and Paul. We’ll be in contact shortly.
What’s Next? Code Challenge #2: The CSS Battle
For our next challenge we’re partnering with our friends at CSSbattles.dev to sponsor Battle round #4 . There are 3 cash prizes and 20 SitePoint Premium Memberships to compete for over a three week period. Details to come in my next post.