我试图做到这一点,以便当我单击按钮更改半径大小时,它将把所有圆的半径大小更改为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>
答案 0 :(得分:1)
代码中有许多简单的错误。
在调用clearRect的位置,您具有:
ctx.clearRect
但必须是:
ctx.clearRect(x, y, width, height);
其中x,y,宽度和高度定义要清除的矩形。要清除整个画布,请使用:
ctx.clearRect(0, 0, canvas.width, canvas.height);
您将parseInt
拼写为paraseInt
。
您将"number"
设置为对ctx.arc
的调用中的半径...我什至不知道您要实现什么目标。看起来像是占位符?无论如何,它必须是实际数字,而不仅仅是字符串"number"
。
也许您打算使用在顶部创建的变量number
却从未使用过?
ctx.arc(0, 0, "number", 0, 2 * Math.PI);
成为
ctx.arc(0, 0, number, 0, 2 * Math.PI);
(请注意,没有"
个字符)
您实际上从未更新过number
的值,因此即使上面的内容也无济于事。
答案 1 :(得分:0)
Michael,您的问题已经存在了一段时间,但希望这个答案对您以及仍在学习JavaScript的其他人可能仍然有用。一旦我解决了Mat列出的基本语法问题,就可以看到缺少的圆圈。那时我发现了三件事。
在画布上绘制的图像可能不会出现在您期望的位置。
在您的第一个变量中声明并初始化为number
的变量
语句不会生成有效数字,更不用说随机数字了。
您的代码具有if
和if else
语句,这些语句将不执行任何操作
没有事件处理程序。
#1
您的代码使用ctx.arc()
绘制基本圆,并使用ctx.translate()
将其移动到画布上的位置。使用ctx.translate()
,两个参数x和y确定圆的移动距离; x是水平方向移动的距离; y是沿垂直方向移动的距离。
问题是移动后您不再知道画布上的位置坐标。因此,在进行下一个ctx.translate()
操作之前,需要重置原点。
要重置原点,请使用CanvasRenderingContext2D.setTransform()
,例如
ctx.setTransform(1, 0, 0, 1, 0, 0);
Canvas 2D的CanvasRenderingContext2D.setTransform()方法 API重置(替代)当前对身份的转换 矩阵,然后调用参数描述的转换 这种方法。这使您可以缩放,旋转,平移(移动)和 倾斜上下文。
此API专为动画绘制而设计,它具有多种动态转换2D形状的方法。对于您的代码而言,足以理解通过清除身份矩阵,您可以还原0,0
(画布原点)作为在随后的任何绘制操作中使用的x和y值的参考。使用ctx.translate()
之前,请重设原点。观察代码启动时的区别。
启动时重置原点的效果
无论何时绘制新图像,都必须首先使用ctx.clearRect()
清除整个画布,并且在重置原点之前非常重要。在每个示例中单击“更改大小”按钮,以查看通过重置原点清除了整个屏幕。如果不进行重置,则清除的矩形的原点将与绘制的最后一个圆的中心对齐,即清除的矩形将吃入该圆的右下象限。
重置原点在清理画布上的效果
#2
第二个问题可以通过在第一条指令后插入alert(number)
来演示。代码运行时,alert
报告一条NaN
消息(即不是数字)。此外,随机值的范围是0.0到1.0,但出于您的目的,可以将其缩放到5.0到10.0的范围(有关更多信息,请参见here和here)。
下面的代码显示getNewRadius(),
,该函数在单击“更改大小”按钮时会生成一个随机数。在函数被调用之前,常量和变量被声明和初始化。每次调用该函数时,即每次单击鼠标,它都会返回一个新的随机值radius
,然后将其作为参数传递给下一个绘图函数。
为清楚起见,我将变量number
重命名为更容易解释的radius
,并用一些恰当命名的constant
或var
替换了代码中的幻数。
#3
在if
和else 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();
}