Frage

Ich versuche, Elemente auf dem zu animieren <canvas> Aber SetTimeout und SetInterval geben mir Probleme. Meine Daten sind in einem Array. Ich bekomme seine Länge. Für jeden Knoten erzeuge ich ein x und ein y, eine Kardinalrichtung und eine Farbe. Dann zeichnet meine Zeichenfunktion einen Kreis für jeden dieser Knoten.

Meine Probleme treten auf, wenn ich versuche, mit einem SetInterval zu schieben. Mein Gedanke war, dass ich alle X-, y-Werte festlegen konnte, dann zurückschieben und sie jedes 10 ms-100 ms inkrementieren konnte. Aber jedes Mal, wenn ich setInterval verwende, erhalten meine untergeordneten Arrays, die die Daten für jeden Kreis enthalten, eine Länge von 3 und die Werte werden auf undefiniert eingestellt.

Ich habe dies einmal mit verschiedenen Objekten codiert, konnte aber die Animation nicht zum Laufen bringen. Ich habe die Probleme mit Scoping setInterval () in Objekten erfahren. Ich habe es neu kodiert, ohne eine Reihe von Objekten zu etablieren. Immer noch kein Glück.

$(document).ready(function(){
    getTweets();
});

CTX = $('#tweets')[0].getContext("2d");
WIDTH = $('#tweets').width();
HEIGHT = $('#tweets').height();
RADIUS = 10;
TWEETS = [];
CORDS = [];
DIRECTION = ['north','east','south','west'];

function getTweets(){
    $.getJSON("http://search.twitter.com/search.json?callback=?&q=scion&rpp=100",
    function(r){
        var numberOfTweets = r.results.length;
        while(numberOfTweets--){
            TWEETS.push(r.results[numberOfTweets].text);
        }
        plotXY();
        animateTweets()
    });
}

function animateTweets(){
    return setTimeout(plotXY(true),100);
}

function plotXY(animating){
    if(!animating){
        var numberOfTweets = TWEETS.length;
        while(numberOfTweets--){
            var topY = Math.ceil(Math.random()*(HEIGHT-20)),
                leftX = Math.ceil(Math.random()*(WIDTH-20)),
                cardinal = Math.floor(Math.random()*4),
                color = '#'+Math.floor(Math.random()*16777215).toString(16);

            var valCords = validateCords(leftX, topY);
            CORDS.push([valCords[0], valCords[1], cardinal, color]);
        }
        // console.log('animating false');
        // console.log(CORDS);
    }
    else{
        var numberOfTweets = TWEETS.length;
        while(numberOfTweets--){
            if(CORDS[numberOfTweets][2]=='north'){ //NORTH
                CORDS[numberOfTweets][1]+=2;
                CORDS[numberOfTweets][0]+=2;
            }
            if(CORDS[numberOfTweets][2]=='east'){ //EAST
                CORDS[numberOfTweets][1]+=2;
                CORDS[numberOfTweets][0]-=2;
            }
            if(CORDS[numberOfTweets][2]=='south'){ //SOUTH
                CORDS[numberOfTweets][1]-=2;
                CORDS[numberOfTweets][0]-=2;
            }
            if(CORDS[numberOfTweets][2]=='west'){ //WEST
                CORDS[numberOfTweets][1]-=2;
                CORDS[numberOfTweets][0]+=2;
            }

            var valCords = validateCords(leftX, topY, numberOfTweets);

            CORDS.push([valCords[0],valCords[1],cardinal]);
            CORDS.shift();          
        }
        // console.log('animating true');
        // console.log(CORDS);
    }
    drawCircles();
}


function drawCircles(){
    console.log('drawing');
    var numOfCords = CORDS.length;
    clear();

    while(numOfCords--){
        CTX.fillStyle = CORDS[numOfCords][3];
        CTX.beginPath();
        CTX.arc(CORDS[numOfCords][0], CORDS[numOfCords][1], RADIUS, 0, Math.PI*2, true);
        CTX.closePath();
        CTX.fill();
    }
}
War es hilfreich?

Lösung

Ich weiß nicht, ob dies das einzige Problem in Ihrem Code ist, aber ein erhebliches Problem ist die Art und Weise, wie Sie es verwenden setTimeout():

setTimeout(plotXY(true), 100); // doesn't work

Das heißt das, das anzurufen plotXY() Funktion und dann übergeben, was auch immer es zurückgibt, als erster Parameter zu setTimeout.

Stattdessen der erste Parameter zu setTimeout() sollte ein Funktionsausdruck oder einen Verweis auf eine Funktion wie folgt sein:

setTimeout(plotXY, 100);      // works, but doesn't pass parameter to plotXY()

Beachten Sie, dass plotXY tut nicht zu diesem Zweck Klammern haben. Aber natürlich hinterlässt Sie ein anderes Problem: Sie wollen plotXY() mit dem Parameter aufgerufen werden true. Das wird leicht gelöst, indem der Anruf an eingewickelt wird plotXY() in einer anderen Funktion und übergeben diese andere Funktion an setTimeout():

setTimeout(function(){ plotXY(true); }, 100);     // works

Das schafft eine anonyme Funktion und übergibt diese Funktion an setTimeout().

Sie möchten wahrscheinlich anrufen setTimeout() wieder am Ende deines plotXY() Funktion oder verwenden setInterval(), Andernfalls hat Ihre Animation nur einen Schritt. Oder Sie können so etwas wie Folgendes tun, was sowohl eine andere Möglichkeit zeigt, um das Problem des Parameters zu lösen setTimeout():

function plotXYProxy() {
   plotXY(true);
   setTimeout(plotXYProxy, 100);
}
plotXYProxy();

Natürlich können Sie eine bedingte Verarbeitung in innerhalb hinzufügen plotXYProxy() Um zu entscheiden, ob Sie jeden Zeitpunkt festlegen, z. B. Sie könnten haben plotXY() Geben Sie einen Booleschen zurück, ob die Animation beendet ist, und rufen Sie an setTimeout() oder nicht auf diesem Booleschen. Oder was auch immer Anzüge.

Alles, was ich gerade über die Parameter von gesagt habe setTimeout() gilt auch für setInterval().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top