Show HN: Boing

(boing.greg.technology)

616 points | by gregsadetsky 14 hours ago ago

115 comments

  • junon 13 hours ago

    Love this. Had to cheat, naturally.

        setInterval(()=>{const canvas=document.getElementById('canvas');const startX=266;const startY=198;const rect=canvas.getBoundingClientRect();const startClientX=rect.left+startX;const startClientY=rect.top+startY;let endClientX,endClientY,distance;do{endClientX=Math.random()*window.innerWidth;endClientY=Math.random()*window.innerHeight;const dx=endClientX-startClientX;const dy=endClientY-startClientY;distance=Math.sqrt(dx*dx+dy*dy)}while(distance<25);const dispatchMouseEvent=(type,target,clientX,clientY)=>{const event=new MouseEvent(type,{view:window,bubbles:true,cancelable:true,clientX:clientX,clientY:clientY,screenX:clientX+window.screenX,screenY:clientY+window.screenY,buttons:type==='mouseup'?0:1,button:0});target.dispatchEvent(event)};dispatchMouseEvent('mousedown',canvas,startClientX,startClientY);setTimeout(()=>{dispatchMouseEvent('mousemove',window,endClientX,endClientY);setTimeout(()=>{dispatchMouseEvent('mouseup',window,endClientX,endClientY)},1);},1);},1);
    • InsomniacL 7 hours ago

      Waiting for somebody to write the code to recreate the Star Wars Imperial March: https://www.youtube.com/watch?v=-NDLlWtudpE

    • blensor 8 hours ago

      I don't think you need to move the mouse, you just need to click slightly offcenter while still bein inside the ball.

      • junon 5 hours ago

        I was looking at the source and it appeared there was special handling on the mousemove event. I also had to introduce timeouts, otherwise it wouldn't work (not entirely sure why). So was being safer since I didn't want this to become a time sink :D

    • Bewelge 7 hours ago

      Almost gave up getting this to work...

      (function () { function rateToDistance(rate) { const minR = 0.09; const maxR = 4.65; if (rate < minR) rate = minR; if (rate > maxR) rate = maxR; const t = (rate - minR) / (maxR - minR); return 400 * t; } function dispatchMouseEvent(type, target, clientX, clientY) { const event = new MouseEvent(type, { view: window, bubbles: true, cancelable: true, clientX, clientY, screenX: clientX + window.screenX, screenY: clientY + window.screenY, buttons: type === "mouseup" ? 0 : 1, button: 0, }); target.dispatchEvent(event); } const canvas = document.getElementById("canvas"); function triggerPull(distance) { const rect = canvas.getBoundingClientRect(); const startX = 266; const startY = 198; const startClientX = rect.left + startX; const startClientY = rect.top + startY; const endClientX = startClientX + distance; const endClientY = startClientY; return new Promise(resolve => { dispatchMouseEvent("mousedown", canvas, startClientX, startClientY); setTimeout(() => { dispatchMouseEvent("mousemove", window, endClientX, endClientY); setTimeout(() => { dispatchMouseEvent("mouseup", window, endClientX, endClientY); resolve(); }, 50); }, 50); }); } const semitones = 12; const notes = { G: Math.pow(4, -9 / semitones), A: Math.pow(4, -7 / semitones), B: Math.pow(4, -5 / semitones), C2: Math.pow(4, -4 / semitones), D2: Math.pow(4, -2 / semitones), E2: Math.pow(4, -0 / semitones), F2: Math.pow(4, 2 / semitones), G2: Math.pow(4, 4 / semitones), }; async function playWithPitch(rate) { const r = rateToDistance(rate); await triggerPull(r); } async function playScale() { const qrt = 200; const hlf = 400; const fll = 800; const pause = 15; const playNote = async (note, dur) => { await playWithPitch(note); await new Promise(res => setTimeout(res, dur)); }; const loop = async () => { await playNote(notes.C2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.D2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.G, hlf); await new Promise(res => setTimeout(res, pause)); await playNote(notes.D2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.E2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.G2, qrt); await playNote(notes.F2, qrt); await playNote(notes.E2, qrt); await new Promise(res => setTimeout(res, pause)); await playNote(notes.C2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.D2, fll); await new Promise(res => setTimeout(res, pause)); await playNote(notes.G, fll); await new Promise(res => setTimeout(res, pause)); await new Promise(res => setTimeout(res, pause)); await playNote(notes.G, qrt); await playNote(notes.G, qrt); await playNote(notes.A, qrt); await playNote(notes.C2, qrt); await new Promise(res => setTimeout(res, pause)); await playNote(notes.C2, qrt); await new Promise(res => setTimeout(res, pause)); }; await loop(); await loop(); await loop(); } playScale(); })();

    • jesse__ 12 hours ago

      take my upvote. That's hilarious

    • meesles 11 hours ago

      BoingBoingBoingBoingBoing

    • ngkw 11 hours ago

      I love this.

    • ivanjermakov 4 hours ago

          while true; do curl -X POST -Ss https://respected-accordion-31461.ondis.co/boing &; sleep 0.1; done
      • gregsadetsky 3 hours ago

        please don't, but I can't stop you. :-) thanks!

  • coffeecoders 11 hours ago

    Funny thing: this feels "realistic" because it’s not perfect physics. A perfectly simulated Hooke's law spring actually looks fake and too stiff. But if you let the animation wobble a bit more and slow down the damping, our brain reads it as weight and squishiness.

    It’s basically controlled sloppiness.

    • dataflow 8 hours ago

      > this feels "realistic" because it’s not perfect physics. A perfectly simulated Hooke's law spring

      Confused. Perfect physics means perfectly simulating reality, not perfectly simulating an unreal idealized formula. Are you saying Hooke's law doesn't feel realistic or are you saying a simulator for a realistic spring doesn't feel realistic?

      • luanmuniz 4 hours ago

        In reality, nothing is perfect. Materials are never 100% one material. Rustness is imperfection, the weight and material of the ball, and the place it's attached are also consideration points, how firmly it is attached, and with which material. A "perfect" simulation of the spring itself would have to consider all these variables, and they almost never do.

        • zamadatix 4 hours ago

          And even if you somehow included "everything" with the "perfect" equations, you'll end up with a lot of stuff which does not have a good closed form solution anyways and good luck getting that running (e.g. the dynamics around the air resistance/sound generation) via approximations both accurate enough that it looks better than "faking it" and fast enough that it's actually usable interactively.

          This leads to what GP was saying: many just cut things off at "Hooke's law simulates a spring, so I'll use that, but the rest is a bit too much to fit so I won't do it" but "Hooke's law simulates a spring but adding a bit of not-physics based fluff approximates all the rest" actually gives far superior results even though it doesn't only use perfect physics equations as the former did.

    • marginalia_nu an hour ago

      Hooke's law is what's not not perfect physics, but an idealized version of a spring. No real spring (that we'd recognize as a spring) actually obeys it perfectly, because there is damping and friction and a bunch of things that Hooke's law does not factor in.

      To get somewhat more realistic model of a spring, you a damping term, which turns it into an ODE[1].

      [1] https://en.wikipedia.org/wiki/Mass-spring-damper_model

    • skrebbel 8 hours ago

      Elasto Mania is a great game from decades ago (but still for sale!) that exploits this fact to a hilarious extent. You control a motor bike with excessively wobbly physics making all kinds of stunts possible (and necessary, to complete the levels) that are spectacular and surprising.

      https://elastomania.com/

      • apgwoz 2 hours ago

        Wait. Is Jelly Car basically a rethinking of this? I never managed to have the elasto games, but looking at the trailer, there’s a lot of similarities.

      • dom96 6 hours ago

        I remember playing this game when I was like 12 years old, good times

      • ngcazz 8 hours ago

        Also worth checking out, the FOSS clone X-Moto

      • finger 8 hours ago

        I spent thousands of hours on that game.. just too good :)

    • iamflimflam1 10 hours ago

      Same is true in a lot of old platformer games. Real physics feels horrible.

      • faeyanpiraat 6 hours ago

        Yeah, I really like the low gravity during my dreams

  • gnarlouse an hour ago

    @gregasadetsky: you should make it social… you know, like, just because. Like I want to be able to send my sister my latest “Boing,” and see what she thinks of my technique.

    • gregsadetsky 31 minutes ago

      how would that work haha. "send last boing"? and it's a permalink.... and it repeats the boing??? I'm... considering it! :-)

      • gnarlouse 25 minutes ago

        Think of it like the Bro App from “Silicon Valley”, just with the charm of a doorstop. ;D

  • mythz 8 hours ago

    This takes me back a few years when the first of my Uni friends had a baby, they spoiled him with so many toys that their lounge room was like an obstacle field where you had to be careful where to step, but despite all his toys the baby spent all his time while I was there playing with the door spring.

    There's something therapeutic about door springs, that you just have to stop and play with it.

  • foobarbecue 18 minutes ago

    It's broken! Now when I boing it, it goes totally wild instead of behaving as expected. Did somebody hack it?

    • gregsadetsky 12 minutes ago

      there are very specific starting points that do go wild - but it should mostly not show you those (and I should add some protection for it)

      try reloading again?

      • foobarbecue 10 minutes ago

        All points are going crazy...

  • Ylpertnodi 5 minutes ago

    Could you include a dark mode? Great fun.

  • analogears 4 hours ago

    This reminds me why simple single-purpose web toys used to be so satisfying. No account, no onboarding, no "upgrade to pro" - just a thing that does one thing well. The world counter is a nice touch without being gamified into oblivion..

  • dfex 12 hours ago

    Finally!

    Time to recreate the classic: https://www.youtube.com/shorts/pTgJaJYHIAs

  • alex440440 6 hours ago

    If you were Elon you would claim it's an early alpha of a world simulator that in a year will be able to perfectly predict weather and stock market.

  • reactordev 8 hours ago

    That’s got to be one of the most satisfying things ever. The real device was a darling invention and this is a faithful recreation of the experience of being in time out in the 80s.

  • jonplackett 9 hours ago

    Oh it needs a total boings by everyone counter!

    • gregsadetsky 8 hours ago

      alright, I implemented a world boing counter :-) thanks for the great idea

      • kentiko 7 hours ago

        Nice, could you share how you implemented it?

        • gregsadetsky 3 hours ago

          Flask + SQLite in WAL mode.

          In-memory ip address rate limiting.

          Hosted and deployed on a ~$20 EC2 server using the open source tool I've been working on, https://disco.cloud/

          We were at ~120 requests/second earlier and it took it on, no sweat.

      • doubleorseven 8 hours ago

        maybe also de-boing the boining now that it's calling the server. i think the js script pasted here will show you it's needed

        • gregsadetsky 8 hours ago

          there's rate limiting so the script posted in this thread actually mostly hits 429s :-) but yeah, great pointer

    • dmje 9 hours ago

      Total boing heatmap!

      • gregsadetsky 8 hours ago

        I considered it for a minute, but then I remembered https://xkcd.com/1138/ .. ha. but let me know if you have other thoughts about this

        • apgwoz 2 hours ago

          Heatmap based on coordinates of the start of the boing!

          • gregsadetsky 2 hours ago

            ahhhhhhhhhhhhhhhhhhh wow I'm dumb. working on it

            EDIT: done! deploying.

            wow ok that was a really good idea.

        • dmje 5 hours ago

          ha :-)

  • TheAceOfHearts 12 hours ago

    Any consideration on sharing the unminified code? I was a bit curious to read through the code and it seems like such a shame to keep it obfuscated. From a quick perusal, it seems like the bulk of the code comes from howler.js (a sound library), and the core functionality is conveniently implemented below the mobile template.

  • uriee 2 hours ago

    Man, slow MO + plot the vibration freq on the axis.

    • gregsadetsky 14 minutes ago

      added slomo mode! it's great, thank you!

  • modeless 13 hours ago

    I would love to see an accurately simulated version of this, à la https://www.engine-sim.parts/

  • aetherspawn 11 hours ago

    The sound is not physics based, the boing sound keeps going if you grab the head, likewise sometimes the sound ends before the vibration finishes.

    • gregsadetsky 9 hours ago

      Well spotted! I'd love a synthesized version - if anyone has pointers.

  • codeulike 8 hours ago

    It doesnt boing rotationally, only in a straight line. Like the spring isn't really there.

    If I bend it right round to one side so the spring is curved I expect it to bounce round to the other side.

    • gregsadetsky 8 hours ago

      you are right - just improved this and I think it looks a lot better (deploying now)

      thanks!

      • codeulike 4 hours ago

        The dream of agile exemplified

  • cons0le 11 hours ago

    Finally something I actually want to pay for!! Give us a premium tier with exclusive boingers plz

  • e1gen-v 5 hours ago

    If you manage to push it all the way down directly in the middle it boings forever

  • texuf 10 hours ago

    TIL I don't know how to “unmute” my device anymore. My new-ish iPhone doesn't have a physical switch on the side and I can’t find it in the settings in the pulldown menu.

    • gregsadetsky 9 hours ago

      Oh good point sorry. If you open the Control Center (drag down from the top left, typically), there should be a bell icon..?

      That, or Settings -> Sounds & Haptics -> Silent Mode ?

      • gmac 8 hours ago

        I just got an iPhone 17, and presumably because it inherited its Control Centre configuration from the 13 it replaces (which had a physical switch) the silent mode toggle was not present. Tap and hold in an empty space to edit the controls and add it in.

  • ethmarks 14 hours ago

    I noticed that the boing sound gets deeper and lower with smaller-magnitude boings. Is the boing audio generated procedurally/realistically in response to the physics of the boing, or is just playing a premade boing sound effect that's dynamically pitch shifted?

    • junon 13 hours ago

      The original is pretty low, it appears to be sped up. Check the network panel.

  • cr125rider 13 hours ago

    Oh random Flash apps, how I miss you

  • gnarlouse 11 hours ago

    Is this physics based audio?

    • gregsadetsky 3 hours ago

      It's not, unfortunately. I'd love to find a synthesized version of a boing sound. Perhaps some folks with modular experience could chime in?

    • zer0tonin 6 hours ago

      I don't think so

  • prodigycorp 14 hours ago

    i love this. it reminds me of simpler times when we’d have iphone apps/games that would explore a single mechanic and implement it really well.

  • egeres 8 hours ago

    Amazing to see software like this without sign-in requirements or paid subscriptions!

  • satvikpendem 14 hours ago

    Very fun and nostalgic. The head of the boinger doesn't seem to exactly follow the cursor/finger however, at least on mobile, it always arcs.

    • gregsadetsky 3 hours ago

      Are you seeing the small dotted lines when pulling very far? It's meant to show the applied tension

  • naich 8 hours ago

    I had to stop at 100 or I would have been there all day.

  • ____tom____ 13 hours ago

    There seems to be a minor bug. When I switch tabs and come back, sometimes the spring is moving. Some times a small amount, and other times it appears to be streched to the max, and extending off the top and bottom of the screen, until it calms down.

    Safari, Mac.

    • mg 13 hours ago

      I just wanted to write about a similar observation when using it in FireFox on Linux:

      When wiggle the spring, keep the mouse inside the white area until it is at rest, press CTRL+u to see the source code, move the mouse to close the source code tab and close it - for some magical reason the spring is moving again for a little bit.

    • gregsadetsky 9 hours ago

      Yes, good sleuthing, that was one of the last remaining things I wanted to fix before launching.

      Just fixed, should be live soon.

  • tdeck 5 hours ago

    I'm slightly ashamed of how many times I boinged this. Great work!

  • OuterVale 11 hours ago

    This is the natural thing to make with this tool: https://youtube.com/watch?v=5VGLPP70Xtw

  • qwertytyyuu 13 hours ago

    As a phone user, I hate you, I hate how good this is. That counter is just mocking me.

  • sam-cop-vimes 12 hours ago

    I wasn't hearing the sound initially so I thought it wasn't working in Firefox. Put the sound all the way up and boinged again. Made me jump out of my seat. Hilarious :-)

    • HelloUsername 10 hours ago

      I have no sound on ff ios, volume 100%

      • gregsadetsky 9 hours ago

        Make sure to unmute your device - either using the physical mute rocker on older iPhones, or by disabling Silent Mode (tap the bell in the Control Center)

        • HelloUsername 3 hours ago

          That already was the case; no sound

          • gregsadetsky 3 hours ago

            Just downloaded Firefox on iOS and tested it and sound works here - can you check this other site please: https://learningsynths.ableton.com/ ?

            There will also be no sound there if your phone is in Silence mode. However if Learning Synths works but not mine, then something else is happening.

            Thanks!

  • Quizzical4230 12 hours ago

    Love this! It's highly addictive. (No guilt)

  • abhinavsns 12 hours ago

    There seems to be a bug. If I catch it mid boing, the sound doesn't stop.

    • gregsadetsky 9 hours ago

      very good observation! just fixed and pushed

  • fHr 2 hours ago

    absolute peak, love it

  • nopurpose 10 hours ago

    How many before you stopped? I am at 37.

  • ramnik10 11 hours ago

    I liked it, would love to code it

  • bitcrshr 13 hours ago

    I needed this. Thank you.

  • rezmason 12 hours ago

    There goes my evening.

  • akho 10 hours ago

    when haptics

    • gregsadetsky 9 hours ago

      I would love to, but iOS support doesn't seem possible - there's a trick [0] to make a hacky haptic vibration in javascript, but it doesn't work with the kinds of events here of drag&release. And (lame excuse, but) I don't have an Android phone to test the haptics to make sure they're semi realistic.

      This might have to wait for the native app versions ha.

      [0] https://progressier.com/pwa-capabilities/vibration-api

  • thenthenthen 12 hours ago

    Can we add accelerometer support? :D

    • gregsadetsky 3 hours ago

      on iOS at least, that requires an additional permission, and it would take some work to get the feeling right on both iOS and Android

      but I agree - I have some other mono-site-ideas like these in mind, and I think that the accelerator could be very fun. thanks for the suggestion!

  • jesse__ 12 hours ago

    boingboingboing

  • brcmthrowaway 9 hours ago

    AI?

    • gregsadetsky 9 hours ago

      Yes! I've been toying with this project idea for a few ~months, trying out most of the models out there. The physics and the look of the spring would come out quite crazy looking, so I put it on the back burner.

      This is not an ad, there's no affiliate link... but the physics & drawing code were one shot by the recently released Gemini 3 Pro. It was pretty incredible to see. Additional tweaks & boing counter server by Claude Code.

  • 29athrowaway 12 hours ago

    I noticed that the sound changes depending on how you interact with it. Neat

  • johnwheeler 12 hours ago

    Most excellent.

  • xpe 5 hours ago

    Anyone want to commission an AI to make a sequel called Boing or Krill where you have to choose between boinging the spring or playing a game of snake (drawn as a line of krill)?

  • karanveer 13 hours ago

    so satisfying.

  • catapart 13 hours ago

    fantasitic