Search code examples
konvajskonvakonvajs-reactjs

What is the best way to drag a transformer by dragging from empty areas in Konvajs?


I'm currently following this guide to select shapes in the stage and put them inside a Transformer. If possible, I'd like to drag an entire Transformer with all of its content without touching any of the shapes inside.

For example, I have two lines that are far from each other. Both of them are nodes inside a Transformer and can be dragged as long as I click one of those 2 lines. However, if I tried to drag from any of the empty area inside the Transformer nothing would happen (or the transformer would reset, depending on the code).

I'm thinking of adding a transparent Rect (this Rect will always have the same size as the Transformer) to the Transformer and then add any other shape that I want inside the Transformer. Since both the Rect and the Transformer have the same size, I could easily drag the entire Transformer from any "empty area" where my other shapes are not located.

I'm not sure if this is the correct/efficient way to do it. How should I tackle this issue to obtain the best outcome?


Solution

  • There is an experimental property shouldOverdrawWholeArea for Konva.Transformer. It is not in the docs yet.

    If you set it to true the whole transformer area will be available for drag.

    But if you have a transformer on top of other shapes, then shapes will be not listening for regular events (such as click, touchstart etc). Because the transformer rectangle will overdraw hit area of attached shapes. Even will start working as soon, as you remove such a transformer from them.

    const stage = new Konva.Stage({
      container: 'container',
      width: window.innerWidth - 20,
      height: window.innerHeight - 20
    });
    
    const layer = new Konva.Layer();
    stage.add(layer);
    
    const shape1 = new Konva.Circle({
      x: 70,
      y: 70,
      radius: 50,
      fill: 'green'
    });
    layer.add(shape1);
    
    const shape2 = shape1.clone({
       x: 190,
       y: 90
    })
    layer.add(shape2);
    
    const tr = new Konva.Transformer({
      nodes: [shape1, shape2],
      shouldOverdrawWholeArea: true
    });
    
    layer.add(tr);
    
    layer.draw();
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <div id="container"></div>