0

I'm using react-konva and I need to be able to drag multiple images at once (not using mutliselect). It appears that Konva handles this by using Groups or Containers.

I looked at the TypeScript files and:

export declare class Group extends Container<Group | Shape> {
    _validateAdd(child: Node): void;
}
export interface ContainerConfig extends NodeConfig {
    clearBeforeDraw?: boolean;
    clipFunc?: (ctx: CanvasRenderingContext2D) => void;
    clipX?: number;
    clipY?: number;
    clipWidth?: number;
    clipHeight?: number;
}
export declare abstract class Container<ChildType extends Node> extends Node<ContainerConfig> {
export declare class Image extends Shape<ImageConfig> {

It would seem the Image is an instance of Shape and should therefore be placeable in a Group, but I just can't get it to work.

I tried doing:

<Group height={<SOME NUMBER>} width={<SOME NUMBER>} draggable>
   {obj.map((obj2: any, idx: number) => {
      return (
        <Image
          X={<SOME NUMBER>}
          Y={<SOME NUMBER>}
          key={idx}
          scale={<SOME NUMBER>}
          image=<SOME IMAGE CONFIG>}
          draggable
        />
      )
   })}
</Group>

I tried looking for example by the vanilla API, but couldn't find any. It shows that Group should be able to contain Shape api

Group constructor. Groups are used to contain shapes or other groups.

I was wondering if anyone has any suggestions on leveraging provided Konva code to accomplish creating a draggable group of images or perhaps an alternative approach I'm not considering.

Dor-Ron
  • 1,787
  • 3
  • 15
  • 27
  • Adding the images to a group and dragging the group works in plain JS - see https://konvajs.org/docs/drag_and_drop/Drag_a_Group.html. You could also associate the images in your own collection and move them sympathetically with the one that is dragged. Also you might want to consider using a transformer with the rotate and sizing nodes switched off. In which case this question might be of use....https://stackoverflow.com/questions/62947885/what-is-the-best-way-to-drag-a-transformer-by-dragging-from-empty-areas-in-konva. Sorry not a react pro. – Vanquished Wombat Sep 18 '20 at 14:37

1 Answers1

1

Your attempt looks fine to me. In Konva a layer may have groups and shapes inside. Any group may have other groups or shapes inside. The image is just a shape.

There is a working demo for you:

const URLImage = ({ url, ...rest }) => {
  const [image] = useImage(url);
  return <Image image={image} {...rest} />;
};

class App extends Component {
  render() {
    const images = [
      "https://konvajs.org/assets/lion.png",
      "https://konvajs.org/assets/yoda.jpg"
    ];
    return (
      <Stage width={window.innerWidth} height={window.innerHeight}>
        <Layer>
          <Group draggable>
            {images.map((url, i) => (
              <URLImage url={url} x={i * 120} key={i} />
            ))}
          </Group>
        </Layer>
      </Stage>
    );
  }
}

DEMO: https://codesandbox.io/s/recursing-bohr-vlcsw?file=/src/index.js

lavrton
  • 18,973
  • 4
  • 30
  • 63
  • thank you this helped, the issue was that both group and image were draggable, and therefore I think image drag event overwrote group drag event. Any suggestions on how to tackle that one? – Dor-Ron Sep 18 '20 at 21:04
  • What kind of drag do you expect with such a configuration? Konva start drag from most down node available for drag. – lavrton Sep 18 '20 at 21:46