blanchon's picture
Mostly UI Update
18b0fa5
<script lang="ts">
import { T } from "@threlte/core";
import { TransformControls, interactivity } from "@threlte/extras";
import type { Snippet } from "svelte";
import { Spring } from "svelte/motion";
import { useCursor } from "@threlte/extras";
interface Props {
content: Snippet<[{ isHovered: boolean; isSelected: boolean }]>; // renderable
onClick?: () => void;
}
let { content, onClick }: Props = $props();
interactivity();
const scale = new Spring(1);
// Hover state
let isHovered = $state(false);
let isSelected = $state(false);
let isHighlighted = $derived(isHovered || isSelected);
$effect(() => {
// If isHighlighted is true, set the color to hoverColor and opacity to hoverOpacity
if (isHighlighted) {
scale.target = 1.05;
} else {
scale.target = 1;
}
});
// Handle keyboard events for deselection
$effect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape" && isSelected) {
isSelected = false;
}
};
if (isSelected) {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}
});
const { onPointerEnter, onPointerLeave } = useCursor();
</script>
<T.Group
onclick={() => {
isSelected = true;
if (onClick) {
onClick();
}
}}
onpointerenter={() => {
onPointerEnter();
isHovered = true;
}}
onpointerleave={() => {
onPointerLeave();
isHovered = false;
}}
scale={scale.current}
>
{#snippet children({ ref })}
{@render content({ isHovered, isSelected })}
{/snippet}
</T.Group>
<!-- From https://github.com/brean/urdf-viewer -->