Pergunta

Estou tentando criar uma luz estroboscópica básica no navegador usando o elemento canvas.Espero que setInterval continue chamando a função changeBG para mudar para uma cor de fundo aleatória.Esta função funciona bem sozinha, mas não quando chamada por setInterval.Tentei abrir esta página no firebug e me disse que as cores eram indefinidas.Aqui está o código problemático.

<html>
<head>
    <title>Strobe!</title>
    <link rel="stylesheet" type="text/css" href="reset.css" />
    <script type="text/javascript">
        function changeBG(colors,ctx,canvas) {                
            ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)]
            ctx.fillRect(0,0,canvas.width,canvas.height)
        }

        function eventLoop() {
            var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']
            var canvas = document.getElementById('mainCanvas')
            var ctx = canvas.getContext('2d')
            canvas.width = window.innerWidth
            canvas.height = window.innerHeight
            //changeBG(colors,ctx,canvas)
            setInterval("changeBG(colors,ctx,canvas)", 1000);               
        }
    </script>
</head>
<body onload="eventLoop()">
    <canvas id="mainCanvas" width="800" height="600">
    </canvas>
</body>

Eu sou novo em javascript, então qualquer insight seria muito apreciado.

Foi útil?

Solução

Seu código funcionaria se você não estivesse passando uma string para setInterval.Por estar em uma string, não é possível criar um fechamento nas variáveis ​​que você está tentando usar.

Em vez disso, tente isto:

setInterval(function() {
    changeBG(colors,ctx,canvas);
}, 1000)​;​

Usando este método, você está passando uma função anônima para setInterval.Ele chamará essa função uma vez por intervalo, que neste exemplo é de 1.000 milissegundos.

A função pode usar as variáveis ​​cores, ctx e canvas porque elas existem no escopo onde a função é declarada.Isso cria um fechamento para que essas variáveis ​​ainda existam (no que diz respeito à nossa função anônima) quando ela for chamada repetidamente.

Por enquanto, você provavelmente pode apenas usar este código.Para maior compreensão, sugiro pesquisar funções e encerramentos anônimos.

Outras dicas

Você pode passar diretamente uma função, em vez de uma string para avaliar, como

setInterval(function(){changeBG(colors,ctx,canvas)}, 1000);

Boa sorte provocando epilepsia para alguém

A raiz do problema é o escopo da variável quando o código de intervalo é executado, as cores e as outras variáveis ​​não estão no escopo.

Experimente isto:

<html>
<head>
<title>Strobe!</title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript">           
    function eventLoop() {
        var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']
        var canvas = document.getElementById('mainCanvas')
        var ctx = canvas.getContext('2d')
        canvas.width = window.innerWidth
        canvas.height = window.innerHeight            
        setInterval(function() {                
            ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)]
            ctx.fillRect(0,0,canvas.width,canvas.height)
        }, 1000);               
    }    
</script>
</head>
<body onload="eventLoop()">
    <canvas id="mainCanvas" width="800" height="600">
    </canvas>
</body>

Experimente este atualizadosetInterval(function(){changeBG(colors,ctx,canvas)}, 1000);

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top