Javascript 是否有一种方法可以避免每次在React中更改状态时重新加载画布的一部分?
我刚刚将Javascript 是否有一种方法可以避免每次在React中更改状态时重新加载画布的一部分?,javascript,reactjs,canvas,html5-canvas,Javascript,Reactjs,Canvas,Html5 Canvas,我刚刚将react color模块添加到此画布页面。当用户选择一种颜色时,strokeStyle会正确地更改为该颜色,但它也会重置整个画布,使其成为一块白板。有没有办法改变这一点,只改变颜色本身,而不重置画布?我尝试添加shouldComponentUpdate,但这只能使颜色完全不变 import React from 'react'; import { Layer, Stage, Image } from 'react-konva'; import { connect } from 'rea
react color
模块添加到此画布页面。当用户选择一种颜色时,strokeStyle
会正确地更改为该颜色,但它也会重置整个画布,使其成为一块白板。有没有办法改变这一点,只改变颜色本身,而不重置画布?我尝试添加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);
从“React”导入React;
从“react konva”导入{图层、舞台、图像};
从'react redux'导入{connect};
从“redux”导入{bindActionCreators};
从“反应颜色”导入{GithubPicker};
类Canvas扩展了React.Component{
建造师(道具){
超级(道具);
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(节点);
log(data.canvasJSON);
this.updateKonva(idToUpdate,data.canvasJSON);
//this.renderisabledKonva(未定义,data.canvasJSON,data.canvasId);
});
此.state={
背景:“#fff”,
};
}
canvasEvent(canvasJSON){
this.props.socket.emit('canvas_event',{roomId:this.props.roomId,canvasJSON:canvasJSON,canvasId:this.props.canvasId},()=>{});
}
handleChangeComplete=(颜色)=>{
this.setState({background:color.hex});
};
renderTools(){
返回(
工具:
刷子
橡皮擦
);
}
renderKonva(集装箱){
常数=this;
const width=400;//window.innerWidth;
const height=400;//window.innerHeight-25;
//首先,我们需要Konva的核心产品:舞台和舞台
const stage=新Konva.stage({
容器:`drawing${this.props.canvasId}`,
宽度:宽度,
高度:高度
});
const layer=新的Konva.layer({});
阶段。添加(层);
//然后我们将绘制到特殊的画布元素中
const canvas=document.createElement('canvas');
canvas.width=stage.width()/1.5;
canvas.height=stage.height()/1.5;
//已创建画布,我们可以将其作为“Konva.Image”元素添加到图层中
让image=new Konva.image({
图片:画布,
x:stage.width()/6,
y:舞台高度()/6,
笔划:“#05AFF2”,
阴影模糊:5,
});
图层。添加(图像);
stage.draw();
//现在我们需要访问上下文元素
const context=canvas.getContext('2d');
context.strokeStyle=this.state.background;
context.lineJoin='round';
context.lineWidth=5;
让isPaint=false;
让最后一个指针定位;
let mode='brush';
//现在我们需要绑定一些事件
//我们需要开始在mousedown上画图
//停止在鼠标上画画
stage.on('contentMousedown.proto',()=>{
isPaint=true;
lastPointerPosition=stage.getPointerPosition();
});
stage.on('contentMouseup.proto',()=>{
isPaint=false;
});
//和核心功能-绘图
stage.on('contentMousemove.proto',()=>{
如果(!isPaint){
返回;
}
如果(模式=='brush'){
context.lineWidth=5;
context.globalCompositeOperation='source over';
}
如果(模式=='橡皮擦'){
context.lineWidth=15;
context.globalCompositeOperation='destination out';
}
context.beginPath();
设localPos={
x:lastPointerPosition.x-image.x(),
y:lastPointerPosition.y-image.y(),
};
moveTo(localPos.x,localPos.y);
const pos=stage.getPointerPosition();
localPos={
x:pos.x-image.x(),
y:pos.y-image.y(),
};
lineTo(localPos.x,localPos.y);
closePath();
stroke();
lastPointerPosition=pos;
layer.draw();
const dataURL=stage.toDataURL();
//window.open(dataURL);
canvasEvent(dataURL);
//canvasEvent(stage.toJSON());
//控制台日志(层);
});
const select=document.getElementById('tool');
select.addEventListener('change',()=>{
模式=选择值;
});
}
render(){
返回(
{this.renderTools()}
this.renderKonva(ref)}/>
);
}
}
常量mapStateToProps=状态=>({
isAuthenticated:state.authReducer.isAuthenticated,
用户:state.authReducer,
roomId:state.roomReducer.currentUserRoom,
});
const-mapDispatchToProps=dispatch=>bindActionCreators({},dispatch);
导出默认连接(mapStateToProps、mapDispatchToProps)(画布);
虽然我没有找到只进行部分重新加载的方法,但我确实为此制定了一个解决方案:
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);
this.updateKonva(idToUpdate, data.canvasJSON);
this.handleChangeComplete = this.handleChangeComplete.bind(this);
//this.renderDisabledKonva(undefined, data.canvasJSON, data.canvasId);
});
}
handleChangeComplete(color) {
newColor = color.hex;
}
canvasEvent(canvasJSON) {
this.props.socket.emit('canvas_event', { roomId: this.props.roomId, canvasJSON: canvasJSON, canvasId: this.props.canvasId }, () => {});
}
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();
context.strokeStyle = newColor;
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} />
<div id={'drawing' + this.props.canvasId} ref={ref => this.renderKonva(ref)} />
</div>
);
}
}
let newColor = '#fff';
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);
从“React”导入React;
从“react konva”导入{图层、舞台、图像};
从'react redux'导入{connect};
从“redux”导入{bindActionCreators};
从“反应颜色”导入{GithubPicker};
类Canvas扩展了React.Component{
建造师(道具){
超级(道具);
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(节点);
this.updateKonva(idToUpdate,data.canvasJSON);
this.handleChangeComplete=this.handleChangeComplete.bind(this);
//this.renderisabledKonva(未定义,data.canvasJSON,data.canvasId);
});
}
把手更换完成(颜色){
newColor=color.hex;
}
canvasEvent(canvasJSON){
这只袜子