весь текст очищается при попытке удалить выбранное слово или символ - PullRequest
0 голосов
/ 01 февраля 2019

Я использую ткань JS с реагированием для добавления текста на холст.Текст добавляется, но когда я пытаюсь удалить символ или выделенные слова, весь текст очищается.Я видел некоторые ресурсы по этому поводу, но я использую реагирование, поэтому мне было трудно решить эту проблему.Вот как я это сделал

class ImageBoard extends React.Component {
  constructor() {
    super();
    this.state = {
      selected: undefined
    };
  }

  handleDeleteKey = event => {
    if (event.keyCode === 46 || event.keyCode === 8) {
      event.preventDefault();
      if (this.state.selected !== undefined) {
        this.canvas.remove(this.state.selected);
        this.setState({ selected: undefined });
      }
    }
  };

  componentDidMount() {
    this.canvas = new fabric.Canvas("canvas");
    document.addEventListener("keydown", this.handleDeleteKey, false);
    this.canvas.on("object:selected", e =>
      this.setState({ selected: e.target })
    );
    this.canvas.on("selection:cleared", e =>
      this.setState({ selected: undefined })
    );
    this.canvas.setBackgroundColor(
      "rgba(255, 73, 64, 0.6)",
      this.canvas.renderAll.bind(this.canvas)
    );
  }

  componentDidUpdate(prevProps) {
    if (prevProps.images !== this.props.images) {
      this.setCanvasBackground(this.props.images, this.canvas);
    }
  }

  addText = () => {
    let text = new fabric.IText("Double click me to change the text!", {
      fontSize: 28,
      fontWeight: 600,
      left: 100,
      top: 100,
      fill: "black",
      width: 20,
      height: 20
    });
    this.canvas.add(text);
  };

  render() {
    return (
      <Wrapper>
        <Column width={80}>
          <canvas
            id="canvas"
            ref={el => (this.canvasEl = el)}
            width={580}
            height={400}
            className="z-depth-1"
          />
        </Column>
        <Filter
          addText={this.addText}
        />
      </Wrapper>
    );
  }
}

export default connect(mapStateToProps)(ImageBoard);

1 Ответ

0 голосов
/ 03 февраля 2019

Поскольку вы удаляете выделенный объект в обработчике ключа delete / backspace, не удивительно, что при попытке очистить текстовые символы с помощью delete / backspace весь текст удаляется,Проверка условия if (this.state.selected !== undefined) недостаточно, поскольку при входе в режим редактирования текста текстовый объект все еще выделяется.

Однако вы можете дополнительно проверить свойство IText isEditing, чтобы увидеть, находится ли выделенный объект также в режиме редактирования:

  handleDeleteKey = event => {
    if (event.keyCode === 46 || event.keyCode === 8) {
      if (this.state.selected !== undefined && !this.state.selected.isEditing) {
        event.preventDefault();
        this.canvas.remove(this.state.selected);
        this.setState({ selected: undefined });
      }
    }
  };

Вот рабочий фрагментпродемонстрировать:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selected: undefined
    };
  }

  handleDeleteKey = event => {
    
    if (event.keyCode === 46 || event.keyCode === 8) {
      if (this.state.selected !== undefined && !this.state.selected.isEditing) {
        event.preventDefault();
        this.canvas.remove(this.state.selected);
        this.setState({ selected: undefined });
      }
    }
  };

  componentDidMount() {
    this.canvas = new fabric.Canvas("canvas");
    document.addEventListener("keydown", this.handleDeleteKey, false);
    this.canvas.on("object:selected", e =>
      this.setState({ selected: e.target })
    );
    this.canvas.on("selection:cleared", e =>
      this.setState({ selected: undefined })
    );
    this.canvas.setBackgroundColor(
      "rgba(255, 73, 64, 0.6)",
      this.canvas.renderAll.bind(this.canvas)
    );
  }

  addText = () => {
    let text = new fabric.IText("Double click me to change the text!", {
      fontSize: 28,
      fontWeight: 600,
      left: 20,
      top: 20,
      fill: "black",
      width: 20,
      height: 20
    });
    this.canvas.add(text);
  };

  render() {
    return (
      <div>
        <canvas
          id="canvas"
          ref={el => (this.canvasEl = el)}
          width={400}
          height={170}
        />
        <button onClick={this.addText}>
          add
        </button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.6.0/fabric.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='app'></div>
...