Dragging elements to new positions independently using useSprings hook (+useDrag)

526 Views Asked by At

I was expecting each element to be updating independently, according to its latest positioning. However, moving an element after having moved another causes this unwanted behavior.

enter image description here

export function Ingredients({ ingredients }: IngredientsProps) {
  const [springs, api] = useSprings(ingredients.length, () => ({
    x: 0,
    y: 0,
  }));
  const bind = useDrag(({ args: [originalIndex], offset: [ox, oy] }) => {
    api.start((index) => {
      if (index !== originalIndex) return;

      return {
        x: ox,
        y: oy,
      };
    });
  });

  return (
    <>
      {springs.map(({ x, y }, i) => (
        <Ingredient key={ingredients[i].name} {...bind(i)} style={{ x, y }}>
          <img
            src={ingredients[i].src}
            alt={ingredients[i].name}
            draggable="false"
          ></img>
        </Ingredient>
      ))}
    </>
  );
}
1

There are 1 best solutions below

0
mjfneto On

Add the from property to the generic options:

export function Ingredients({ ingredients }: IngredientsProps) {
  const [springs, api] = useSprings(ingredients.length, () => ({
    x: 0,
    y: 0,
  }));
  const bind = useDrag(({ args: [originalIndex], offset: [ox, oy] }) => {
    api.start((index) => {
      if (index !== originalIndex) return;

      return {
        x: ox,
        y: oy,
      };
    });
  },
  {
    from: ({args: [originalIndex]}) => [
        springs[originalIndex].x.get(),
        springs[originalIndex].y.get()
    ],
  });

  return (
    <>
      {springs.map(({ x, y }, i) => (
        <Ingredient key={ingredients[i].name} {...bind(i)} style={{ x, y }}>
          <img
            src={ingredients[i].src}
            alt={ingredients[i].name}
            draggable="false"
          ></img>
        </Ingredient>
      ))}
    </>
  );
}