我是一个总菜鸟,我正在使用HTML5 Canvas和JS处理“素数”绘图/动画。我在'for'循环中遇到了困难,因为浏览器只在'for'循环完成后才显示绘图,而不是在它工作时显示(显示每个循环的输出,如动画)。
HTML / CSS:
<!doctype html>
<html>
<head>
</head>
<style>
body
{
background: #999999
}
#canvas
{
background: white;
border: 19px solid black;
}
</style>
<body>
<canvas id="canvas" width="4000" height="4000">
Bájate un nuevo navegador!!
</canvas>
<script src="jscode.js"></script>
</body>
</html>
JS(jscode.js):
var canvas1 = document.getElementById('canvas');
var context = canvas.getContext ('2d');
// Text properties
context.font = '32pt Arial';
context.fillStyle = 'DeepSkyBlue';
context.StrokeStyle = 'DarkSlateGray';
// Line properties
context.StrokeStyle = "rgb (200,0,0)";
context.lineWidth = 1;
// Each Natural number is represented by a segment
// "t" corresponds to the length of each segment.
var t = 3;
// Starting position within the canvas.
var x = 500;
var y = 500;
//Array stores every movement's direction.
//(We need to know the last segment direction in order "continue" the drawing)
var Dmemory = new Array();
// Drawing using a Path function.
// Drawing "manually".
context.beginPath();
//0
context.moveTo(x,y);
Dmemory [0] = "A";
//1
/*UP*/ var y = y - t;
context.lineTo(x,y);
Dmemory [1] = "A";
// Continue using a "for" loop.
// Variable "num" is the LIMIT. The program will run until the loop gets to this number.
var num = 10000;
// The program begins with 1 and starts counting adding 1+.
for (i=2 ; i < num ; i++ )
{
//Creating a "Divisors tracking variable".
//We are going to divide each number between all the natural numbers below to verify if its a prime.
var contador = 0;
for ( div = i ; div > 0 ; div--)
{
if (i%div == 0)
{
contador = contador + 1;
}
//Breaking condition: More than 2 divisors.
if (contador>2)
{
break;
}
}
//Primes Test: Primes have ONLY two divisors: Themselves and number One
if (contador == 2)
{
//If Prime: check the last movements direction and proceed.
switch (Dmemory[i - 1])
{
case "A":
var y = y - t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="D";
break;
case "B":
var y = y + t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="I";
break;
case "D":
var x = x + t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="B";
break;
case "I":
var x = x - t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="A";
}
}
else
{
//If not Prime: check the last movement direction and proceed.
switch (Dmemory[i - 1])
{
case "A":
var y = y - t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="A";
break;
case "B":
var y = y + t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="B";
break;
case "D":
var x = x + t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="D";
break;
case "I":
var x = x - t;
context.lineTo(x,y);
context.stroke();
Dmemory[i]="I";
break;
}
}
}
我一直在阅读其他答案,现在我明白了主要原因:网络浏览器中的JavaScript是单线程的。
但是,有什么方法可以实现我的需要吗? (我需要的是:随着循环的进行在屏幕上显示绘图)
提前谢谢你,
来自利马的问候 - 秘鲁
答案 0 :(得分:0)
为了能够报告进度,您必须在给定的时间间隔内进行计算,以便系统获得足够的时间来“呼吸”。
下面是一个假定的间隔计算,将定期调用。我希望它可以帮助您找到解决方案。
http://jsbin.com/qarivina/1/edit?js,output
var canvas = document.getElementById('canvas');
var context = canvas.getContext ('2d');
setupNow();
function computeFromTo(i1, i2) {
var st = now();
for (var i=i1; i<i2; i++) computeForIndex(i);
var ed = now();
var timeTaken = (ed-st);
}
function computeForIndex(i) {
var res = Math.pow(i,2.5)/Math.abs(1 + Math.sin(i));
}
function beginCallCompute() {
var startIndex = 0 ;
var indexIncrease = 500 ;
var lastIndex = 500000;
var computeInterval = setInterval(callCompute, 5);
function callCompute() {
computeFromTo(startIndex, startIndex+indexIncrease);
startIndex += indexIncrease;
context.clearRect(0,0,canvas.width, canvas.height);
context.fillText(startIndex, 20, 20);
if (startIndex>=lastIndex) {
clearInterval(computeInterval);
}
}
}
beginCallCompute();
// ---------------------------
function setupNow() {
window.now = ( performance && performance.now.bind(performance) )|| Date.now ;
}