如何让用户从任意位置删除canvas 2D中的对象

问题描述

我编写了一些简单的条形图制作代码,该代码允许用户添加条形图,但我也想允许他们从画布上删除选择的条形图。我认为这应该不会太困难,但是我对html还是比较陌生,我不确定该怎么做。任何帮助将不胜感激。

这是我编写的代码

<html>
<head>
<script>

var barVals = [];

function draw() {

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    // calculate highest bar value (used to scale the rest)
    var highest = 0;
    for (var b=0; b<barVals.length; b++) {
    if (barVals[b]>highest)
    highest=barVals[b];
    }

// we have 8 horizontal lines so calculate an appropriate scale

var linespacing = 1;
var highestLine = 7*linespacing;

    while (highestLine<highest) {
    linespacing *= 10;
    highestLine = 7*linespacing;
    }



// grey background

ctx.fillStyle = "rgb(200,200,200)";
ctx.fillRect (0,600,450);



// draw and (if we have any data to scale from) label horizontal lines

var lineNum = 0;
ctx.fillStyle="white";
ctx.font="16px sans-serif";
for (y=0; y<=350; y+=50) {

    // line
    ctx.beginPath();
    ctx.moveto(50,y+50);
    ctx.lineto(550,y+50);
    ctx.stroke();

    // label (the 6 is an offset to centre the text vertically on the line)

    if (barVals.length>0) {
        ctx.fillText(linespacing*lineNum,10,400-y+6); 
        lineNum++;
    
    }

}



// draw Boxes (widths based on how many we have)

var barWidth = 500/barVals.length;
var halfBarWidth = barWidth/2;
for (b=0; b<barVals.length; b++) {

    // calculate size of Box and draw it
    
    var x = 60+b*barWidth;
    var hgt = (barVals[b]/highestLine)*350; // as fraction of highest line
    
    if (b%2==0)
    ctx.fillStyle = "red";
    
    else

    ctx.fillStyle = "blue";
    
    ctx.fillRect(x,400-hgt,barWidth,hgt);

    // calculate position of text and draw it

    ctx.fillStyle="white";
    var metrics = ctx.measureText(barVals[b]);
    var halfTextWidth = metrics.width/2;
    x = 60+halfBarWidth+(b*barWidth)-halfTextWidth;
    ctx.fillText(barVals[b],x,420-hgt); 

    }

}



function addBar() {

    var textBoxObj = document.getElementById("barVal"); 
    barVals.push(parseInt(textBoxObj.value)); // add new value to end of array. As an integer not a string!!
    draw(); // redraw

    textBoxObj.value = 0;

    }

</script>
</head>
    

<body onload="draw();">
<center>
<canvas id="canvas" width="600" height="450"></canvas>
<form>
<BR>
<input type=button value='Add Bar' onclick='addBar();'> <input id='barVal' value=0>
</form>
</body>
</html>

解决方法

删除特定图表与添加没有太大不同。实际上,您几乎已经在代码中拥有了所需的一切。

我们来看一下。一旦单击“添加栏”按钮,它将从关联的文本框中向barVal数组添加一个值。例如,如果值为5和12,则可以使用

将barVal的内容跟踪到控制台
console.log(barVal);

您会看到的

数组[5,12]

因此,在数组内部,将5存储在第一个位置,将12存储在第二个位置。考虑到这些知识,如何添加一个简单地从数组中删除特定元素的函数呢? array.splice()函数开始发挥作用。您可以向其传递数组内的索引以及应删除的许多元素。

例如如果我们想摆脱12,我们会打电话给barVal.splice(1,1);

删除元素后,只需再次调用draw()即可更新图形。现在,您可能想知道为什么我们要传递 1 作为索引,因为我们要删除第二个元素-这是因为索引从 0 开始计数。

这是一个例子:

var barVals = [];

function draw() {

  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  // calculate highest bar value (used to scale the rest)
  var highest = 0;
  for (var b = 0; b < barVals.length; b++) {
    if (barVals[b] > highest)
      highest = barVals[b];
  }

  // we have 8 horizontal lines so calculate an appropriate scale

  var lineSpacing = 1;
  var highestLine = 7 * lineSpacing;

  while (highestLine < highest) {
    lineSpacing *= 10;
    highestLine = 7 * lineSpacing;
  }



  // grey background

  ctx.fillStyle = "rgb(200,200,200)";
  ctx.fillRect(0,600,450);



  // draw and (if we have any data to scale from) label horizontal lines

  var lineNum = 0;
  ctx.fillStyle = "white";
  ctx.font = "16px sans-serif";
  for (y = 0; y <= 350; y += 50) {

    // line
    ctx.beginPath();
    ctx.moveTo(50,y + 50);
    ctx.lineTo(550,y + 50);
    ctx.stroke();

    // label (the 6 is an offset to centre the text vertically on the line)

    if (barVals.length > 0) {
      ctx.fillText(lineSpacing * lineNum,10,400 - y + 6);
      lineNum++;

    }
  }



  // draw boxes (widths based on how many we have)

  var barWidth = 500 / barVals.length;
  var halfBarWidth = barWidth / 2;
  for (b = 0; b < barVals.length; b++) {

    // calculate size of box and draw it

    var x = 60 + b * barWidth;
    var hgt = (barVals[b] / highestLine) * 350; // as fraction of highest line

    if (b % 2 == 0)
      ctx.fillStyle = "red";

    else

      ctx.fillStyle = "blue";

    ctx.fillRect(x,400 - hgt,barWidth,hgt);

    // calculate position of text and draw it

    ctx.fillStyle = "white";
    var metrics = ctx.measureText(barVals[b]);
    var halfTextWidth = metrics.width / 2;
    x = 60 + halfBarWidth + (b * barWidth) - halfTextWidth;
    ctx.fillText(barVals[b],x,420 - hgt);

  }

}



function addBar() {

  var textBoxObj = document.getElementById("barVal");
  barVals.push(parseInt(textBoxObj.value)); // add new value to end of array. As an integer not a string!!
  draw(); // redraw

  textBoxObj.value = 0;

}

function removeBar() {

  var textBoxObj = document.getElementById("removeBarVal");
  barVals.splice(parseInt(textBoxObj.value),1);
  draw(); // redraw



}
draw();
<center>
  <canvas id="canvas" width="600" height="450"></canvas>
  <form>
    <br>
    <input type=button value='Add Bar' onclick='addBar();'> <input id='barVal' value=0>
    <input type=button value='Remove Bar' onclick='removeBar();'> <input id='removeBarVal' value=0>
  </form>
</center>