1

我有Konva.Group几个节点,我设置了剪辑属性以限制看到的内容。我正在申请Konva.Transformer该组,我面临的问题是 Transformer 包含了整个组,甚至是未剪辑的部分。即使它功能齐全并且可以完成工作,这看起来也不是很好。有什么方法可以设置变压器的初始宽度和高度,使其仅包含被剪裁的部分?

这是应用剪辑和变换之前的组

在此处输入图像描述

这是应用剪辑和变换后的样子

在此处输入图像描述

import React, {useRef, useEffect} from 'react';
import { render } from 'react-dom';
import { Stage, Layer, Rect, Circle, Line, Group, Transformer } from 'react-konva';

const App = () => {
  const trRef = useRef(null)
  const grpRef = useRef(null)


  useEffect(()=>{
    const transformNode = trRef.current;
    transformNode.enabledAnchors(["top-left",
    "top-right",
    "bottom-left",
    "bottom-right"])
    transformNode.nodes([grpRef.current])
  },[trRef])

  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <Group ref={grpRef} clipX={0} clipY={0} clipWidth={200} clipHeight={200}>
        <Rect
          x={20}
          y={50}
          width={100}
          height={100}
          fill="red"
          shadowBlur={10}
        />
        <Circle x={200} y={100} radius={50} fill="green" />
        <Line
          x={20}
          y={200}
          points={[0, 0, 100, 0, 100, 100]}
          tension={0.5}
          closed
          stroke="black"
          fillLinearGradientStartPoint={{ x: -50, y: -50 }}
          fillLinearGradientEndPoint={{ x: 50, y: 50 }}
          fillLinearGradientColorStops={[0, 'red', 1, 'yellow']}
        />
        </Group>
        <Transformer rotateEnabled={false} ref={trRef} />
      </Layer>
    </Stage>
  );
};

render(<App />, document.getElementById('root'));
4

1 回答 1

2

这是 的默认行为,Konva.Transform无法更改。一种解决方法是在剪裁部分周围创建一个透明矩形,对其应用变换,然后将更改复制到组中。

import React, {useRef, useEffect} from 'react';
import { render } from 'react-dom';
import { Stage, Layer, Rect, Circle, Line, Group, Transformer } from 'react-konva';

const App = () => {
  const trRef = useRef(null)
  const grpRef = useRef(null)
  const rectRef = useRef(null)

  // To copy the transform matrix from the rectangle to the group
  function handleTransform(e){
    const shape1 = e.target;
    const transform = shape1.getTransform().copy();
    const attrs = transform.decompose();
    grpRef.current.setAttrs(attrs);
  }

  useEffect(()=>{
    const transformNode = trRef.current;
    transformNode.enabledAnchors(["top-left",
    "top-right",
    "bottom-left",
    "bottom-right"])
    transformNode.nodes([rectRef.current])
  },[trRef])

  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <Group draggable>
          {/* Transparent rectangle to which the transform is now applied to */}
          <Rect
            ref={rectRef}
            x={0}
            y={0}
            width={200}
            height={200}
            id="invisible-rect"
          />
        <Group ref={grpRef} clipX={0} clipY={0} clipWidth={200} clipHeight={200}>
        <Rect
          x={20}
          y={50}
          width={100}
          height={100}
          fill="red"
          shadowBlur={10}
        />
        <Circle x={200} y={100} radius={50} fill="green" />
        <Line
          x={20}
          y={200}
          points={[0, 0, 100, 0, 100, 100]}
          tension={0.5}
          closed
          stroke="black"
          fillLinearGradientStartPoint={{ x: -50, y: -50 }}
          fillLinearGradientEndPoint={{ x: 50, y: 50 }}
          fillLinearGradientColorStops={[0, 'red', 1, 'yellow']}
        />
        </Group>
        </Group>
        <Transformer onTransform={handleTransform} rotateEnabled={false} ref={trRef} />
      </Layer>
    </Stage>
  );
};

render(<App />, document.getElementById('root'));

这是上述代码的演示。感谢 Anton,这个精彩库的创建者提出了这个解决方案。

参考- Konva 形状变换分享很简单

于 2021-02-04T13:14:58.253 回答