feat: add onAnimationFrame
lifecycle function
Just an idle thought I had while washing the dishes: should we have an onFrame
function? It would mean for example that this demo could be written like this:
$effect(() => {
const context = canvas.getContext('2d');
onFrame(() => {
paint(context, Date.now());
});
});
Alternatively we might want to have some sort of reactive time primitive (other than SvelteDate
) so that it could be used in deriveds too. Either way not wedded to it, just an idle thought that I thought was worth a PR
feat:
, fix:
, chore:
, or docs:
.packages/svelte/src
, add a changeset (npx changeset
).pnpm test
and lint the project with pnpm lint
Latest commit: 605a1f7
The changes in this PR will be included in the next version bump.
Name | Type |
---|---|
svelte | Minor |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
preview: https://svelte-dev-git-preview-svelte-14594-svelte.vercel.app/
this is an automated message
pnpm add https://pkg.pr.new/svelte@14594
pnpm add https://pkg.pr.new/svelte@14594
While it's nice, this does feel more of a thing for a utility or animation library. I wouldn't call it a lifecycle function at least and expose it through svelte/reactivity
instead.
Adjacent to #12441
Adjacent to #12441
I'm not sure it is at all. You definitely don't want to be updating the UI with Date.now()
every frame, that's going to put a lot of pressure on the runtime for no real benefit. I'd imagine you'd only want to update the time in relation to your UI requirements, such as every second or minute. This is very much a user-space problem rather than a problem that Svelte should even attempt to solve.
Renamed to onAnimationFrame
. I toyed with putting it in svelte/reactivity
or svelte/motion
but neither felt right — I think you can make the case that it is a lifecycle function, and it definitely feels more natural to me to have it alongside onMount
than elsewhere
FWIW I still think this is not worth adding as it's so easy to replicate in user land - so if this is about cleaning the PR queue I'd rather close it.
It's easy but annoying — you have to understand whether it's 'safe' to run the logic inside a requestAnimationFrame
callback the first time or if it'll result in flicker unless you call it directly inside the effect, in which case you might need to faff about with untrack
unless you're using onMount
(you don't need to, because it is safe, but that means you have to call requestAnimationFrame
twice — once inside the callback, once to kick it off). And of course it's a lot more verbose — this...
$effect(() => {
let frame = requestAnimationFrame(function next() {
frame = requestAnimationFrame(next);
do_stuff();
});
return () => {
cancelAnimationFrame(frame);
};
});
...versus this:
import { onAnimationFrame } from 'svelte';
onAnimationFrame(() => {
do_stuff();
});
The intent-to-noise ratio is much higher in the second case. It's something I've wanted often enough that I do think its presence is justified, it's not just about cleaning the PR queue.
I'm not saying it doesn't have any value, but not that it deserves to be in the same place as things like "real" life cycle hooks or other important stuff under the svelte
import space. It feels like something that can be put into a 3rd party lib like runed
I'm not saying it doesn't have any value, but not that it deserves to be in the same place as things like "real" life cycle hooks or other important stuff under the
svelte
import space. It feels like something that can be put into a 3rd party lib likeruned
We have something similar in runed :) https://www.runed.dev/docs/utilities/animation-frames