Javascript 自动删除/刷新画布中的元素

Javascript 自动删除/刷新画布中的元素,javascript,reactjs,canvas,redux,Javascript,Reactjs,Canvas,Redux,我用一个带websocket的相机发送一个图像,用画布显示,然后在上面画画。当用户点击另一个地方时,我试图删除之前的线条并绘制新的线条,但是,我读到这是不可能清除画布的精确部分的,但是,令人惊讶的是,这发生在我身上 所以我想知道为什么即使我读了很多遍,这也是不可能的 当我第一次启动程序时,还没有图像,没有刷新,但是当我显示第一张图片时,我可以多次单击,只显示最后一次单击,我不明白为什么 谢谢你的帮助,这里是我的代码示例 updateImage(){ console.log(thi

我用一个带websocket的相机发送一个图像,用画布显示,然后在上面画画。当用户点击另一个地方时,我试图删除之前的线条并绘制新的线条,但是,我读到这是不可能清除画布的精确部分的,但是,令人惊讶的是,这发生在我身上

所以我想知道为什么即使我读了很多遍,这也是不可能的

当我第一次启动程序时,还没有图像,没有刷新,但是当我显示第一张图片时,我可以多次单击,只显示最后一次单击,我不明白为什么

谢谢你的帮助,这里是我的代码示例

    updateImage(){
    console.log(this.refs.myCanvas);

    const ctx = this.refs.myCanvas.getContext('2d');
    let src = this.state.imageSrc;

    this.image.onload = () => {
      console.log('done')
      //ctx.clearRect(0,0,this.refs.myCanvas.width,this.refs.myCanvas.height)
      ctx.drawImage(this.image, 0, 0,this.refs.myCanvas.width,this.refs.myCanvas.height); //On dessine l'image
      if(this.props.beam_markX != undefined && this.props.beam_markY != undefined){
        this.draw_Beam_Marker()
      }

    }
    this.image.src = "data:image/jpg;base64,"+src;
    this.componentWillUnmount() //On appel la derniere methode

  }

  draw_Beam_Marker(e){
    const ctx = this.refs.myCanvas.getContext('2d');
    ctx.strokeStyle = "#7FFF00" //chartreuse
    ctx.font = '15px Arial'
    ctx.fillStyle = "#7FFF00"

    if(e != undefined){ //Quand on clique sur l'image

      if(this.props.beam_markX != e.nativeEvent.offsetX && this.props.beam_markY != e.nativeEvent.offsetY && this.props.crosshair === 0){ //On ne dessine que si nouveaux coordonnes et que le crosshair n'est pas lock

        ctx.beginPath();
        ctx.moveTo(0, e.nativeEvent.offsetY);
        ctx.lineTo(this.refs.myCanvas.width, e.nativeEvent.offsetY);
        ctx.stroke();
        ctx.moveTo(e.nativeEvent.offsetX, 0);
        ctx.lineTo(e.nativeEvent.offsetX, this.refs.myCanvas.height);
        ctx.stroke();
        ctx.fillText("X: "+e.nativeEvent.offsetX,e.nativeEvent.offsetX+1,e.nativeEvent.offsetY+12);
        ctx.fillText("Y: "+e.nativeEvent.offsetY,e.nativeEvent.offsetX+1,e.nativeEvent.offsetY+30);
        ctx.fillText("W: "+this.refs.myCanvas.width,e.nativeEvent.offsetX+1,e.nativeEvent.offsetY+48);
        ctx.fillText("H: "+this.refs.myCanvas.height,e.nativeEvent.offsetX+1,e.nativeEvent.offsetY+66);
        ctx.closePath();
        this.props.setBeamMark(e.nativeEvent.offsetX,e.nativeEvent.offsetY);

      }
    }
      else if(this.props.beam_markX != undefined && this.props.beam_markY != undefined ){ //Quand on passe a une nouvelle image
        //ctx.clearRect(0,0,this.refs.myCanvas.width,this.refs.myCanvas.height)
        ctx.beginPath();
        ctx.moveTo(0, this.props.beam_markY);
        ctx.lineTo(this.refs.myCanvas.width, this.props.beam_markY);
        ctx.stroke();
        ctx.moveTo(this.props.beam_markX, 0);
        ctx.lineTo(this.props.beam_markX, this.refs.myCanvas.height);
        ctx.stroke();
        ctx.fillText("X: "+this.props.beam_markX,this.props.beam_markX+1,this.props.beam_markY+12)
        ctx.fillText("Y: "+this.props.beam_markY,this.props.beam_markX+1,this.props.beam_markY+30);
        ctx.fillText("W: "+this.refs.myCanvas.width,this.props.beam_markX+1,this.props.beam_markY+48);
        ctx.fillText("H: "+this.refs.myCanvas.height,this.props.beam_markX+1,this.props.beam_markY+66);
        ctx.closePath();
      }
  }


只显示最后一次单击,因为您正在绘制图像,这将覆盖整个画布,然后您正在绘制线条
this.props.beam\u markX
this.props.beam\u markY
,这将只绘制一条线条。可以这样做的一种方法是,每次单击“在数组中存储x和y值”,然后:清除画布,绘制图像,并重新绘制线条!以下是一个例子:

var canvas=document.querySelectorAll('canvas')[0]
var ctx=canvas.getContext('2d')
var单击=[]
canvas.addEventListener('click',函数(事件){
var x=event.clientX
var y=event.clientY
点击。推({
x:event.clientX,
y:event.clientY
})
抽绳()
})
函数drawLines(){
//使画布空白
clearRect(0,0,canvas.width,canvas.height)
//在这里画你的图像
//ctx.drawImage
//画线
对于(点击次数){
//Y轴线
抽绳(点击.x,0,点击.x,画布.height)
//X轴线
绘制线(0,单击.y,画布.width,单击.y)
//正文
ctx.fillText(单击.x+,'+单击.y,单击.x,单击.y)
}
}
功能抽绳(x1、y1、x2、y2){
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
}
html,正文{
边际:0px;
填充:0px;
}
帆布{
背景:cdcdcd;
}


点击画布

您的全部问题在于此代码:

this.image.onload = () => {
  console.log('done')
  //ctx.clearRect(0,0,this.refs.myCanvas.width,this.refs.myCanvas.height)
  ctx.drawImage(this.image, 0, 0,this.refs.myCanvas.width,this.refs.myCanvas.height); //On dessine l'image
  if(this.props.beam_markX != undefined && this.props.beam_markY != undefined){
    this.draw_Beam_Marker() 
  }
}

简单地说,这条语句
ctx.drawImage(this.image,0,0,this.refs.myCanvas.width,this.refs.myCanvas.height)将在以前的图形上绘制。唯一剩下的标记是加载图像后绘制的标记。

我不理解你的问题。请更简洁,尽量写一篇文章;太长,读不下去了其次,请链接你读过的文章,清除画布的精确部分是不可能的,这样我才能理解什么是原创的meant@EyuelDK对不起,我的英语不好,我会尽量说得更准确。首先,这里有一个链接,它说这是不可能的。其次,为什么我想知道,这就是为什么当我有一个图像,只有最后几行我点击可见,为什么它不是相同的渲染像第一张图片,没有刷新你确定这是你用来产生下面的图像的代码?此语句
This.draw\u Beam\u Marker()
永远不会绘制任何内容,因为参数
e
始终未定义。我不认为这是最初使用的代码。然而,这实际上是使用和运行的代码,e只有在我点击画布时才定义。我仍然不认为这段代码讲述了全部故事,但如果它起作用,它就起作用了——尽管我不同意这种想法。但是看看你对方法的定义
draw\u Beam\u Marker(e)
,它接受一个参数
e
,但是在这里调用时没有任何合适的参数
this。draw\u Beam\u Marker()
draw\u Beam\u Marker
的主体中,它清楚地说明了
如果(e!=未定义){//Quand on clique sur l'image
当执行时,这应该总是错误的
This.draw\u Beam\u Marker()
IMO,您的代码中有一些其他部分使其工作,而不是您在此处显示的部分。感谢花时间提供帮助,但我只有一个问题,“仅显示最后一次单击,因为您正在绘制图像,这将覆盖整个画布".好的,我理解,但是当画布与图像重叠时,为什么会出现刷新样式?我的意思是,是否每次我单击图像的某个位置时,都会再次覆盖她之前的“实例”?是的,画布的工作方式与普通html元素的工作方式不同技术上你甚至不需要清除画布,因为图像将采用全宽和全高,并覆盖所有内容!:]因此,是的,每次绘制图像时,它都覆盖最后一张图像。是的,我了解这一部分,但如果我不更改图像,我每次都保持不变,我在某个地方点击,旧的标记消失,新的出现,我不知道为什么,因为我没有调用方法绘制新图像…抱歉,我可能有点迟钝…好吧,我明白了,我试着调整我的绘制图像的宽度和高度,你写道,每次我点击我的图像,即使它与重新绘制的图像相同,谢谢你的帮助:)我试着删除这个部分:如果(this.props.beam\u markX!=未定义&&this.props.beam\u markY!=未定义){this.draw_Beam_Marker()}结果是,如果我试着点击某个地方,标记会立即出现并消失,就像画布总是在刷新一样。我理解,我试着测量我的绘图图像的宽度和高度,你写道,每次我点击我的图像,即使它与重新绘制的图像相同,谢谢你的帮助:)