[HN Gopher] Show HN: Boing
       ___________________________________________________________________
        
       Show HN: Boing
        
       Author : gregsadetsky
       Score  : 687 points
       Date   : 2025-11-30 03:46 UTC (19 hours ago)
        
 (HTM) web link (boing.greg.technology)
 (TXT) w3m dump (boing.greg.technology)
        
       | satvikpendem wrote:
       | 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 wrote:
         | Are you seeing the small dotted lines when pulling very far?
         | It's meant to show the applied tension
        
           | satvikpendem wrote:
           | I see it now, I was using the Dark Reader extension which
           | covered it up, looks good now.
        
       | prodigycorp wrote:
       | 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.
        
       | ethmarks wrote:
       | 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 wrote:
         | The original is pretty low, it appears to be sped up. Check the
         | network panel.
        
       | catapart wrote:
       | fantasitic
        
       | junon wrote:
       | 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;d
       | o{endClientX=Math.random()*window.innerWidth;endClientY=Math.rand
       | om()*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:tr
       | ue,clientX:clientX,clientY:clientY,screenX:clientX+window.screenX
       | ,screenY:clientY+window.screenY,buttons:type==='mouseup'?0:1,butt
       | on:0});target.dispatchEvent(event)};dispatchMouseEvent('mousedown
       | ',canvas,startClientX,startClientY);setTimeout(()=>{dispatchMouse
       | Event('mousemove',window,endClientX,endClientY);setTimeout(()=>{d
       | ispatchMouseEvent('mouseup',window,endClientX,endClientY)},1);},1
       | );},1);
        
         | jesse__ wrote:
         | take my upvote. That's hilarious
        
         | ngkw wrote:
         | I love this.
        
         | meesles wrote:
         | BoingBoingBoingBoingBoing
        
         | blensor wrote:
         | I don't think you need to move the mouse, you just need to
         | click slightly offcenter while still bein inside the ball.
        
           | junon wrote:
           | 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
        
         | InsomniacL wrote:
         | Waiting for somebody to write the code to recreate the Star
         | Wars Imperial March:
         | https://www.youtube.com/watch?v=-NDLlWtudpE
        
           | port11 wrote:
           | Humanity could be busy with silly, amazing stuff like this,
           | but we playin'...
        
           | Bewelge wrote:
           | Only the first few notes
           | 
           | (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", canvas, endClientX,
           | endClientY); setTimeout(() => { dispatchMouseEvent("mouseup",
           | canvas, 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.E2, fll); await new Promise(res =>
           | setTimeout(res, pause)); await playNote(notes.E2, fll); await
           | new Promise(res => setTimeout(res, pause)); await
           | playNote(notes.E2, fll); await new Promise(res =>
           | setTimeout(res, pause)); await playNote(notes.C2, fll); await
           | new Promise(res => setTimeout(res, pause)); await
           | playNote(notes.G2, qrt); await playNote(notes.E2, fll); await
           | new Promise(res => setTimeout(res, pause)); await
           | playNote(notes.C2, fll); await new Promise(res =>
           | setTimeout(res, pause)); await playNote(notes.G2, qrt); await
           | playNote(notes.E2, fll); await new Promise(res =>
           | setTimeout(res, pause)); await new Promise(res =>
           | setTimeout(res, pause)); await new Promise(res =>
           | setTimeout(res, pause)); }; await loop(); await loop(); await
           | loop(); } playScale(); })();
        
         | Bewelge wrote:
         | 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(); })();
        
         | ivanjermakov wrote:
         | while true; do curl -X POST -Ss https://respected-
         | accordion-31461.ondis.co/boing &; sleep 0.1; done
        
           | gregsadetsky wrote:
           | please don't, but I can't stop you. :-) thanks!
        
           | junon wrote:
           | When I wrote this there wasn't a leaderboard, and that wasn't
           | the point of the cheat anyway. Was only later I noticed the
           | network requests starting to hit after boinging.
        
         | ianberdin wrote:
         | https://boing.playcode.io
        
           | gregsadetsky wrote:
           | DAMN. can you try to bring in my physics code (err it'd have
           | to be 3d-ified, but still)? was this oneshotted-ish?
           | 
           | cheers, 3d is glorious.
        
       | cr125rider wrote:
       | Oh random Flash apps, how I miss you
        
         | victorbuilds wrote:
         | Recreated a kids version on Codorex:
         | 
         | https://codorex.com/shared/Ko4qJfnIKEjxDwqN2NAGueqWxYJFiz1F
        
       | modeless wrote:
       | I would love to see an accurately simulated version of this, a la
       | https://www.engine-sim.parts/
        
       | karanveer wrote:
       | so satisfying.
        
       | ____tom____ wrote:
       | 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 wrote:
         | 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 wrote:
         | Yes, good sleuthing, that was one of the last remaining things
         | I wanted to fix before launching.
         | 
         | Just fixed, should be live soon.
        
       | qwertytyyuu wrote:
       | As a phone user, I hate you, I hate how good this is. That
       | counter is just mocking me.
        
       | bitcrshr wrote:
       | I needed this. Thank you.
        
       | johnwheeler wrote:
       | Most excellent.
        
       | TheAceOfHearts wrote:
       | 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.
        
         | sixtyj wrote:
         | Online unminifier doesn't work? E.g. https://www.unminify2.com/
        
         | coffeecoders wrote:
         | Looks like a simple exponential drag/sprint-return simulation
         | using requestAnimationFrame.
         | 
         | Here is AI's implementation. https://jsfiddle.net/z0or7d2y/1/
        
           | lionkor wrote:
           | If they wanted an AI answer, surely they would have asked AI
        
         | gregsadetsky wrote:
         | Of course! https://github.com/gregsadetsky/boing
        
           | mmabbq wrote:
           | Turns out I was curious too, so I tried to de-minify it
           | myself. Now I get to see how close I was.
           | 
           | https://pastebin.com/FKyz20LG
        
       | thenthenthen wrote:
       | Can we add accelerometer support? :D
        
         | gregsadetsky wrote:
         | 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!
        
       | Quizzical4230 wrote:
       | Love this! It's highly addictive. (No guilt)
        
       | dfex wrote:
       | Finally!
       | 
       | Time to recreate the classic:
       | https://www.youtube.com/shorts/pTgJaJYHIAs
        
         | mavamaarten wrote:
         | Heh. I expected it to be this one
         | https://youtube.com/shorts/ocvBI_vtJwA
        
         | mhall wrote:
         | Or this https://youtu.be/lQ6jZgMaZk4
        
       | 29athrowaway wrote:
       | I noticed that the sound changes depending on how you interact
       | with it. Neat
        
       | rezmason wrote:
       | There goes my evening.
        
       | abhinavsns wrote:
       | There seems to be a bug. If I catch it mid boing, the sound
       | doesn't stop.
        
         | gregsadetsky wrote:
         | very good observation! just fixed and pushed
        
       | jesse__ wrote:
       | boingboingboing
        
       | sam-cop-vimes wrote:
       | 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 wrote:
         | I have no sound on ff ios, volume 100%
        
           | gregsadetsky wrote:
           | 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 wrote:
             | That already was the case; no sound
        
               | gregsadetsky wrote:
               | 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!
        
               | HelloUsername wrote:
               | "Your browser does not support this site. Please try
               | using a recent version of Chrome, Firefox, Safari, Edge,
               | or Opera."
               | 
               | Probably because I have Lockdown mode enabled, and/or
               | NextDNS
        
               | gregsadetsky wrote:
               | I'm not showing that message (ie those words are not from
               | me) so yeah sorry - I'm not sure what's going on
        
       | cons0le wrote:
       | Finally something I actually want to pay for!! Give us a premium
       | tier with exclusive boingers plz
        
         | structuredPizza wrote:
         | A16z is already working on the ipo
        
       | gnarlouse wrote:
       | Is this physics based audio?
        
         | zer0tonin wrote:
         | I don't think so
        
         | gregsadetsky wrote:
         | 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?
        
           | gnarlouse wrote:
           | My best offering is the engine sim which may or may not have
           | a lib. https://github.com/ange-yaghi/engine-sim If nothing
           | else, it's a brilliant, novel oddity.
        
       | aetherspawn wrote:
       | 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 wrote:
         | Well spotted! I'd love a synthesized version - if anyone has
         | pointers.
        
           | pierrec wrote:
           | Having done a fair amount of audio physical modeling, I'll
           | just say a synthesized version that's both fast and realistic
           | would be possible but difficult. The difficulty is at least
           | "it would make an impressive presentation at DAFx [1]",
           | though I might be underestimating it, and it's more "you
           | could make it your master's thesis at CCRMA [2]"
           | 
           | Ideal springs are a common, simple element in this field, but
           | this kind of spring is very much not that.
           | 
           | You're probably better off improving the sample-based version
           | by fading out the audio when necessary and using different
           | samples based on the way it's triggered. If you have "ultra-
           | dry" samples (maybe taken with a contact mic), you can add a
           | convolution effect with a well-chosen impulse response, this
           | will allow you to sharply cut off or adjust the audio and
           | still have a natural-sounding tail.
           | 
           | [1] https://www.dafx.de/
           | 
           | [2] https://ccrma.stanford.edu/
        
             | gregsadetsky wrote:
             | I'm extremely grateful for this. My most deeply held secret
             | is that I wish I could do this for a living - digitally
             | modeling weird/beautiful objects/instruments and work on
             | that forever haha. (And maybe make pedals out of them, I
             | don't know)
             | 
             | If you don't mind humoring me (I'm quite the novice in this
             | field), if I automated the recording of "all" possible
             | positions for a spring (say I had a motor positioned in a
             | way that would let me pull the spring in any polar
             | direction), would that make modeling potentially easier?
             | 
             | There might be a "train an AI, here's 1000 recordings"
             | angle, but I'm not necessarily interested in/asking about
             | that.
             | 
             | Just strictly for modeling, would it help the R&D phase to
             | have a lot of high sample rate recordings? Thanks a lot!
             | 
             | P.S. Also, if you have a good intro to DSP class/book, I'd
             | love to hear it. I know about a few, but a recc is always
             | appreciated
        
               | pierrec wrote:
               | That's funny, I was trying to do other stuff after
               | posting my comment, but my brain kept working in the
               | background, against my will, looking for the best
               | approach to actually model this. Honestly, I was probably
               | being pessimistic about the difficulty of a synthesized
               | version, but I still think your current approach (don't
               | synthesize, use samples) is more reasonable and can be
               | made more responsive.
               | 
               | I don't think that recording a large number of starting
               | positions would help that much with creating a (non-ML)
               | model, and I doubt a high sample rate would provide much
               | useful information either. A more common approach would
               | be to try getting separate sounds for the _impulse_ and
               | the _resonant body_ , though they may be impossible to
               | really separate, and the actual model may end up more
               | complex than that.
               | 
               | You probably have a good starting point already with your
               | code for the animated model. I think the sound mostly
               | comes from the collision between coils (collisions not
               | visible in your animated model), and almost entirely from
               | the lowest couple of windings that are against the wall.
               | This is your impulse. The resonant body might be in 2
               | parts: the wall and the long end of the spring. Your
               | existing model can tell you when to trigger the impulses,
               | and how much force to put into them.
               | 
               | For resources, one of my favorite intros to DSP is the
               | one by Sean Luke:
               | https://cs.gmu.edu/~sean/book/synthesis/
               | 
               | I wrote my own intro to physical modeling, though it
               | focuses on different instruments:
               | https://www.osar.fr/notes/waveguides/
               | 
               | Julius O. Smith has an encyclopedic amount of content on
               | the topic, though it's often condensed into math that can
               | be hard to apply: https://ccrma.stanford.edu/~jos/
        
               | gregsadetsky wrote:
               | I'm deeply, extremely, super duper grateful for all of
               | this. Thanks a ton!
        
       | OuterVale wrote:
       | This is the natural thing to make with this tool:
       | https://youtube.com/watch?v=5VGLPP70Xtw
        
       | ramnik10 wrote:
       | I liked it, would love to code it
        
       | coffeecoders wrote:
       | 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.
        
         | iamflimflam1 wrote:
         | Same is true in a lot of old platformer games. Real physics
         | feels horrible.
        
           | faeyanpiraat wrote:
           | Yeah, I really like the low gravity during my dreams
        
         | dataflow wrote:
         | > 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 wrote:
           | 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 wrote:
             | 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.
        
           | stavros wrote:
           | I think they mean that "ideal" springs don't feel realistic
           | (because they aren't).
        
         | skrebbel wrote:
         | 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/
        
           | ngcazz wrote:
           | Also worth checking out, the FOSS clone X-Moto
        
           | finger wrote:
           | I spent thousands of hours on that game.. just too good :)
        
           | dom96 wrote:
           | I remember playing this game when I was like 12 years old,
           | good times
        
           | apgwoz wrote:
           | 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.
        
         | marginalia_nu wrote:
         | 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
        
         | SAI_Peregrinus wrote:
         | Hooke's law only accounts for the force the spring applies, not
         | the mass of the spring itself. Once you have to account for the
         | mass of the spring, how that mass distribution changes as the
         | string stretches & compresses, and how that alters the momentum
         | it quickly loses its simplicity. That's far too difficult to do
         | by hand, but it's what the real world does so I'd rather say
         | that Hooke's law is a first-order approximation of spring
         | force, not a perfect law for describing linear spring behavior.
        
       | nopurpose wrote:
       | How many before you stopped? I am at 37.
        
         | arbol wrote:
         | 230
        
         | ku1ik wrote:
         | 103. Was curious if there's any prize for hitting 100 :)
        
           | arbol wrote:
           | Same, I thought it might be like cookie clicker
        
           | ProllyInfamous wrote:
           | >prize for hitting 100 :)
           | 
           | https://www.decisionproblem.com/paperclips/
           | 
           | You can hate me and/or close the window at any point,
           | friend...
        
       | texuf wrote:
       | 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 wrote:
         | 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 wrote:
           | 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.
        
       | akho wrote:
       | when haptics
        
         | gregsadetsky wrote:
         | 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
        
       | jonplackett wrote:
       | Oh it needs a total boings by everyone counter!
        
         | dmje wrote:
         | Total boing heatmap!
        
           | gregsadetsky wrote:
           | 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
        
             | dmje wrote:
             | ha :-)
        
             | apgwoz wrote:
             | Heatmap based on coordinates of the start of the boing!
        
               | gregsadetsky wrote:
               | ahhhhhhhhhhhhhhhhhhh wow I'm dumb. working on it
               | 
               | EDIT: done! deploying.
               | 
               | wow ok that was a really good idea.
        
         | gregsadetsky wrote:
         | alright, I implemented a world boing counter :-) thanks for the
         | great idea
        
           | doubleorseven wrote:
           | 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 wrote:
             | there's rate limiting so the script posted in this thread
             | actually mostly hits 429s :-) but yeah, great pointer
        
           | kentiko wrote:
           | Nice, could you share how you implemented it?
        
             | gregsadetsky wrote:
             | 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.
        
       | brcmthrowaway wrote:
       | AI?
        
         | gregsadetsky wrote:
         | 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.
        
       | egeres wrote:
       | Amazing to see software like this without sign-in requirements or
       | paid subscriptions!
        
       | codeulike wrote:
       | 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 wrote:
         | you are right - just improved this and I think it looks a lot
         | better (deploying now)
         | 
         | thanks!
        
           | codeulike wrote:
           | The dream of agile exemplified
        
       | mythz wrote:
       | 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.
        
       | naich wrote:
       | I had to stop at 100 or I would have been there all day.
        
       | reactordev wrote:
       | 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.
        
       | alex440440 wrote:
       | 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.
        
       | tdeck wrote:
       | I'm slightly ashamed of how many times I boinged this. Great
       | work!
        
       | e1gen-v wrote:
       | If you manage to push it all the way down directly in the middle
       | it boings forever
        
       | xpe wrote:
       | 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)?
        
       | analogears wrote:
       | 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..
        
       | uriee wrote:
       | Man, slow MO + plot the vibration freq on the axis.
        
         | gregsadetsky wrote:
         | added slomo mode! it's great, thank you!
        
       | fHr wrote:
       | absolute peak, love it
        
       | gnarlouse wrote:
       | @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 wrote:
         | how would that work haha. "send last boing"? and it's a
         | permalink.... and it repeats the boing??? I'm... considering
         | it! :-)
        
           | gnarlouse wrote:
           | Think of it like the Bro App from "Silicon Valley", just with
           | the charm of a doorstop. ;D
        
       | foobarbecue wrote:
       | It's broken! Now when I boing it, it goes totally wild instead of
       | behaving as expected. Did somebody hack it?
        
         | gregsadetsky wrote:
         | 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 wrote:
           | All points are going crazy...
        
           | foobarbecue wrote:
           | https://github.com/gregsadetsky/boing/issues/1
        
             | gregsadetsky wrote:
             | fixed!
        
       | Ylpertnodi wrote:
       | Could you include a dark mode? Great fun.
        
         | gregsadetsky wrote:
         | just did! thank you
        
       | ianberdin wrote:
       | Challenge accepted: https://boing.playcode.io.
       | 
       | three.js, audio generating.
        
         | ianberdin wrote:
         | Source code: https://playcode.io/boing
        
       | mrlonglong wrote:
       | Going to give this to a cat to play with, see if he enjoys it
        
       ___________________________________________________________________
       (page generated 2025-11-30 23:00 UTC)