通过JavaScript使用Canvas,如何在单击按钮后更改圆的半径?

时间:2019-04-04 10:22:03

标签: javascript html canvas

我试图做到这一点,以便当我单击按钮更改半径大小时,它将把所有圆的半径大小更改为5-10之间的随机大小。

我已经尝试绘制2个圆(1个黑色,1个蓝色),然后调用,然后尝试将半径更改为5-10之间的新随机半径大小。添加功能后,看不到绘制的两个圆。任何反馈,不胜感激。

<canvas width="300" height="300" id="myCanvas" style="border: 1px solid black"></canvas>
<button id="changeRadius">Change Size</button>

<script>
var number = Math.min(Math.max(paraseInt(number), 5), 10);
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
ctx.translate(100,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 10, 0, 2 * Math.PI);
  ctx.fillStyle = "black";
  ctx.fill();
ctx.translate(140,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 10, 0, 2 * Math.PI);
  ctx.fillStyle = "blue";
  ctx.fill();
document.getElementById("changeRadius").onclick = function() {
ctx.clearRect
ctx.translate(100,120);
ctx.beginPath(); 
  ctx.arc(0, 0, "number", 0, 2 * Math.PI);
  ctx.fillStyle = "black";
  ctx.fill();
ctx.translate(140,120);
ctx.beginPath(); 
  ctx.arc(0, 0, "number", 0, 2 * Math.PI);
  ctx.fillStyle = "blue";
  ctx.fill();
if (event.keycode == s){
ctx.translate(100,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 5, 0, 2 * Math.PI);
  ctx.fillStyle = "black";
  ctx.fill();
ctx.translate(140,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 5, 0, 2 * Math.PI);
  ctx.fillStyle = "blue";
  ctx.fill();
}else if (event.keycode == b) {
ctx.translate(100,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 10, 0, 2 * Math.PI);
  ctx.fillStyle = "black";
  ctx.fill();
ctx.translate(140,120);
ctx.beginPath(); 
  ctx.arc(0, 0, 10, 0, 2 * Math.PI);
  ctx.fillStyle = "blue";
  ctx.fill();
}
}
</script>

2 个答案:

答案 0 :(得分:1)

代码中有许多简单的错误。

1。

在调用clearRect的位置,您具有:

ctx.clearRect

但必须是:

ctx.clearRect(x, y, width, height);

其中x,y,宽度和高度定义要清除的矩形。要清除整个画布,请使用:

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

2。

您将parseInt拼写为paraseInt

3。

您将"number"设置为对ctx.arc的调用中的半径...我什至不知道您要实现什么目标。看起来像是占位符?无论如何,它必须是实际数字,而不仅仅是字符串"number"

也许您打算使用在顶部创建的变量number却从未使用过?

ctx.arc(0, 0, "number", 0, 2 * Math.PI);

成为

ctx.arc(0, 0, number, 0, 2 * Math.PI);

