admin管理员组

文章数量:1289525

Using Konva (konva-react), i render line using this component:

  const renderLine = (pathProps: CanvasPath | ActivePath, key?: number) => (
    <Line
      key={key}
      points={pathProps.points}
      stroke={pathProps.tool === "eraser" ? ERASER_COLOR : STROKE_COLOR}
      strokeWidth={pathProps.strokeWidth}
      tension={0.5}
      lineCap="round"
      globalCompositeOperation={
        pathProps.tool === "eraser" ? "destination-out" : "source-over"
      }
    />
  );

and here's my mouseEvent:


const handleMouseMove = useCallback(
    (e: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
      if (!activePath?.isDrawing) return;

      const pos = e.target.getStage()?.getPointerPosition();
      if (!pos || !isPointInImage(pos.x, pos.y)) return;

      setActivePath({
        ...activePath,
        points: [...activePath.points, pos.x, pos.y],
      });
    },
    [activePath, isPointInImage]
  );

  const handleMouseUp = useCallback(() => {
    if (!activePath) return;

    const newPath: CanvasPath = {
      tool: activePath.tool,
      points: activePath.points,
      strokeWidth: activePath.strokeWidth,
    };

    setPaths(newPaths);
    setActivePath(null);
  }, [activePath, paths]);

nb: the set function is react state

I'd like, on mouse up, it'll be a single shape (or at least shapes in the same layer) that convert the width of the stroke into custom shape, like both the 'x' and the 'i'. Is it possible? Because, my goal is:

  • to create shape that can be subtracted/cut by another shape to erase.
  • to make opacity even across the shapes in single layer, so, it'll not become overlapping.

If it's in adobe illustrator the behavior is similar to expand to shape. So, It'll take the line, convert it to a shape alongside its stroke width and it will no longer be editable as a line.

Using Konva (konva-react), i render line using this component:

  const renderLine = (pathProps: CanvasPath | ActivePath, key?: number) => (
    <Line
      key={key}
      points={pathProps.points}
      stroke={pathProps.tool === "eraser" ? ERASER_COLOR : STROKE_COLOR}
      strokeWidth={pathProps.strokeWidth}
      tension={0.5}
      lineCap="round"
      globalCompositeOperation={
        pathProps.tool === "eraser" ? "destination-out" : "source-over"
      }
    />
  );

and here's my mouseEvent:


const handleMouseMove = useCallback(
    (e: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
      if (!activePath?.isDrawing) return;

      const pos = e.target.getStage()?.getPointerPosition();
      if (!pos || !isPointInImage(pos.x, pos.y)) return;

      setActivePath({
        ...activePath,
        points: [...activePath.points, pos.x, pos.y],
      });
    },
    [activePath, isPointInImage]
  );

  const handleMouseUp = useCallback(() => {
    if (!activePath) return;

    const newPath: CanvasPath = {
      tool: activePath.tool,
      points: activePath.points,
      strokeWidth: activePath.strokeWidth,
    };

    setPaths(newPaths);
    setActivePath(null);
  }, [activePath, paths]);

nb: the set function is react state

I'd like, on mouse up, it'll be a single shape (or at least shapes in the same layer) that convert the width of the stroke into custom shape, like both the 'x' and the 'i'. Is it possible? Because, my goal is:

  • to create shape that can be subtracted/cut by another shape to erase.
  • to make opacity even across the shapes in single layer, so, it'll not become overlapping.

If it's in adobe illustrator the behavior is similar to expand to shape. So, It'll take the line, convert it to a shape alongside its stroke width and it will no longer be editable as a line.

Share Improve this question edited Feb 25 at 1:47 Jastria Rahmat asked Feb 20 at 2:09 Jastria RahmatJastria Rahmat 9111 gold badge9 silver badges29 bronze badges 1
  • Come over to the Konva Discord channel and we can get better bandwidth, then we can come back and write up the answer. – Vanquished Wombat Commented Feb 24 at 21:55
Add a comment  | 

1 Answer 1

Reset to default 1

Assuming you take the same approach as adobe and make some button to fire code for 'expand to shape', you can make a custom shape to replace the Path shapes you have constructed.

A custom shape is a first-class shape in Konva, meaning it responds to all the usual events, z-index, etc, etc. See the Konva docs for information and examples.

The customshape.sceneFunc is where you code the drawing commands.

本文标签: reactjsIn Konvahow to convert line with certain width to shapeStack Overflow