Intersection Observer Issues

I'm working on a game and I want some elements to animate in when they become visible, so I'm using intersection observers. I came up with this solution, and it works perfectly on firefox, but it sometimes bugs out on chrome. Sometimes the elements don't appear, and the screens stays like on pic related. Here's the relevant code
//get_observer.ts
export default function get_observer(
element: HTMLElement,
set_isVisible: (isVisible: boolean) => void,
threshold: number,
toggle: boolean
) {
const observer = new IntersectionObserver(
(entries) => {
const target = entries[0];

if (target.isIntersecting) set_isVisible(true);
else if (toggle) set_isVisible(false);
},
{ threshold }
);

observer.observe(element);

return observer;
}
//get_observer.ts
export default function get_observer(
element: HTMLElement,
set_isVisible: (isVisible: boolean) => void,
threshold: number,
toggle: boolean
) {
const observer = new IntersectionObserver(
(entries) => {
const target = entries[0];

if (target.isIntersecting) set_isVisible(true);
else if (toggle) set_isVisible(false);
},
{ threshold }
);

observer.observe(element);

return observer;
}
//Component.tsx
import { createSignal, onCleanup } from "solid-js";
import get_observer from "../get_observer.ts";

export default function Cmp() {
const [isVisible, setIsVisible] = createSignal(false);
const [observer, setObserver] = createSignal();

function set_observer(element: HTMLElement) {
const observer = get_observer(element, setIsVisible, .5, false);

setObserver(observer);
}

onCleanup(() => observer()?.disconnect());

return (
<div ref={set_observer}>
<div
class="invisible"
classList={{ "anime-enter": isVisible() }}
>
</div>
</div>
);
}
//Component.tsx
import { createSignal, onCleanup } from "solid-js";
import get_observer from "../get_observer.ts";

export default function Cmp() {
const [isVisible, setIsVisible] = createSignal(false);
const [observer, setObserver] = createSignal();

function set_observer(element: HTMLElement) {
const observer = get_observer(element, setIsVisible, .5, false);

setObserver(observer);
}

onCleanup(() => observer()?.disconnect());

return (
<div ref={set_observer}>
<div
class="invisible"
classList={{ "anime-enter": isVisible() }}
>
</div>
</div>
);
}
/* styles.css */

.invisible {
transform: translate(-100px);
opacity: 0;
}

.anime-enter {
transform: translate(-100px);
opacity: 0;
animation: enter-anime .33s forwards;

@keyframes enter-anime {
from {
transform: translate(-100px);
opacity: 0;
}

to {
transform: translate(0);
opacity: 1;
}
}
}
/* styles.css */

.invisible {
transform: translate(-100px);
opacity: 0;
}

.anime-enter {
transform: translate(-100px);
opacity: 0;
animation: enter-anime .33s forwards;

@keyframes enter-anime {
from {
transform: translate(-100px);
opacity: 0;
}

to {
transform: translate(0);
opacity: 1;
}
}
}
I know there's a library, but since this is a learning project I'd like to do it from scratch to understand things better. repo: https://github.com/kxrn0/fem_hangman
GitHub
GitHub - kxrn0/fem_hangman
Contribute to kxrn0/fem_hangman development by creating an account on GitHub.
No description
4 Replies
bigmistqke 🌈
bigmistqke 🌈4mo ago
from just looking at ur code here: are you sure you want to disconnect() on each unmount/cleanup of that Cmp-component?
bigmistqke 🌈
bigmistqke 🌈4mo ago
if you could make a minimal repro on http://playground.solidjs.com i can have a deeper look, but i m too lazy to git clone
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
microsoft
microsoft4mo ago
removing onCleanup(() => observer()?.disconnect()); does seem to get rid of the bug
bigmistqke 🌈
bigmistqke 🌈4mo ago
I just looked again at ur code. It worked a bit differently then I initially thought: I thought you had 1 global intersection-observer and then used this set_observer to observer.observe(...) the element, but instead you are creating a new IntersectionObserver for each element. In that case you do want to remove the observer onCleanup I suppose and your code should work. Maybe it's due to the fact that with <div ref={set_observer}/> set_observer is also called during unmount (with value undefined)... idk 🤷‍♂️ i would have to run the code to be able to see that. I would personally go for 1 global IntersectionObserver and use observer.unobserve to unobserve the element during cleanup/unmount.
Want results from more Discord servers?
Add your server
More Posts
what write so as not to constantly write a redirect in every function in case of unauthorizeI don’t have a database on the solidstart server, I only work with third-party APIs. Where to store Solid doesn't re-render when update the same array in createSignalExpected behavior: Re-render inputs every time passwords array is updated even with the same value,For some reason <select> doesn't work correctlyhttps://playground.solidjs.com/anonymous/eedf65f3-e52b-49b0-a8b2-513465a75666 Here it is. When changCan someone tell me how to redirect the user on each API, if 401, that is, do not write the logic agCan someone tell me how to redirect the user on each API, if 401, that is, do not write the logic agHow to use web component in solidjsPlease ask solidjs how to solve the use of web component component editor ts reported error PropertyHow do I debug updatesI thought My app is working fine except I noticed a lag, which performance profile shows lots of unnHow to detect button holding in solid js?Does anyone know how to detect a button being holding for 2 seconds and are there any libraries or bVite internal server error expected "}" but found end of filesee screenshot, this is not the end of the file (not even close)How do I "curry" a function with props?I have a method "colorize" that receives two arguments: hue and shade. A component has a props.hue aMobX + SolidJS enableExternalSource untracked bug?I am evaluating using MobX with SolidJS and now that there is an `untrack` parameter to `enableExter