2012-08-28 35 views
2

此脚本无休止地在所有浏览器中记忆。我看不出为什么!Javascript绘制画布内存泄漏

var canvas = document.getElementById("canvas"); 
var ctx = canvas.getContext("2d"); 
var particles = [], amount = 5; 
var x = 100; var y = 100; 
var W, H; 
var p, gradient; 

//dimensions 
if(window.innerHeight){ 
    W = window.innerWidth, H = window.innerHeight; 
}else{ 
    W = document.documentElement.clientWidth, H = document.documentElement.clientHeight; 
} 
canvas.width = W, canvas.height = H; 


//array voor de meerdere particles 
for(var i=0;i<amount;i++){ 
    particles.push(new create_particle()); 
} 

function create_particle(){ 
    //random positie op canvas 
    this.x = Math.random()*W; 
    this.y = Math.random()*H; 

    //random snelheid 
    this.vx = Math.random()*20-10; 
    this.vy = Math.random()*20-10; 

    //Random kleur 
    var r = Math.random()*255>>0; 
    var g = Math.random()*255>>0; 
    var b = Math.random()*255>>0; 
    this.color = "rgba("+r+", "+g+", "+b+", 0.5)"; 
    this.radius = Math.random()*20+20; 

} 

window.requestAnimFrame = (function(){ 
    return window.requestAnimationFrame  || 
      window.webkitRequestAnimationFrame || 
      window.mozRequestAnimationFrame || 
      window.oRequestAnimationFrame  || 
      window.msRequestAnimationFrame  || 
      function(callback){ 
      window.setTimeout(callback, 1000/60); 
      }; 
})(); 

function draw(){ 
    canvas.width = canvas.width; 
    canvas.height = canvas.height; 
    //achtergrond tekenen 
    //ctx.globalCompositeOperation = "source-over"; 
    //ctx.fillStyle = "rgba(0,0,0,0.5)"; 
    ctx.fillRect(0, 0, W, H); 
    //ctx.globalCompositeOperation = "lighter"; 

    //teken cirkel 
    for(var t=0; t<particles.length;t++){ 
     p = particles[t]; 

     //gradient 
     gradient = ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,p.radius); 
     gradient.addColorStop(0,"white"); 
     gradient.addColorStop(0.4,"white"); 
     gradient.addColorStop(0.4,p.color); 
     gradient.addColorStop(1,"black"); 
     ctx.beginPath(); 
     ctx.fillStyle = gradient; 
     ctx.arc(p.x,p.y,p.radius,Math.PI*2,false) 
     ctx.fill(); 

     //beweeg 
     p.x+=p.vx; 
     p.y+=p.vy; 

     //canvas boundery detect 
     if(p.x < -50)p.x = W+50; 
     if(p.y < -50)p.y=H+50; 
     if(p.x > W+50)p.x = -50; 
     if(p.y > H+50)p.y = -50; 
    } 
} 

(function animloop(){ 
    canvas.width = canvas.width; 
    canvas.height = canvas.height; 
    requestAnimFrame(animloop); 
    draw(); 
})(); 


//resize? 
function resizeCanvas(){ 
    canvas.height = W; 
    canvas.width = H; 
    ctx.fillRect(0, 0, W, H); 
} 
if(window.addEventListener){ 
    window.addEventListener('resize', resizeCanvas, false); 
}else{ 
    window.attachEvent('resize', resizeCanvas); 
} 

我试图改变一些代码(这也是最终版本),但它仍然泄漏。如果你使用这个脚本并观看'taskmanager'或浏览器内存检查,你会发现它慢慢地,不断地吃内存。

编辑:在canvas.height解决方案中添加并移动一些声明后,脚本仍然泄漏!我必须说,看起来Firefox比Chrome更难泄露!

+1

不要使用任务管理器。使用Firefox和about:内存选项卡,以便获得准确的报告内存消耗情况。 –

+0

只是一个参考,因为即使在那里,它是比可见..但感谢提示:) – Dominique

+0

嗨。你有没有找到一个答案,除了“有渐变内存泄漏”? –

回答

1

尝试在开始另一套绘图之前清洁画布。您可以通过再次设置宽度和高度来清除它。

下面是一些orientative代码:

function draw() { 
    canvas.width = canvas.width; 
    canvas.height = canvas.height; 

    /* draw */ 
} 
+0

我的第一个结论,当我直接尝试这个,是,这不是解决方案。:( – Dominique

2

您有:

canvas.width = canvas.width; 
    canvas.height = canvas.height; 

我猜这不一样clearRect ......但可以肯定的尝试这也太:

function draw(){ 

    ctx.clearRect (0 , 0 , canvas.width , canvas.height); 

    /* draw */ 
} 

看看有没有变化。

0

我的猜测是你create_particle功能可以泄漏,但林不知道,作为一个想法如何,是创建一个INTERAL对象,而不是使用this

function create_particle(){ 
    return { 
    x: Math.random()*W, 
    y: Math.random()*H, 
    vx: Math.random()*20-10, 
    vy: Math.random()*20-10, 
    r: Math.random()*255>>0, 
    g: Math.random()*255>>0, 
    b: Math.random()*255>>0, 
    color: "rgba("+r+", "+g+", "+b+", 0.5)", 
    radius: Math.random()*20+20, 
    }; 
} 

林不知道如果这是问题,但它似乎是我能真正想到的那种有点奇怪的东西,