gpt4 book ai didi

javascript - 每次在 React 中更改状态时,有没有办法不重新加载部分 Canvas ?

转载 作者:行者123 更新时间:2023-11-29 23:40:25 25 4
gpt4 key购买 nike

我刚刚将 react-color 模块添加到这个 Canvas 页面。当用户选择一种颜色时,strokeStyle 会正确地更改为该颜色,但它也会重置整个 Canvas ,使其成为一张白纸。有什么办法可以改变这一点,只有颜色本身会改变但 Canvas 不会重置吗?我尝试添加 shouldComponentUpdate 但这只是为了让颜色根本没有改变。

import React from 'react';
import { Layer, Stage, Image } from 'react-konva';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { GithubPicker } from 'react-color';

class Canvas extends React.Component {
constructor(props) {
super(props);
this.canvasEvent = this.canvasEvent.bind(this);
this.props.socket.on('canvas_update', data => {
const idToUpdate = data.canvasId == 1 ? 'drawing2' : 'drawing1';
const node = document.createElement('p');
const textNode = document.createTextNode('test');
node.appendChild(textNode);
document.getElementById(idToUpdate).appendChild(node);
console.log(data.canvasJSON);
this.updateKonva(idToUpdate, data.canvasJSON);

//this.renderDisabledKonva(undefined, data.canvasJSON, data.canvasId);
});
this.state = {
background: '#fff',
};
}

canvasEvent(canvasJSON) {
this.props.socket.emit('canvas_event', { roomId: this.props.roomId, canvasJSON: canvasJSON, canvasId: this.props.canvasId }, () => {});
}

handleChangeComplete = (color) => {
this.setState({ background: color.hex });
};

renderTools() {
return (
<div className="tool">
Tool:
<select id="tool">
<option value="brush">Brush</option>
<option value="eraser">Eraser</option>
</select>
</div>
);
}

renderKonva(container) {
const that = this;
const width = 400; // window.innerWidth;
const height = 400; // window.innerHeight - 25;
// first we need Konva core things: stage and layer
const stage = new Konva.Stage({
container: `drawing${this.props.canvasId}`,
width: width,
height: height
});
const layer = new Konva.Layer({});
stage.add(layer);
// then we are going to draw into special canvas element
const canvas = document.createElement('canvas');
canvas.width = stage.width() / 1.5;
canvas.height = stage.height() / 1.5;
// created canvas we can add to layer as 'Konva.Image' element
let image = new Konva.Image({
image: canvas,
x: stage.width() / 6,
y: stage.height() / 6,
stroke: '#05AFF2',
shadowBlur: 5,
});
layer.add(image);
stage.draw();
// Now we need to get access to context element
const context = canvas.getContext('2d');
context.strokeStyle = this.state.background;
context.lineJoin = 'round';
context.lineWidth = 5;
let isPaint = false;
let lastPointerPosition;
let mode = 'brush';
// now we need to bind some events
// we need to start drawing on mousedown
// and stop drawing on mouseup
stage.on('contentMousedown.proto', () => {
isPaint = true;
lastPointerPosition = stage.getPointerPosition();
});
stage.on('contentMouseup.proto', () => {
isPaint = false;
});
// and core function - drawing
stage.on('contentMousemove.proto', () => {
if (!isPaint) {
return;
}
if (mode === 'brush') {
context.lineWidth = 5;
context.globalCompositeOperation = 'source-over';
}
if (mode === 'eraser') {
context.lineWidth = 15;
context.globalCompositeOperation = 'destination-out';
}
context.beginPath();
let localPos = {
x: lastPointerPosition.x - image.x(),
y: lastPointerPosition.y - image.y(),
};
context.moveTo(localPos.x, localPos.y);
const pos = stage.getPointerPosition();
localPos = {
x: pos.x - image.x(),
y: pos.y - image.y(),
};
context.lineTo(localPos.x, localPos.y);
context.closePath();
context.stroke();
lastPointerPosition = pos;
layer.draw();

const dataURL = stage.toDataURL();
// window.open(dataURL);
that.canvasEvent(dataURL);
// that.canvasEvent(stage.toJSON());
// console.log(layer);
});
const select = document.getElementById('tool');
select.addEventListener('change', () => {
mode = select.value;
});
}

render() {
return (
<div className="container">
{this.renderTools()}
<GithubPicker onChangeComplete={this.handleChangeComplete} color={this.state.background} />
<div id={'drawing' + this.props.canvasId} ref={ref => this.renderKonva(ref)} />
</div>
);
}
}

const mapStateToProps = state => ({
isAuthenticated: state.authReducer.isAuthenticated,
user: state.authReducer,
roomId: state.roomReducer.currentUserRoom,
});

const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(Canvas);

最佳答案

我可以想到几种方法来解决这个问题:

  1. 如果您想保留任何类型的信息,只需将其添加到状态即可。在重新渲染期间,只需引用状态即可确保事物仍按原样渲染。
  2. 将事情分解成更小的组件并向它们添加 shouldComponentUpdate。不断分解,直到获得所需的精细控制。请记住,此函数还将 next props 和 next state 作为参数传递,因此您可以观察这些属性,并且仅在与组件相关的内容发生更改时才渲染,否则返回 false。

注意:如果您正在使用外部库 react-color,并且您试图阻止它的某些组件呈现,但又无权访问它,您可以只在其周围放置一个包装器组件纯粹是为了控制渲染条件。

希望对您有所帮助!

关于javascript - 每次在 React 中更改状态时,有没有办法不重新加载部分 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45356983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com