使用鼠标在HTML5画布上绘制

171

我想使用鼠标在HTML画布上绘图(例如,签名、姓名的绘制...)

我该如何实现这个功能?


1
检查一下! https://dev59.com/R1DTa4cB1Zd3GeqPMMgQ - Nitesh
参见:如何在画布上手绘? - Martin Thoma
好问题。谢谢。 - Titus Sutio Fanpula
1
一个相关的问题:在画布上绘制后,如何将鼠标位置存储并发送到服务器以记录(重新跟踪)绘图? - Ben L
13个回答

2
我使用了1083202的方法,但是去掉了所有控制器,并实现了KWILLIAMS建议的更改,使其对滚动不敏感。我还将画布放大到整个页面大小,即2000x1600像素,除了边距以外。我删除了所有绘图工具和按钮,只使用“蓝色”作为唯一的颜色。
我将JS代码放在一个名为myJS.js的单独文件中,并将其放在本地名为“JS”的文件夹中。
然后我使用笔记本电脑上的触摸板上的Stylus进行书写,这比使用手指或鼠标更好一些。
我用它来处理一些非正式的内部文档,在生成PDF文件之前,能够在上面画一些笔画很不错。

    var canvas, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        dot_flag = false;

    var x = "blue",
        y = 3;
    
    function init() {
        canvas = document.getElementById('can');
        ctx = canvas.getContext("2d");
        w = canvas.width;
        h = canvas.height;
    
        canvas.addEventListener("mousemove", function (e) {
            findxy('move', e)
        }, false);
        canvas.addEventListener("mousedown", function (e) {
            findxy('down', e)
        }, false);
        canvas.addEventListener("mouseup", function (e) {
            findxy('up', e)
        }, false);
        canvas.addEventListener("mouseout", function (e) {
            findxy('out', e)
        }, false);
    }
 
    function draw() {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = x;
        ctx.lineWidth = y;
        ctx.stroke();
        ctx.closePath();
    }
   
    function findxy(res, e) {
        if (res == 'down') {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.getBoundingClientRect().left;
            currY = e.clientY - canvas.getBoundingClientRect().top;
    
            flag = true;
            dot_flag = true;
            if (dot_flag) {
                ctx.beginPath();
                ctx.fillStyle = x;
                ctx.fillRect(currX, currY, 2, 2);
                ctx.closePath();
                dot_flag = false;
            }
        }
        if (res == 'up' || res == "out") {
            flag = false;
        }
        if (res == 'move') {
            if (flag) {
                prevX = currX;
                prevY = currY;
                currX = e.clientX - canvas.getBoundingClientRect().left;
                currY = e.clientY - canvas.getBoundingClientRect().top;
                draw();
            }
        }
    }
<html> 



<body onload="init()">
<p>Below you can draw:</p>
<canvas id="can" width="750" height="1050" style="position:absolute;">Below you can write:</canvas>
</body>


1
如果您为画布设置了背景图像,则需要进行一些微调,以使其正常工作,因为白色擦除技巧会隐藏背景。

这里有一个包含代码的gist

