admin管理员组文章数量:1122846
When modifying the height of a sticky header based on a threshold
for the yScroll
position, the animation can loop infinitely if scrolling is stopped close to the threshold, as the shrinking header itself reduces the value of yScroll
and thereby triggers it to grow again (and so on). I fixed the problem by triggering the animation only if the threshold was crossed including a buffer value.
While the code below works fine, I could not find a way to use $derived
instead of $effect
. Is this problem solvable using $derived
? Am I approaching the issue correctly?
<script lang="ts">
let yScroll = $state(0);
let threshold = 50;
let buffer = 40;
let isShrunk = $state(false);
$effect(() => {
if (yScroll >= threshold + buffer) {
isShrunk = true;
} else if (yScroll <= threshold - buffer) {
isShrunk = false;
}
});
</script>
<svelte:window bind:scrollY={yScroll} />
<header class="transition-all duration-500 {isShrunk ? 'h-16' : 'h-32'}">Header</header>
When modifying the height of a sticky header based on a threshold
for the yScroll
position, the animation can loop infinitely if scrolling is stopped close to the threshold, as the shrinking header itself reduces the value of yScroll
and thereby triggers it to grow again (and so on). I fixed the problem by triggering the animation only if the threshold was crossed including a buffer value.
While the code below works fine, I could not find a way to use $derived
instead of $effect
. Is this problem solvable using $derived
? Am I approaching the issue correctly?
<script lang="ts">
let yScroll = $state(0);
let threshold = 50;
let buffer = 40;
let isShrunk = $state(false);
$effect(() => {
if (yScroll >= threshold + buffer) {
isShrunk = true;
} else if (yScroll <= threshold - buffer) {
isShrunk = false;
}
});
</script>
<svelte:window bind:scrollY={yScroll} />
<header class="transition-all duration-500 {isShrunk ? 'h-16' : 'h-32'}">Header</header>
Share
Improve this question
edited Nov 25, 2024 at 22:16
Philipp
asked Nov 22, 2024 at 14:13
PhilippPhilipp
424 bronze badges
1 Answer
Reset to default 1This feels very event-based, so I don't think $derived
is the right tool.
If you describe what was happening before the logic change and after, this should become more apparent:
Before: "Header is shrunk while scroll offset is smaller than threshold"
After: "Header is shrunk when scroll offset crosses upper boundary and expanded when scroll offset crosses lower boundary.
The former describes a consistent condition, the latter two discrete events that have to be detected.
If you don't like the $effect
(which I would say is fine here), you could also use the scroll
event instead.
<svelte:window on:scroll={onScroll} />
function onScroll() {
if (window.scrollY >= threshold + buffer) {
isShrunk = true;
} else if (window.scrollY <= threshold - buffer) {
isShrunk = false;
}
}
Though the function might need to be called once, if the initial state is off.
本文标签: css animationsUse derived based on current state of selfStack Overflow
版权声明:本文标题:css animations - Use $derived based on current state of self - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303224a1931810.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论