javascript 画布直线问题

nwo49xxi  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(126)

这个画布已经创建了一个错误,因为我创建了它,我还没有找到一个解决方案后,我所有的研究。所以我需要一只手。我需要画布创建一条直线,但它最终创建多条直线从起点时,鼠标移动,而不是一条直线。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]>      <html class="no-js"> <!--<![endif]-->
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
    </head>

    <style>
        *{
            box-sizing: border-box;
        }

        body,html{
            padding: 0;
            margin: 0;
            height: 100vh;
            width: 100vw;
        }

    </style>
    <body>
       
        <canvas>
            
        </canvas>
        
        <script>
            var colorLine = 'black'
            var fillLine = 'none'
            var prevX = ''
            var prevY = ''
            var isDrawing = false
            var snapshot;
            var canvas = document.querySelector('canvas');
            var ctx = canvas.getContext('2d');

            
            let backgroundSetUp = () => {
                
                canvas.height = window.innerHeight - 50; 
                canvas.width = window.innerWidth - 50;
                ctx.fillStyle = colorLine;
                ctx.fillStyle = fillLine
            };

            let startDrawing = e => {
                isDrawing = true
                
                prevX = e.offsetX 
                prevY = e.offsetY 
                ctx.beginPath();
                ctx.strokeStyle  = 'black'
                ctx.fillStyle = '#fff'
           
            }

            let Drawing = e => {
                if(isDrawing === false)
                return
                ctx.beginPath();
                ctx.moveTo(prevX, prevY);
                ctx.lineTo(e.offsetX, e.offsetY);
                ctx.stroke()

                
            }

            let stopDrawing = e => {
                isDrawing = false
            }




            canvas.onmousedown = ( e => {
                startDrawing(e)
            })
            canvas.onmousemove = ( e => {
                Drawing(e)
            })
            canvas.onmouseup = ( e => {
                stopDrawing(e)
            })

            backgroundSetUp()

        </script>
    </body>
</html>
aiazj4mn

aiazj4mn1#

在执行另一次绘制之前,应清除画布绘制:

ctx.clearRect( 0, 0, canvas.width, canvas.height );

这会在你绘制你的“修正”线到新的鼠标位置之前重置画布。如果你想绘制更多的线,你需要另一个画布,上面有一个先前绘制的副本,然后把它画回输出画布,而不是使用clear
x一个一个一个一个x一个一个二个x
这里有一个缓冲区,允许你在第一行之后继续绘制。我还清理了一些你的定义(正确使用constlet,忽略var并使用function,这样可以创建更简洁明了的代码):
一个三个三个一个

nkkqxpd9

nkkqxpd92#

存储现有行的位置,以便删除它

令人不安的是,我需要让擦除线比绘图线(1 px)粗一点(3 px)才能完全擦除。即使是2 px的擦除也不够。我愿意解释为什么会这样-这让我很惊讶。

var colorLine = 'black'
var fillLine = 'none'
var prevX = ''
var prevY = ''
var currX = ''
var currY = ''
var isDrawing = false
var snapshot;
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

let backgroundSetUp = () => {
  canvas.height = window.innerHeight - 50;
  canvas.width = window.innerWidth - 50;
  ctx.fillStyle = colorLine;
  ctx.fillStyle = fillLine
};

let startDrawing = e => {
  isDrawing = true
  prevX = e.offsetX
  prevY = e.offsetY
  currX = prevX
  currY = prevY

}

let Drawing = e => {
  if (isDrawing === false)
    return

  ctx.strokeStyle = 'white'
  ctx.lineWidth = 3;
  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.stroke()

  currX = e.offsetX
  currY = e.offsetY
  ctx.strokeStyle = 'black'
  ctx.lineWidth = 1;
  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.stroke()
}

let stopDrawing = e => {
  isDrawing = false
}

canvas.onmousedown = (e => {
  startDrawing(e)
})
canvas.onmousemove = (e => {
  Drawing(e)
})
canvas.onmouseup = (e => {
  stopDrawing(e)
})

backgroundSetUp()
* {
  box-sizing: border-box;
}

body,
html {
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100vw;
}
<canvas>

</canvas>

或者在绘制前清空画布

如果画布上有任何其他内容,您将丢失它,除非您存储信息并重新绘制它。

为什么我们需要用更粗的线条擦除,为什么异或不起作用

我发现这个StackOverflow的答案解释了为什么擦除线需要更宽。它也解释了为什么我们不能用XOR做一个聪明的技巧来允许我们绘制和删除一条线,而不干扰画布上已经存在的任何东西。
https://stackoverflow.com/a/16740592/7549483
简而言之,当我们绘图时,浏览器会进行反锯齿处理,这是一个复杂的过程,不容易逆转。这需要擦除线更宽,并阻止XOR执行我们希望的操作。

相关问题