<html>
    <script type="text/javascript">
    var canvas, canvasimg, backgroundImage, finalImg;
    var mouseClicked = false;
    var prevX = 0;
    var currX = 0;
    var prevY = 0;
    var currY = 0;
    var fillStyle = "black";
    var globalCompositeOperation = "source-over";
    var lineWidth = 2;

    function init() {
      var imageSrc = '/abstract-geometric-pattern_23-2147508597.jpg'
      backgroundImage = new Image();
      backgroundImage.src = imageSrc;
      canvas = document.getElementById('can');
      finalImg = document.getElementById('finalImg');
      canvasimg = document.getElementById('canvasimg');
      canvas.style.backgroundImage = "url('" + imageSrc + "')";
      canvas.addEventListener("mousemove", handleMouseEvent);
      canvas.addEventListener("mousedown", handleMouseEvent);
      canvas.addEventListener("mouseup", handleMouseEvent);
      canvas.addEventListener("mouseout", handleMouseEvent);
    }

    function getColor(btn) {
      globalCompositeOperation = 'source-over';
      lineWidth = 2;
      switch (btn.getAttribute('data-color')) {
        case "green":
        fillStyle = "green";
        break;
        case "blue":
        fillStyle = "blue";
        break;
        case "red":
        fillStyle = "red";
        break;
        case "yellow":
        fillStyle = "yellow";
        break;
        case "orange":
        fillStyle = "orange";
        break;
        case "black":
        fillStyle = "black";
        break;
        case "eraser":
        globalCompositeOperation = 'destination-out';
        fillStyle = "rgba(0,0,0,1)";
        lineWidth = 14;
        break;
      }

    }

    function draw(dot) {
      var ctx = canvas.getContext("2d");
      ctx.beginPath();
      ctx.globalCompositeOperation = globalCompositeOperation;
      if(dot){
        ctx.fillStyle = fillStyle;
        ctx.fillRect(currX, currY, 2, 2);
      } else {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = fillStyle;
        ctx.lineWidth = lineWidth;
        ctx.stroke();
      }
      ctx.closePath();
    }

    function erase() {
      if (confirm("Want to clear")) {
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        document.getElementById("canvasimg").style.display = "none";
      }
    }

    function save() {
      canvas.style.border = "2px solid";
      canvasimg.width = canvas.width;
      canvasimg.height = canvas.height;
      var ctx2 = canvasimg.getContext("2d");
      // comment next line to save the draw only
      ctx2.drawImage(backgroundImage, 0, 0);
      ctx2.drawImage(canvas, 0, 0);
      finalImg.src = canvasimg.toDataURL();
      finalImg.style.display = "inline";
    }

    function handleMouseEvent(e) {
      if (e.type === 'mousedown') {
        prevX = currX;
        prevY = currY;
        currX = e.offsetX;
        currY = e.offsetY;
        mouseClicked = true;
        draw(true);
      }
      if (e.type === 'mouseup' || e.type === "mouseout") {
        mouseClicked = false;
      }
      if (e.type === 'mousemove') {
        if (mouseClicked) {
          prevX = currX;
          prevY = currY;
          currX = e.offsetX;
          currY = e.offsetY;
          draw();
        }
      }
    }
    </script>
    <body onload="init()">
      <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;">
      </canvas>
      <div style="position:absolute;top:12%;left:43%;">Choose Color</div>
      <div style="position:absolute;top:15%;left:45%;width:10px;height:10px;background:green;" data-color="green" onclick="getColor(this)"></div>
      <div style="position:absolute;top:15%;left:46%;width:10px;height:10px;background:blue;" data-color="blue" onclick="getColor(this)"></div>
      <div style="position:absolute;top:15%;left:47%;width:10px;height:10px;background:red;" data-color="red" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:45%;width:10px;height:10px;background:yellow;" data-color="yellow" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:46%;width:10px;height:10px;background:orange;" data-color="orange" onclick="getColor(this)"></div>
      <div style="position:absolute;top:17%;left:47%;width:10px;height:10px;background:black;" data-color="black" onclick="getColor(this)"></div>
      <div style="position:absolute;top:20%;left:43%;">Eraser</div>
      <div style="position:absolute;top:22%;left:45%;width:15px;height:15px;background:white;border:2px solid;" data-color="eraser" onclick="getColor(this)"></div>
      <canvas id="canvasimg" style="display:none;" ></canvas>
      <img id="finalImg" style="position:absolute;top:10%;left:52%;display:none;" >
      <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
      <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
    </body>
    </html>

1

如果您在实现此内容时遇到问题,请告诉我。它使用 processing.js,并具有更改颜色、使绘图点变大或变小的功能。

<html>
<head>
<!--script librarires-->
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript" src="init.js"></script>

<!--styles -->
<style type="text/css" src="stylesheet.css">
</style> 
</head>
<body>
<!--toolbox -->
<div id="draggable toolbox"></div>
<script type="application/processing">
// new script
int prevx, prevy;
int newx, newy;
boolean cliked;
color c1 = #000000;
int largeur=2;
int ps = 20;
int px = 50;
int py = 50;

void setup() {
size(500,500);
frameRate(25);
background(50);

 prevx = mouseX;
 prevy = mouseY;
 cliked = false;
 }

void draw() {
 //couleur
 noStroke(0);
 fill(#FFFFFF);//blanc
rect(px, py, ps, ps);
 fill(#000000);
 rect(px, py+(ps), ps, ps);
 fill(#FF0000);
 rect(px, py+(ps*2), ps, ps);
 fill(#00FF00);
 rect(px, py+(ps*3), ps, ps);
 fill(#FFFF00);
 rect(px, py+(ps*4), ps, ps);
 fill(#0000FF);
 rect(px, py+(ps*5), ps, ps);
 //largeur
 fill(#FFFFFF);
 rect(px, py+(ps*7), ps, ps);
  fill(#FFFFFF);
 rect(px, py+(ps*8), ps, ps);
 stroke(#000000);
 line(px+2, py+(ps*7)+(ps/2), px+(ps-2), py+(ps*7)+(ps/2));
 line(px+(ps/2), py+(ps*7)+1, px+(ps/2), py+(ps*8)-1);
 line(px+2, py+(ps*8)+(ps/2), px+(ps-2), py+(ps*8)+(ps/2));

 if(cliked==false){
  prevx = mouseX;
 prevy = mouseY;  
 }
 if(mousePressed) { 
  cliked = true;
 newx = mouseX;
  newy = mouseY;
  strokeWeight(largeur);
  stroke(c1);
  line(prevx, prevy, newx, newy);
  prevx = newx;
 prevy = newy;
 }else{
  cliked= false;
  }
}
void mouseClicked() {
 if (mouseX>=px && mouseX<=(px+ps)){
  //couleur
  if (mouseY>=py && mouseY<=py+(ps*6)){ 
   c1 = get(mouseX, mouseY);
  }
   //largeur
  if (mouseY>=py+(ps*7) && mouseY<=py+(ps*8)){ 
   largeur += 2;
  }
 if (mouseY>=py+(ps*8) && mouseY<=py+(ps*9)){ 
   if (largeur>2){
    largeur -= 2;
   }
  }
 }
}
</script><canvas></canvas>
</body>
</html>

我不理解它,但它开始处理了。 - expiredninja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接