(请注意,没有"个字符)

4。

您实际上从未更新过number的值,因此即使上面的内容也无济于事。

答案 1 :(得分:0)

Michael,您的问题已经存在了一段时间,但希望这个答案对您以及仍在学习JavaScript的其他人可能仍然有用。一旦我解决了Mat列出的基本语法问题,就可以看到缺少的圆圈。那时我发现了三件事。

  1. 在画布上绘制的图像可能不会出现在您期望的位置。

  2. 在您的第一个变量中声明并初始化为number的变量 语句不会生成有效数字,更不用说随机数字了。

  3. 您的代码具有ifif else语句,这些语句将不执行任何操作 没有事件处理程序。


#1

您的代码使用ctx.arc()绘制基本圆,并使用ctx.translate()将其移动到画布上的位置。使用ctx.translate(),两个参数x和y确定圆的移动距离; x是水平方向移动的距离; y是沿垂直方向移动的距离。

问题是移动后您不再知道画布上的位置坐标。因此,在进行下一个ctx.translate()操作之前,需要重置原点。

要重置原点,请使用CanvasRenderingContext2D.setTransform(),例如

ctx.setTransform(1, 0, 0, 1, 0, 0);

from Mozilla MDN

Canvas 2D的CanvasRenderingContext2D.setTransform()方法 API重置(替代)当前对身份的转换 矩阵,然后调用参数描述的转换 这种方法。这使您可以缩放,旋转,平移(移动)和 倾斜上下文。

此API专为动画绘制而设计,它具有多种动态转换2D形状的方法。对于您的代码而言,足以理解通过清除身份矩阵,您可以还原0,0(画布原点)作为在随后的任何绘制操作中使用的x和y值的参考。使用ctx.translate()之前,请重设原点。观察代码启动时的区别。

启动时重置原点的效果

without / with

无论何时绘制新图像,都必须首先使用ctx.clearRect()清除整个画布,并且在重置原点之前非常重要。在每个示例中单击“更改大小”按钮,以查看通过重置原点清除了整个屏幕。如果不进行重置,则清除的矩形的原点将与绘制的最后一个圆的中心对齐,即清除的矩形将吃入该圆的右下象限。

重置原点在清理画布上的效果

without / with


#2

第二个问题可以通过在第一条指令后插入alert(number)来演示。代码运行时,alert报告一条NaN消息(即不是数字)。此外,随机值的范围是0.0到1.0,但出于您的目的,可以将其缩放到5.0到10.0的范围(有关更多信息,请参见herehere)。

下面的代码显示getNewRadius(),,该函数在单击“更改大小”按钮时会生成一个随机数。在函数被调用之前,常量和变量被声明和初始化。每次调用该函数时,即每次单击鼠标,它都会返回一个新的随机值radius,然后将其作为参数传递给下一个绘图函数。

为清楚起见,我将变量number重命名为更容易解释的radius,并用一些恰当命名的constantvar替换了代码中的幻数。


#3

ifelse if测试范围内的声明将永远不会执行。可测试值可能是在运行时通过键盘事件(即event.keycode)创建的。但是在您的代码中,没有设置处理程序来侦听此类事件。此外,Mozilla MDN建议keyCode is obsolete并提出以下建议

MDN警告:不建议使用此属性;你应该使用 如果可以的话,请改用KeyboardEvent.key。

有关键盘事件选项的更全面的摘要,请参见here

下面的代码包括一个称为setMaxOrMinRadius(e)的基本功能,该功能允许通过在键盘上键入来选择最大或最小半径值。与您的初始代码保持一致,键入s将选择minRadius,键入b将选择maxRadius。仅在按下键并初始化事件侦听器后才能识别此功能。现在,如果事件侦听器检测到击键,它将能够切换到该功能并识别出已按下了哪个键。

致谢

此答案是退休人员与前同事鲍勃·道格拉斯和我本人之间的共同努力。我们在一起学习JavaScript已有两个月了。我们欢迎您提出改进建议。

代码

<canvas width="300" height="300" id="myCanvas" style="border: 1px solid black"></canvas>
<button id="changeRadius">Change Size</button>

<script>
const maxRadius     = 10;
const minRadius     = 5;
var range           = maxRadius - minRadius;
var radius          = maxRadius;

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

    document.addEventListener('keydown', setMaxOrMinRadius);

    drawCircles(maxRadius);

    document.getElementById("changeRadius").onclick = function() {
    clearCanvas();
    radius          = getNewRadius();
    drawCircles(radius);
}

function setMaxOrMinRadius(e) {
clearCanvas();
switch (e.which) {
    case 83:                                // type 's'
        drawCircles(minRadius);
    break;

    case 66:                                // type 'b'
        drawCircles(maxRadius);
    break;
    }
}

function getNewRadius() {
    var radius      = (Math.random() * minRadius) + range;
    return radius;
}

function drawCircles(radius) {
    drawBlueCircle(radius);
    drawBlackCircle(radius);
}

function clearCanvas(){
    ctx.setTransform(1, 0, 0, 1, 0, 0);     // reset origin
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function drawBlackCircle (radius) {
    ctx.setTransform(1, 0, 0, 1, 0, 0);     // reset origin
    ctx.translate(100,120);
    ctx.beginPath();
    ctx.arc(0, 0, radius, 0, 2 * Math.PI);
    ctx.fillStyle   = "black";
    ctx.fill();
}

function drawBlueCircle (radius) {
    ctx.setTransform(1, 0, 0, 1, 0, 0);     // reset origin
    ctx.translate(140,120);
    ctx.beginPath();
    ctx.arc(0, 0, radius, 0, 2 * Math.PI);
    ctx.fillStyle   = "blue";
    ctx.fill();
}