2013-05-21 45 views
4

我目前正在尝试使用JavaScript/JQuery和HTML5画布制作一个小型pythagoras树应用程序。使用JavaScript和HTML5画布显示绘画过程

该算法工作正常,但可悲的是我无法看到绘图的过程。 UI完成后冻结并显示整个图形。

当前的行为:http://www.kappelcation.com/index.php?contentid=4 这是行为我想有:http://www.jjam.de/Java/Applets/Fraktale/Pythagoras_Baum.html(你需要允许Java的小程序,并单击几次看到图纸的进度)。

$(document).ready(function(){ //just some listeners and initialization 
initCanvas(); 

$(autOrManSelect).change(function(){ 
    if(($(this).val()==1)) //changed from manual to automatic 
    { 
     $(pythagorasCanvas).click(); 
    } 
}); 
$(startButton).click(function(event){ 
    $(this).unbind(event); 
    $(this).html('Add Leaves'); 
    $(restartButton).css("visibility", "visible"); 
    startTree(); 
    $(this).click(function(){ 
     var next = parseInt($(depthInput).val())+1; 
     $(depthInput).val(next); 
     $(pythagorasCanvas).click(); 
    }); 
}); 
$(restartButton).click(function(){ 
    startTree(); 
}); 
}); 

function initCanvas() //adjust size, clear the canvas and draw a boarder 
{ 
var canvas = document.getElementById("pythagorasCanvas"); 
canvas.height=600; 
canvas.width=$(mainDiv).width()-40; 
$(pythagorasCanvas).unbind("click"); 
if (canvas.getContext) 
{ 
    var context = canvas.getContext("2d"); 
    //clear canvas 
    drawRectangle(context, new Point(0,canvas.height), new Point(canvas.width,canvas.height), new Point(canvas.width,0), new Point(0,0), "#FFFFFF"); 
    //draw border for canvas 
    drawRectangle(context,new Point(0,canvas.height),new Point(canvas.width,canvas.height), new Point(canvas.width, 0),new Point(0,0), '#000000', true); 
} 
} 

function startTree() //start drawing process 
{ 
initCanvas(); 
var canvas = document.getElementById("pythagorasCanvas"); 
if (canvas.getContext) 
{ 
    var context = canvas.getContext("2d"); 
    var rectLength = parseInt($(firstSquareInput).val()); 
    var startWidth = canvas.width/2-rectLength/2; 
    var startHeight = canvas.height-canvas.height/4; 
    var startA = new Point(startWidth, startHeight); 
    var startB = new Point(startWidth+rectLength, startHeight);  
    drawBranch(context, startA, startB, 0); 
} 
} 

function Point(x, y) { 
this.x = x; 
this.y = y; 
} 

function drawBranch(context, a, b, depth) //gets called recursively 
{ 
var maxDepth = $(depthInput).val(); 
if(depth<maxDepth) 
{ 
    depth++; 
    //calculate positions of current rectangle 
    var dx = b.x - a.x; 
    var dy = a.y - b.y; 
    var c = new Point(b.x-dy, b.y-dx); 
    var d = new Point(a.x-dy, a.y-dx); 
    //draw current rectangle 
    drawRectangle(context, a, b, c, d); 

    //calculate new position 
    var offSetX; 
    if($(triangleOffsetInput).val().toLowerCase()=="random") 
    { 
     offSetX = Math.random(); 
    } 
    else 
    { 
     offSetX = parseFloat($(triangleOffsetInput).val())/100; //first offset in x-direction (in relation to a square length of 1) 
    } 
    var offSetY = -Math.sqrt(Math.pow(0.5,2)-Math.pow((0.5-offSetX),2)); //Pythagoras to get the offset in y (negative sign necessary because the y-values get smaller upwards) 
    var e = new Point(d.x + offSetX*(c.x-d.x) + offSetY*(a.y-b.y), d.y + offSetX*(c.y-d.y) + offSetY*(b.x-a.x)); 

    if($(fillTriangleBox).prop("checked")) 
    { 
     drawTriangle(context, c, d, e); 
    } 

    var autOrMan = $(autOrManSelect).val(); 
    if(autOrMan==1) 
    { 
     //draw new positions 
     drawBranch(context, d, e, depth); 
     drawBranch(context, e ,c, depth);  
    } 
    else 
    { 
     $(pythagorasCanvas).click(function(event) 
     { 
      $(this).unbind(event); 
      drawBranch(context, d, e, depth); 
      drawBranch(context, e ,c, depth);  
     }); 
    } 
} 
else 
{ 
    $(pythagorasCanvas).click(function(event) 
    { 
     $(this).unbind(event); 
     drawBranch(context, a, b, depth); 
    }); 
} 
} 

function drawTriangle(context, c, d, e, color) 
{ 
if(typeof(color)==='undefined') 
{ 
    color='#'+$(triangleColorInput).val(); 
} 
context.strokeStyle = color; 
context.beginPath(); 
context.moveTo(c.x, c.y); 
context.lineTo(d.x, d.y); 
context.lineTo(e.x, e.y); 
context.closePath(); 
context.fillStyle = color; 
context.fill(); 
context.stroke(); 
} 

function drawRectangle(context, a, b, c, d, color, ignoreFill) 
{ 
if(typeof(color)==='undefined') 
{ 
    color='#'+$(rectColorInput).val(); 
} 
if(typeof(ignoreFill)==='undefined') 
{ 
    ignoreFill=false; 
} 
context.strokeStyle = color; 
context.beginPath(); 
context.moveTo(a.x, a.y); 
context.lineTo(b.x, b.y) 
context.lineTo(c.x, c.y); 
context.lineTo(d.x, d.y); 
context.closePath(); 
if($(fillRectBox).prop("checked") && !ignoreFill) 
{ 
    context.fillStyle = color; 
    context.fill(); 
} 
context.stroke(); 
} 

我曾尝试使用的setTimeout()函数来使拉丝工艺异步达到预期的行为,但我无论是在执行它或的setTimeout()在这种情况下不利于可怕的失败。

我希望你能给我一个提示。提前致谢!

回答

1

我认为以下(未经测试)修改使用的setTimeout您drawBranch功能应该工作

if(autOrMan==1) 
{ 
    //draw new positions 
    setTimeout(function() { 
     drawBranch(context, d, e, depth); 
     drawBranch(context, e ,c, depth);  
    }, 0); 
} 
else 
{ 
    $(pythagorasCanvas).click(function(event) 
    { 
     $(this).unbind(event); 
     drawBranch(context, d, e, depth); 
     drawBranch(context, e ,c, depth);  
    }); 
} 
+0

作品!非常感谢! :) – Refrigerator

+0

现在修好了! (我把setTimeout放在了错误的位置!) –

+0

顺便说一句,你的回答非常快。我很惊讶。再次感谢 :) – Refrigerator

1

冷极了,因为JavaScript is single-threaded。递归调用drawBranch,而不是通过setTimeout递归调度,然后脱离函数。这将使浏览器有时间重画画布。