0

When I run the tick() function once it works flawlessly, but when I loop it using setInterval(this.tick,this.interval) all the functions in tick() give the following error: Uncaught TypeError: this.{a function} is not a function.

This is the full code:

function Particles(settings){
this.canvas = document.getElementById('particle-js');
this.context = this.canvas.getContext('2d');
this.fps = 60;
this.interval = 1000/this.fps;
this.TWO_PI = Math.PI*2;
this.mousePosition;


this.tick = function(){
    console.log("tick");


    this.drawNodes();
    this.clear();

}

setInterval(this.tick,this.interval);

this.generateNodes = function generateNodes(){
    var nodes = [];


    for(var i = 0; i < 1; i++){
        var node = {
            origin: {
                x: this.random(0, this.canvas.width),
                y: this.random(0, this.canvas.height)
            },
            direction: this.random(0,359),
            subNodes: []
        }
        for(var j = 0; j < this.random(1,8); j++){
            var subNode = {
                xOffset: this.random(-50,50),
                yOffset: this.random(-50,50),
                distance: function(){
                    var x = Math.pow(this.xOffset,2);
                    var y = Math.pow(this.yOffset,2);
                    return Math.sqrt(x + y);
                }
            }
            while(subNode.distance() < 20){
                subNode = {
                    xOffset: this.random(-50,50),
                    yOffset: this.random(-50,50),
                    distance: function(){
                        var x = Math.pow(this.xOffset,2);
                        var y = Math.pow(this.yOffset,2);
                        return Math.sqrt(x + y);
                    }
                }
            }
            node.subNodes.push(subNode);
        }
        nodes.push(node);
    }

    console.log("generated: " + nodes.length);

    return nodes;
}

this.canvas.addEventListener('mousemove', function(evt) {
    if(evt.offsetX) {
        mouseX = evt.offsetX;
        mouseY = evt.offsetY;
    }
    else if(e.layerX) {
        mouseX = evt.layerX;
        mouseY = evt.layerY;
    }
    this.mousePos = {
        x: mouseX,
        y: mouseY
    }
}, false);

this.drawNodes = function drawNodes(){
    for(var k = 0; k < this.nodes.length; k++){
        var current_node = this.nodes[k];
        this.fillCircle(current_node.origin.x,current_node.origin.y, 3);

        for(var l = 0; l < current_node.subNodes.length; l++){
            var current_subNode = current_node.subNodes[l];

            this.fillLine(current_node.origin.x,current_node.origin.y,current_node.origin.x + current_subNode.xOffset, current_node.origin.y + current_subNode.yOffset)
            this.fillCircle(current_node.origin.x + current_subNode.xOffset, current_node.origin.y + current_subNode.yOffset, 2);
        }
    }
}

this.fillCircle = function fillCircle(x, y, radius, color){
    if(color == undefined || color == false){
        color = "black";
    }
    this.context.fillStyle = color;
    this.context.beginPath();
    this.context.arc(x,y,radius,0,this.TWO_PI,false);
    this.context.fill();
}
this.fillLine = function fillLine(xFrom, yFrom, xTo, yTo, color){
    if(color == undefined || color == false){
        color = "black";
    }
    this.context.beginPath();
    this.context.moveTo(xFrom,yFrom);
    this.context.lineTo(xTo, yTo);
    this.context.lineWidth = 1;
    this.context.stroke();
}
this.clear = function clear(color){
    if(color == undefined || color == false){
        color = "white";
    }
    this.context.fillStyle = color;
    this.context.fillRect(0,0,this.canvas.width,this.canvas.height);
}

this.random = function random(min, max){
    return min+Math.round((max-min)*Math.random());
}

this.nodes = this.generateNodes();

}

The following is shown in console:

Result in console

Nathan Prins
  • 383
  • 1
  • 4
  • 16

1 Answers1

2

That's because the setTimeout callback function's context isn't bound to your object, try this instead:

setInterval(this.tick.bind(this), this.interval);
Rob M.
  • 35,491
  • 6
  • 51
  • 50