-
-
Notifications
You must be signed in to change notification settings - Fork 150
Open
Description
Hi @postspectacular ,
I'm experimenting a bit with rdom
and I slightly modified the example from rdom-svg-nodes to change the color of the currently selected circle but I'm having different behaviors (commented in the following code sample) that I don't quite understand:
import { defAtom } from "@thi.ng/atom";
import { svg } from "@thi.ng/hiccup-svg";
import { $compile, $klist } from "@thi.ng/rdom";
import { fromAtom } from "@thi.ng/rstream";
import { repeatedly } from "@thi.ng/transducers";
import { random2, type Vec } from "@thi.ng/vectors";
const WIDTH = 600;
const NUM = 4;
const R = 20;
// define atom of NUM random points
const db = defAtom({
clicked: -1,
pts: [...repeatedly(() => random2([], R, WIDTH - R), NUM)]
});
// reactive subscription for atom changes
const $db = fromAtom(db);
$compile([
'div',
{},
svg(
{
width: WIDTH,
height: WIDTH,
viewBox: `0 0 ${WIDTH} ${WIDTH}`,
onmousemove: (e: MouseEvent) => {
const clicked = db.deref().clicked
clicked !== -1 && db.resetIn(['pts', clicked], [e.clientX, e.clientY])
},
onmouseup: () => db.resetIn(['clicked'], -1),
ondblclick: (e: MouseEvent) =>
db.swap((state) => ({
...state,
pts: [...state.pts, [e.clientX, e.clientY]]
})),
},
$klist(
$db.map(({ clicked, pts }): [number, number, Vec][] => pts.map((p, i) => [clicked, i, p])),
"g",
{
fill: 'white',
stroke: 'black'
},
([_clicked, i, p]) => [
"circle",
{
r: R,
cx: p[0],
cy: p[1],
onmousedown: (e: MouseEvent) => {
db.resetIn(['clicked'], i)
db.resetIn(['pts', i], [e.clientX, e.clientY]);
},
// fill: clicked === i ? 'grey' : 'white' // -> the circle will stay grey after the first click
fill: $db.map(({ clicked }) => clicked === i ? 'grey' : 'white') // -> correct solution
}
],
([clicked, i, p]) => {
const fill = clicked === i ? 'grey' : 'white'
// return `${p}-${i}-${fill}` // -> the circle will be duplicated on click
return `${p}-${i}` // -> correct solution
}
),
)
]).mount(document.getElementById("app")!);
- The selected circle will stay grey even after a mouse release but I was expecting
clicked
to be updated automatically because it's coming from$db.map(...)
(just like the circle position is automatically updated fromp
):
fill: clicked === i ? 'grey' : 'white'
- The
$klist
doc says that "Like a hash, the key value MUST represent an item's current value such that if the value changes, so does the key." So I thought that I needed to make thefill
color part of the key but it will actually duplicate the circle:
return `${p}-${i}-${fill}`
Can you help me understand my mistakes?
Thank you in advance 😄
Metadata
Metadata
Assignees
Labels
No labels