News for hackers. Stuff that matters.
Re:Breaking down a ripple animation in JavaScript by netgusto on Thursday August 19, 2021 @04:02PM (#28238633)
Cool, thank you! For a smoother animation, you may want to replace the setInterval() with:

  const anim = () => {
    drawRipple();
    requestAnimationFrame(anim);
  }
  anim();
Re:Breaking down a ripple animation in JavaScript by bryanbraun on Friday August 20, 2021 @10:31PM (#28253587)
Agreed, just trying to keep the tutorial simple for now. My other web-animation/education project (https://sparkbox.github.io/bouncy-ball) uses requestAnimationFrame more heavily.

Now that I think of it, it might be worth adding an asterisk and footnote about requestAnimationFrame to the post.

Re:Breaking down a ripple animation in JavaScript by beebeepka on Thursday August 19, 2021 @05:32PM (#28239630)
Also, setTimeout is more reliable for loops and such. As a fallback to requestAnimationFrame

Edit: I wonder why was this downvoted. Is setTimeout not more reliable time wise than setInterval?

Re:Breaking down a ripple animation in JavaScript by franciscop on Thursday August 19, 2021 @07:41PM (#28240695)
Probably because requestAnimationFrame is much better than setTimeout, AND requestAnimationFrame is supported even by IE10 so there's absolutely no need for a fallback. Also no, setTimeout is not more reliable than setInterval in many situations.
Re:Breaking down a ripple animation in JavaScript by beebeepka on Friday August 20, 2021 @02:09PM (#28249396)
Did I not day FALLBACK? Oh, I did but I am getting downvoted and mansplained for pointing that out a simple fact.

RAF also stops executing when tab is inactive. Sometimes we don't want our loop halted and that's where setTimeout comes in as the better alternative to setInterval.

Re:Breaking down a ripple animation in JavaScript by franciscop on Friday August 20, 2021 @03:42PM (#28250524)
This is the perfect example of why it says not to ask why you were downvoted in the FAQ, and the last time I try to help. You literally asked, I just tried to give a plausible explanation. Instead you rant back, scream and insult those literally answering your question. Not the right behavior for HN.
Re:Breaking down a ripple animation in JavaScript by beebeepka on Friday August 20, 2021 @08:01PM (#28252756)
I provided a real world example that you haven't considered before.

Your condescending responses are hardly genuine attempts at finding a plausible explanation for me being downvoted by people who can't think that pointing out thing A is better than thing B even though thing C exists and is the correct approach most of the time.

Re:Breaking down a ripple animation in JavaScript by qweqwweqwe-90i on Thursday August 19, 2021 @09:07PM (#28241270)
No one should bother supporting IE now.
Re:Breaking down a ripple animation in JavaScript by forgotmypw17 on Thursday August 19, 2021 @10:17PM (#28241691)
I strongly disagree. If you can't be bothered to write resilient code, that's your choice, but don't speak for me on what I should and shouldn't support.
Re:Breaking down a ripple animation in JavaScript by tomxor on Friday August 20, 2021 @09:22AM (#28245612)
Supporting IE !== "writing resilient code"

If anything your code will be much worse for it and likely to contain more bugs.

Re:Breaking down a ripple animation in JavaScript by forgotmypw17 on Saturday August 21, 2021 @11:47PM (#28262695)
Your code could also just be simpler and not include bug-prone ways of writing.

For each browser you add support for, x more browsers and access limitations you've never even heard of also become supported.

Re:Breaking down a ripple animation in JavaScript by franciscop on Friday August 20, 2021 @11:26AM (#28247135)
At 2.3% in Japan, and a much higher percentage in some specific industries there like healthcare, some people probably might be bothered supporting IE. Not me or most people though:

https://twitter.com/FPresencia/status/1428359948182818836

Re:Breaking down a ripple animation in JavaScript by jsf01 on Thursday August 19, 2021 @10:13PM (#28241655)
Absolutely. setInterval with a very tight interval runs the risk that your code execution time eventually catches up with the interval duration itself. Using setTimeout and raf recursively avoid this problem, but they do add a bit of baggage themselves by growing the call stack via many many recursive calls.

Edit: looking into this some more, it seems like the recursive methods might not actually grow the call stack due to being asynchronous. Their only added baggage is the extra closure which would be negligible. Anyone know if this is actually the case?

Re:Breaking down a ripple animation in JavaScript by fenomas on Thursday August 19, 2021 @11:02PM (#28242021)
There's no recursion involved with RAF or looping with setTimeout. In either case the "anim" function doesn't invoke itself, it calls a scheduling function and passes itself as an argument.
Re:Breaking down a ripple animation in JavaScript by fenomas on Thursday August 19, 2021 @11:15PM (#28242122)
requestAnimationFrame is much better here. If you're just drawing into a canvas, there's no reason to do that every N milliseconds - you want to do it once per screen refresh, which is what RAF is for. There's also the added benefit that RAF won't fire when the document isn't visible, so you don't waste cycles drawing to a canvas that's in a background tab, etc.
Re:Breaking down a ripple animation in JavaScript by tomxor on Friday August 20, 2021 @09:31AM (#28245705)
> there's no reason to do that every N milliseconds

Usually if you want to do any kind of posteriori procedural animation i.e real-time physics, you need a constant interval, and RAF does not give you this...

RAF usually runs at 60FPS but it can drop to 30 or increase to 120 depending on the browser, hardware and power saving modes - Which means whatever you are running in that function can get called at drastically different intervals for different users.

In this case the animation is a priori, meaning we don't have to simulate intermediate steps, so it's possible to correct for this inside the RAF alone by using Date.now() as the time parameter for shifting the sine wave... however this is not always the case. And in those cases setInterval can be far simpler when timing is important, but if you want to continue using RAF ultimately you would need to decouple rendering from "physics" or any timing related code that cannot be calculated a priori, and run the latter at a constant interval.

Re:Breaking down a ripple animation in JavaScript by fenomas on Friday August 20, 2021 @10:17AM (#28246274)
I think a few topics are conflated here. The part of the code that draws pixels into a canvas (or tells webgl to draw) should always be called from RAF - there's never a reason to do that more often than the screen refreshes. And since TFA does basically nothing except set canvas pixels, RAF is clearly the thing to use.

OTOH whether you want your animation to advance in real time is a separate issue, regardless of whether the animation is interpolated. If you do want real-time animations, and you're using an interpolated physics engine or similar, there really aren't any good options besides decoupling the interpolation from the rendering. And if you've done that, then it doesn't matter much whether the interpolation is called from RAF or setInterval (personally I use both, so that physics ticks can happen between RAF events if the CPU load is heavy).

But as a footnote, setInterval definitely does not give you a "constant" interval. Besides the normal variance, browsers will throttle the events (e.g. if the document is in a background tab).

Re:Breaking down a ripple animation in JavaScript by tomxor on Friday August 20, 2021 @01:12PM (#28248557)
Nothing gives you a constant interval, but it attempts to unlike RAF.
[dead]
Re:Breaking down a ripple animation in JavaScript by fenomas on Friday August 20, 2021 @10:26PM (#28253550)
I understand that, but the answer is the same. setTimeout isn't needed as a fallback (since RAF is widely supported), and it's not better time-wise (since the code we're talking shouldn't run when the document isn't visible).

And to answer the edit, setTimeout is not more reliable than setInterval. They both fire from the same event loop, so timing-wise they're identical (apart from one recurring and the other not).

Re:Breaking down a ripple animation in JavaScript by beebeepka on Saturday August 21, 2021 @03:58AM (#28255100)
I see. You are downvoting me because you think RAF is only useful for drawing graphics in the active tab, and nothing else.

setTimeout is absolutely more reliable than setInterval. Maybe try writing a scheduler/task runner and try for yourself before coming down on people.

Re:Breaking down a ripple animation in JavaScript by fenomas on Saturday August 21, 2021 @04:46AM (#28255328)
(a) I didn't downvote you.

(b) setInterval and setTimeout fire off the same event loop; they can only occur at the same fixed times. Why do you think one is more reliable? Just repeating that it's the case doesn't convey any information.

(c) I've written various schedulers; the most recent one is `micro-game-shell` on github if you're interested.

Re:Breaking down a ripple animation in JavaScript by beebeepka on Saturday August 21, 2021 @10:23AM (#28257239)
b) I've observed different time deltas between the two on embedded and standard PC hardware. That's why I think there's a difference. Also, their behaviour has changed over the last few years, making them extremely unreliable as the user changes tabs
Re:Breaking down a ripple animation in JavaScript by tomxor on Thursday August 19, 2021 @06:25PM (#28240127)
Faster 125 FPS, 165B version

  <canvas id=c><svg onload=setInterval("for(c.width=64,i=4096;i--;)c.getContext('2d').fillRect(X=i&63,Y=i/64|0,1,Math.sin(Math.hypot(X-32,Y-32)/2-++t/4e4)/4+.5)",t=8)>
Re:Breaking down a ripple animation in JavaScript by kroltan on Thursday August 19, 2021 @04:00PM (#28238622)
A plea to anyone who wants to do that, I would highly recommend running that kind of thing on the GPU! Looping through all those pixels every frame is ought to hog a lot of UI thread time otherwise, especially with big resolutions!
Re:Breaking down a ripple animation in JavaScript by zokier on Thursday August 19, 2021 @05:03PM (#28239336)
very basic shadertoy shader in the spirit of the article:

    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        vec2 center = iMouse.xy/iResolution.xy;
        float aspect = iResolution.x/iResolution.y;
        vec2 uv = fragCoord/iResolution.xy;
        uv.x *= aspect;
        center.x *= aspect;
        float r = distance(uv, center);
        float h = (sin((r*50.0)-(iTime*2.0))+1.0)/2.0;
        h *= 1.0 - min(1.0, r);
        fragColor = vec4(h,h,h,1.0);
    }
Re:Breaking down a ripple animation in JavaScript by tomxor on Thursday August 19, 2021 @06:42PM (#28240274)
It's also not necessary to do such high resolutions to get smooth result with this animation due to the nature of the image. Interpolation is much faster based on a low res version, especially the hardware accelerated smooth interpolation built into the browser for canvas. My example in this thread is only 64x64 pixels but you can zoom in as much as you like and it remains fast and smooth.
Re:Breaking down a ripple animation in JavaScript by geuis on Thursday August 19, 2021 @09:09PM (#28241278)
Good follow up article would be an intro to shaders, where you take the work from pixel looping and move it to shaders.
Re:Breaking down a ripple animation in JavaScript by agys on Thursday August 19, 2021 @03:12PM (#28238024)
This is the basic building block for cool old-school plasma effects!

Quick GLSL tutorial: https://web.archive.org/web/20210119091116/http://www.bidoui...

Re:Breaking down a ripple animation in JavaScript by nayuki on Thursday August 19, 2021 @04:08PM (#28238700)

    let distance = hypotenuseLength(reIndexedX, reIndexedY);
    
    function hypotenuseLength(x, y) {
      return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
    }
The above can be replaced with:

    let distance = Math.hypot(reIndexedX, reIndexedY);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Re:Breaking down a ripple animation in JavaScript by wizzwizz4 on Thursday August 19, 2021 @04:16PM (#28238805)
It's a tutorial, so there's a benefit to writing out the separate function in the article, but given that it's “in JavaScript” I agree with your suggestion.
Re:Breaking down a ripple animation in JavaScript by bryanbraun on Friday August 20, 2021 @10:16PM (#28253483)
Haha, yeah I discovered this after I wrote it. Probably worth going back and updating.
Re:Breaking down a ripple animation in JavaScript by ktpsns on Thursday August 19, 2021 @04:32PM (#28238988)
Story time! When I was around 12 years old, I've tried so hard to understand the JavaScript code to render an analog clock within HTML. I did not learn yet about sine and cosine and it was really a miracle how the code could determine the positions of the clock elements.

First learning how to code, then learning the math was a hard way to do the interesting stuff with computers. The other way around is much more straight forward.

Re:Breaking down a ripple animation in JavaScript by atum47 on Thursday August 19, 2021 @04:41PM (#28239122)
You just described my whole career, haha. I learned JavaScript by inspecting other's people code. I remember this cool effect I saw on the website for the matrix (the movie), it blew my mind back then, now I know is just image replacement on the mouse hover. The effects was a bunch of out of air tvs and when you position the mouse the tv would show a channel
Re:Breaking down a ripple animation in JavaScript by memalign on Thursday August 19, 2021 @03:50PM (#28238494)
Desmos (the graphing calculator tool used by the author) is really great! One thing that’s inconvenient about it is not being able to copy/paste formulas in. I ended up making my own graphing calculator web app to make drawing with math easier: FormulaGraph[0].

In a similar vein to the ripple, here’s[1] the Batman Curve in FormulaGraph.

[0] https://memalign.github.io/m/formulagraph/index.html

[1] https://memalign.github.io/p/batman-curve.html

Re:Breaking down a ripple animation in JavaScript by __ryan__ on Thursday August 19, 2021 @02:48PM (#28237709)
> To animate the wave in JavaScript, we can use setInterval to repeatedly call our drawRipple() function, and pass in a timestamp to adjust the wave position.

You described generating a ripple still-frame then completely glossed over the “animation” part.

Re:Breaking down a ripple animation in JavaScript by agys on Thursday August 19, 2021 @03:10PM (#28237989)
While setInterval works, requestAnimationFrame(time) is probably better suited for animation purposes.
Re:Breaking down a ripple animation in JavaScript by bryanbraun on Saturday August 21, 2021 @11:38AM (#28257841)
That's a good callout. I just updated it to add more detail there.
Re:Breaking down a ripple animation in JavaScript by recursive on Thursday August 19, 2021 @02:40PM (#28237591)
If you're into this kind of stuff, you might like dwitter.net
Re:Breaking down a ripple animation in JavaScript by dcsan on Friday August 20, 2021 @06:15AM (#28244485)
That's a really cool site. Almost like demo scene in JS. Any other similar places?
Re:Breaking down a ripple animation in JavaScript by onion2k on Thursday August 19, 2021 @04:43PM (#28239137)
This is a naive, but very fun, implementation of a 2D signed distance field. It's the same principle that artists like iq use to make amazing shader animations.

https://www.iquilezles.org/www/articles/distfunctions/distfu...

Re:Breaking down a ripple animation in JavaScript by atum47 on Thursday August 19, 2021 @04:00PM (#28238613)
I once wrote something similar on a jsfiddle but can't find it now. Later in I found an article and a YouTube video that proposed a different approach to do ripples, which I followed:

https://github.com/victorqribeiro/rippleEffect

Re:Breaking down a ripple animation in JavaScript by rojobuffalo on Thursday August 19, 2021 @02:27PM (#28237435)
here's one that animates a CSS radial-gradient and centers it on the click location https://gist.github.com/rojobuffalo/3a4f108937ffcd318c70
Re:Breaking down a ripple animation in JavaScript by TeeWEE on Thursday August 19, 2021 @02:56PM (#28237802)
While its cool drawing this iteratively is not really something that scales well. Better to use the GPU which most devices have today.