如何使用 React 添加 Konva 组件?

How to add a Konva component using React?

我对 React 比较陌生,在尝试集成时遇到了问题 KonvaJS into React. I'm trying to follow the first example shown in the Konva Overview:

// first we need to create a stage
var stage = new Konva.Stage({
  container: 'container',   // id of container <div>
  width: 500,
  height: 500
});

// then create layer
var layer = new Konva.Layer();

// create our shape
var circle = new Konva.Circle({
  x: stage.width() / 2,
  y: stage.height() / 2,
  radius: 70,
  fill: 'red',
  stroke: 'black',
  strokeWidth: 4
});

// add the shape to the layer
layer.add(circle);

// add the layer to the stage
stage.add(layer);

// draw the image
layer.draw();

所以我创建了自己的文件 KonvaDrawer.js 封装了上面的代码:

import Konva from 'konva';

function KonvaDrawer() {
    // first we need to create a stage
    var stage = new Konva.Stage({
        container: 'container',   // id of container <div>
        width: 500,
        height: 500
    });
    
    // then create layer
    var layer = new Konva.Layer();
    
    // create our shape
    var circle = new Konva.Circle({
        x: stage.width() / 2,
        y: stage.height() / 2,
        radius: 70,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4
    });
    
    // add the shape to the layer
    layer.add(circle);
    
    // add the layer to the stage
    stage.add(layer);
    
    // draw the image
    layer.draw();
}

export default KonvaDrawer;

然后在我的 App.js 中,我创建了带有 id="container"div,因为上面的代码提到它需要有一个带有该 ID 的 div(或者就是这样我明白了)

import React from 'react';
import './App.css';

function App() {
  return (
    <div id="container"></div>
  );
}

export default App;

最后是我调用 KonvaDrawer 函数的 index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import KonvaDrawer from './KonvaDrawer';

ReactDOM.render(
  <React.StrictMode>
    <App />
    {KonvaDrawer()}
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
serviceWorker.unregister();

但是当我这样做时 npm start 我得到这个错误:

Stage.js:105 Uncaught Can not find container in document with id container

所以,我不确定为什么会这样,

我在网上找到的所有示例都是这样创建 Konva 组件的:

<Stage>
    <Layers>
        <Shapes>

例如 here and here 但我很好奇我尝试这样做的方式是否可行以及为什么它目前不起作用。

所以,如果我按照上面的结构做这个:

import React from 'react';
import './App.css';
import {Stage, Layer, Circle} from 'react-konva';

function App() {
  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <Circle x={window.innerWidth / 2} 
                y={window.innerHeight / 2} 
                radius={70}
                fill={'red'}
                stroke={'black'}
                strokeWidth={4}
        />
      </Layer>
    </Stage>
  );
}

export default App;

它正确地显示了一个红色圆圈,但是如果我想用 for 循环自动创建一些东西的层,或者用 Javascript 创建元素,那我该怎么做呢?

你的KonvaDrawer只是一个直接创建Konva节点的函数。它不能用作 React 组件 (https://reactjs.org/tutorial/tutorial.html#overview)

所以react组件不会直接创建元素(比如Konva节点或者DOM元素)。它们只是定义页面(或 canvas 元素)在结尾处的外观。

如果您想使用 for-loop 或其他方式创建元素,您只需定义应用程序的“状态”并从该状态生成组件。

const App = () => {
  const [circle, setCircles] = React.useState([{x: 10, y: 10}, {x: 100, y: 100}]);

  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        {circles.map(circle => (
          <Circle x={circle.x} 
                y={circle.y} 
                radius={70}
                fill={'red'}
                stroke={'black'}
                strokeWidth={4}
          />
        ))}
      </Layer>
    </Stage>
  );
}