我是html画布的新手。我试图旋转两个轮子看起来旋转形成像汽车的底座(例如)但是,下面的代码围绕第一个轮子旋转第二个轮子(当它在中心旋转时)。 / p>
function wheel(rot,angle) {
c.save();
c.beginPath();
this.rot = rot;
for(var i =0; i<2*Math.PI; i = i + 0.01) {
var x = 50 * Math.cos(6 * i) * Math.cos(i);
var y = 50 * Math.cos(6 * i) * Math.sin(i);
c.lineTo(x, y);
}
if(this.rot===1) {
c.fill();
}else{
c.stroke();
}
}
var slider1 = document.getElementById('slider1');
var slider2 = document.getElementById('slider2');
slider2.value =1;
slider1.value = 1;
function draw() {
c.clearRect(-450, -450, canvas.width, canvas.height);
c.save();
c.rotate(slider2.value);
wheel(1);
c.restore();
c.save();
c.translate(200, 200);
wheel(2);
c.restore();
c.restore();
window.requestAnimationFrame(draw);
}
c.save();
c.translate(400, 200);
draw();
我认为我的错误在于放置c.save()和c.restore()但是 我不确定。
答案 0 :(得分:0)
您的代码中的主要问题是c.save()
函数中的wheel
调用不平衡。您对save
和restore
的其他用法很好,但通常这些调用需要进行平衡(还要考虑嵌套函数调用,例如wheel
函数)。这类似于数学方程中的平衡括号或代码块中的平衡括号。
如果删除除save
和restore
来电之外的所有代码,则很容易看出出现了什么问题。保持心理计数器,从零开始并为每个save
呼叫添加1,并为每个restore
呼叫减去1。最后,你应该回到零。
function wheel(rot,angle) {
c.save();
}
function draw() {
// counter = 0
c.save();
// counter = 1
wheel(1); // contains save() call
// counter = 2
c.restore();
// counter = 1
c.save();
// counter = 2
wheel(2); // contains save() call
// counter = 3
c.restore();
// counter = 2;
c.restore();
// counter = 1;
}
我们在draw()函数的末尾,我们的计数器等于1.某些东西是不平衡的,并且快速分析显示wheel()函数是罪魁祸首,其无法匹配的save()调用。
wheel
函数不会改变画布状态,因此它实际上不需要使用保存和恢复。如果从wheel函数中删除save()调用,事情几乎是平衡的。最后一个更改是在draw()结束时删除冗余restore()调用。
以下是您可以运行的包含这些更改的片段,以及其他一些可以启用两个轮子的独立旋转的片段。
var canvas = document.querySelector('canvas');
var c = canvas.getContext('2d');
var slider1 = document.getElementById('slider1');
var slider2 = document.getElementById('slider2');
function wheel(rot,angle) {
c.beginPath();
this.rot = rot;
for(var i =0; i<2*Math.PI; i = i + 0.01) {
var x = 50 * Math.cos(6 * i) * Math.cos(i);
var y = 50 * Math.cos(6 * i) * Math.sin(i);
c.lineTo(x, y);
}
if(this.rot===1) {
c.fill();
}else{
c.stroke();
}
}
function draw() {
c.clearRect(-100, -100, canvas.width, canvas.height);
c.save();
c.rotate(slider1.value);
wheel(1);
c.restore();
c.save();
c.translate(200, 0);
c.rotate(slider2.value);
wheel(2);
c.restore();
window.requestAnimationFrame(draw);
}
c.save();
c.translate(100, 100);
draw();
<input id="slider1" type="range" min="0" max="6.28" step="0.01" />
<input id="slider2" type="range" min="0" max="6.28" step="0.01" />
<canvas width="400" height="300"></canvas>