首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在画布上绘制多个形状,同时可视化橡皮筋?

如何在画布上绘制多个形状,同时可视化橡皮筋?
EN

Stack Overflow用户
提问于 2019-12-11 16:36:22
回答 1查看 211关注 0票数 0

我用帆布和js制作一个用橡皮筋作画的工具。目前,它会绘制椭圆,但是每次我开始拖动一个新形状时--由于rubberBand函数的特殊性,前面的形状会擦除,因为它每次都会清除画布。有办法解决这个问题吗?

以下是jsfiddle链接:https://jsfiddle.net/ThePanda/bspf5v40/

HTML (index.html):

代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
    <script src="index.js"></script>
  </head>
  <body>
    <div style="position:absolute; top:4px; left:4px;"><canvas id="canvas"></canvas></div>
    <script>
      canvasEngine();
    </script>
  </body>
</html>

CSS (style.css):

代码语言:javascript
复制
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

#canvas {
    border: 2px solid black;
}

JavaScript (index.js):

代码语言:javascript
复制
function canvasEngine() {
  let canvas = document.getElementById('canvas');
  let ctx = canvas.getContext('2d');

  canvas.height = window.innerHeight - 12;
  canvas.width = window.innerWidth - 12;

  //letiables
  let canvasStartX = 4;
  let canvasStartY = 4;
  let lastMouseY, lastMouseX;
  let mouseX, mouseY;
  let width, height;

  let mousedown = false;

  //Mousedown
  function startPosition(e) {
    lastMouseX = parseInt(e.clientX - canvasStartX);
    lastMouseY = parseInt(e.clientY - canvasStartY);
    mousedown = true;
  };

  //Mousemove
  function rubberBand(e) {
    if (!mousedown) return;

    mouseX = parseInt(e.clientX - canvasStartX);
    mouseY = parseInt(e.clientY - canvasStartY);

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

    ctx.beginPath();
    width = mouseX-lastMouseX;
    height = mouseY-lastMouseY;
    ctx.rect(lastMouseX,lastMouseY,width,height);
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 2;
    ctx.stroke();
  };

  //Mouseup
  function finishedPosition(e) {
    mousedown = false;

    mouseX = parseInt(e.clientX - canvasStartX);
    mouseY = parseInt(e.clientY - canvasStartY);

    width = mouseX - lastMouseX;
    height = mouseY - lastMouseY;

    const rw = Math.abs(width/2);
    const rh = Math.abs(height/2);

    let centerX = mouseX - width/2;
    let centerY = mouseY - height/2;

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

    ctx.beginPath();
    ctx.ellipse(centerX,centerY,rw,rh,0,0,2 * Math.PI);
    ctx.strokeStyle = color;
    ctx.lineWidth = 5;
    ctx.stroke();
  };

  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("mousemove", rubberBand);
  canvas.addEventListener("mouseup", finishedPosition);
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-11 16:58:25

你的代码对于你想要达到的目标来说是正确的。

主要的问题是,每次绘制新东西时都要调用ctx.clearRect。这样,整个画布就会被清除,你的旧椭圆也就消失了。

我试图对您的代码进行最小的更改,以修复以下问题:

代码语言:javascript
复制
function canvasEngine() {
  let canvas = document.getElementById('canvas');
  let ctx = canvas.getContext('2d');
    
  canvas.height = window.innerHeight - 12;
  canvas.width = window.innerWidth - 12;
  
  //letiables
  let canvasStartX = 4;
  let canvasStartY = 4;
  let lastMouseY, lastMouseX;
  let mouseX, mouseY;
  let width, height;
  
  let mousedown = false;
  
  let ellipses = [];

	function drawEllipse(ellipse) {
  	ctx.beginPath();
  	ctx.ellipse(
    	ellipse.centerX,
      ellipse.centerY,
      ellipse.rw,
      ellipse.rh,
      0,
      0,
      2 * Math.PI
    );
    ctx.stroke();
  }

	function drawEllipses() {
  	ctx.strokeStyle = 'black';
    ctx.lineWidth = 5;
  	
  	ellipses.forEach(drawEllipse)
  }

  //Mousedown
  function startPosition(e) {
    lastMouseX = parseInt(e.clientX - canvasStartX);
    lastMouseY = parseInt(e.clientY - canvasStartY);
    mousedown = true;
  };
  
  //Mousemove
  function rubberBand(e) {
    if (!mousedown) return;

    mouseX = parseInt(e.clientX - canvasStartX);
    mouseY = parseInt(e.clientY - canvasStartY);
    
    ctx.clearRect(0,0,canvas.width,canvas.height);
    
    drawEllipses();

    ctx.beginPath();
    width = mouseX-lastMouseX;
    height = mouseY-lastMouseY;
    ctx.rect(lastMouseX,lastMouseY,width,height);
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 2;
    ctx.stroke();
  };

  //Mouseup
  function finishedPosition(e) {
    mousedown = false;

    mouseX = parseInt(e.clientX - canvasStartX);
    mouseY = parseInt(e.clientY - canvasStartY);

    width = mouseX - lastMouseX;
    height = mouseY - lastMouseY;
    
    const rw = Math.abs(width/2);
    const rh = Math.abs(height/2);
    
    let centerX = mouseX - width/2;
    let centerY = mouseY - height/2;
    
    // Add the ellipse to the list of ellipses
    ellipses.push({ centerX, centerY, rw, rh })

    ctx.clearRect(0,0,canvas.width,canvas.height);
    drawEllipses();
  };
  
  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("mousemove", rubberBand);
  canvas.addEventListener("mouseup", finishedPosition);
};

canvasEngine();
代码语言:javascript
复制
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

#canvas {
    border: 2px solid black;
}
代码语言:javascript
复制
<div style="position:absolute; top:4px; left:4px;"><canvas id="canvas"></canvas></div>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59290280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档