2017-03-04 53 views
4

首先,我是新来的画布,我一直试图围绕这个包裹2天,所以我非常感谢任何帮助。我的目标是让绿色矩形一次向上移动1个像素(这个数量目前并不重要),但是我最终也会想要为红色的做同样的事情。如果我注释了for循环,你可以在我想要的起始位置看到矩形,但是当我将for循环添加回画布时,在理论上我是希望绿色矩形向上移动。 (或者向下,实际上并不重要)。如何使用for循环来移动画布中的矩形位置

$(document).ready(function() { 
 
    var canvas = document.getElementById("canvas"), 
 
    ctx = canvas.getContext("2d"), 
 
    cw = canvas.width, 
 
    ch = canvas.height; 
 

 

 
    function rectangles() { 
 

 
    var y = 0; 
 
    // Starting point rectangles 
 
    ctx.save(); 
 
    ctx.clearRect(0, 0, cw, ch); 
 
    ctx.beginPath(); 
 
    ctx.fillStyle = "#006847"; 
 
    ctx.fillRect(0, 0, 200, 450); 
 
    ctx.closePath(); 
 

 
    ctx.beginPath(); 
 
    ctx.fillStyle = "#CE1126"; 
 
    ctx.fillRect(400, 0, 200, 450); 
 
    ctx.closePath(); 
 

 
    ctx.save(); 
 
    /*for (i = 0; i < 450; i++) { 
 
     y = y + 1; 
 
     ctx.beginPath(); 
 
     ctx.fillRect(0, y, 200, 450); 
 
     ctx.closePath(); 
 
     ctx.clearRect(0, 0, cw, ch); 
 
    }*/ 
 
    } 
 

 
    setInterval(rectangles, 2000); 
 
});
CSS : #canvas { 
 
    border: 3px #000 solid; 
 
    margin: 0 auto; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div id="canvas-container"> 
 
    <canvas id="canvas" height="450" width="600"></canvas> 
 
</div>

回答

3

不需要一个for循环。您只需使用if语句即可完成此操作。

$(document).ready(function() { 
 
    var canvas = document.getElementById("canvas"), 
 
     ctx = canvas.getContext("2d"), 
 
     cw = canvas.width, 
 
     ch = canvas.height, 
 
     GY = 0, 
 
     RY = 0; 
 

 
    rectangles(); 
 

 
    function rectangles() { 
 
     if (GY > -450 && RY > -450) { 
 
      GY -= 1; // pixel 
 
      RY -= 1; 
 
     } else if (GY == -450 && RY == -450) { 
 
      GY = 450; 
 
      RY = 450; 
 
     } 
 
     // Starting point rectangles 
 
     ctx.clearRect(0, 0, cw, ch); 
 
     // green 
 
     ctx.fillStyle = "#006847"; 
 
     ctx.fillRect(0, GY, 200, 450); 
 
     // red 
 
     ctx.fillStyle = "#CE1126"; 
 
     ctx.fillRect(400, RY, 200, 450); 
 
     requestAnimationFrame(rectangles); 
 
    } 
 
});
#canvas { 
 
    border: 3px #000 solid; 
 
    margin: 0 auto; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="canvas-container"> 
 
    <canvas id="canvas" height="450" width="600"></canvas> 
 
</div>

+0

谢谢你提供这个。 @暹 – Xander

0

简短的回答是:你不能。

原因是:您的浏览器不会呈现任何东西,直到您的脚本完成执行(因为只有当浏览器回到它的渲染上下文)。

使用​​:https://developer.mozilla.org/de/docs/Web/API/window/requestAnimationFrame

$(document).ready(function() { 
    var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"), 
    cw = canvas.width, 
    ch = canvas.height; 

    var y = 0; 

    function rectangles() { 

    // Starting point rectangles 
    ctx.save(); 
    ctx.clearRect(0, 0, cw, ch); 
    ctx.beginPath(); 
    ctx.fillStyle = "#006847"; 
    ctx.fillRect(0, 0, 200, 450); 
    ctx.closePath(); 

    ctx.beginPath(); 
    ctx.fillStyle = "#CE1126"; 
    ctx.fillRect(400, 0, 200, 450); 
    ctx.closePath(); 

    ctx.save(); 
    y++; 

    ctx.beginPath(); 
    ctx.fillRect(0, y, 200, 450); 
    ctx.closePath(); 
    ctx.clearRect(0, 0, cw, ch); 
    if (y < 450) 
     requestAnimationFrame(rectangles); 
    } 


    setInterval(rectangles, 2000); 
}); 
0

编辑:罗确实在这之后一个更好的答案:HERE

画布变成空白,因为在功能上的矩形(),for循环计算位置,并绘制矩形在眨眼之间,在我们看到任何动画之前向我们展示最终状态(这是空白的)。

所以我们在每次绘制新的矩形之间放了一些时间。我还添加了一个索引来记录已经过去了多少时间,以计算矩形的新位置。请检查该代码段并发表评论,看看是否需要。

$(document).ready(function() { 
 
    var canvas = document.getElementById("canvas"), 
 
     ctx = canvas.getContext("2d"), 
 
     cw = canvas.width, 
 
     ch = canvas.height; 
 
     step = 1; // Distance the rectangle move each time 
 
     refresh = 10; // Repaint interval 
 
     var i = 0; // Record how far has the rectangle go 
 

 
    function rectangles() { 
 
     // Starting point rectangles 
 
     ctx.save(); 
 
     ctx.clearRect(0, 0, cw, ch); 
 
     ctx.beginPath(); 
 
     ctx.fillStyle = "#006847"; 
 
     // Leave blank area with height: i*step 
 
     ctx.fillRect(0, 0, 100, ch-i*step); 
 
     ctx.closePath(); 
 

 
     ctx.beginPath(); 
 
     ctx.fillStyle = "#CE1126"; 
 
     ctx.fillRect(200, 0, 100, ch-i*step); 
 
     ctx.closePath(); 
 

 
     ctx.save(); 
 
     i ++; 
 
     // The canvas is blank, stop drawing 
 
     if (ch-i*step < 0) { 
 
      clearInterval(interval) 
 
     } 
 
    } 
 
    interval = setInterval(rectangles, refresh); 
 
    });
#canvas { 
 
    border: 3px #000 solid; 
 
    margin: 0 auto; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div id="canvas-container"> 
 
    <canvas id="canvas" height="225" width="300"></canvas> 
 
</div>

+0

非常感谢您@jrying。正是我所期待的,现在我只是打算进一步开发它,让动画循环。 – Xander

+0

不客气。 :) 然后,也许你可以在 '做一些事情if(ch-i * step <0){clearInterval(interval)}' – jrying

+0

对不起,但你的答案很差,-1你可能已经解决了OP的问题,但只是鼓励进一步的坏习惯。不要为'动画使用'requestAnimationFrame'使用'setInterval'(非常糟糕)。不要无故保存状态,不要调用'ctx。保存'没有相应的'ctx.restore'。如果不需要,不要调用'beginPath'或'closePath'。请花时间来创建一个高质量的答案,因为从长远来看,这对OP和其他人无所帮助。 – Blindman67

0

你之所以不能做到是因为画布是单一的实体。在清除画布之前,您无法移动矩形。 clearRect在这里是为了营救。

我创建了函数clearCanvas。它将在重新定位矩形之前运行并清除画布。所以,你正在用新计算的位置每隔两秒钟重新绘制画布。

$(document).ready(function() { 
 
    var canvas = document.getElementById("canvas"), 
 
    ctx = canvas.getContext("2d"), 
 
    cw = canvas.width, 
 
    ch = canvas.height; 
 

 
    var x = 100; 
 
    var y = 100; 
 

 
    function rectangles() { 
 
    clearCanvas(); 
 
    var y = 0; 
 
    // Starting point rectangles 
 
    ctx.save(); 
 
    ctx.clearRect(0, 0, cw, ch); 
 
    ctx.beginPath(); 
 
    ctx.fillStyle = "#006847"; 
 
    ctx.fillRect(x, 0, 50, 50); 
 
    ctx.closePath(); 
 

 
    ctx.beginPath(); 
 
    ctx.fillStyle = "#CE1126"; 
 
    ctx.fillRect(x + 400, 0, 50, 50); 
 
    ctx.closePath(); 
 

 
    ctx.save(); 
 

 

 
    if (x < 10) { 
 
     x = 100; 
 
    } 
 
    x = x - 10; 
 

 
    } 
 

 
    setInterval(rectangles, 400); 
 

 
    function clearCanvas() { 
 
    ctx.clearRect(0, 0, cw, ch); 
 
    } 
 

 
});
#canvas { 
 
    border: 3px #000 solid; 
 
    margin: 0 auto; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div id="canvas-container"> 
 
    <canvas id="canvas" height="450" width="600"></canvas> 
 
</div>