1

so I am trying to dynamically create shapes based on a number pulled from a database. I've tried the most logical way of wrapping a for loop around creating a shape and subsequently adding the shape into a layer. But for some reason unknown to me, it keeps re-modifying the same shape even though the shapes stored in the layer should be at different positions (and different attributes).

My code is the following:

function graph(w) {
        barLayer.removeChildren();
        var bar = new Array();

        for (var i = 1; i <= array.length; i++) {
            var pos = i * Math.PI / 30;
            var scaleUp = (i / array.length) * 2.5;
            bar[i-1] = new Kinetic.Shape({
                drawFunc: function(context) {
                    context.beginPath();
                    context.moveTo(radius2, radius2);
                    context.arc(radius2, radius2, scaleUp * radius2, (- Math.PI / 2) - w + pos, (- Math.PI / 2) - w + (Math.PI / 30) + pos, false);
                    context.closePath();
                    this.stroke(context);
                    this.fill(context);
                },
                fill: "#333",
                stroke: "#000",
                strokeWidth: 4,
                x: centerX,
                y: centerY,
                offset: [200,200],
            });
            console.log("Starting: ", (- Math.PI / 2) - w + pos, "/ Ending: ",  (- Math.PI / 2) - w + (Math.PI / 30) + pos);
        }

        for (var n = 0; n < bar.length; n++) {
            barLayer.add(bar[n]);

        }
        barLayer.draw();
    }

I've tried everything from putting the shapes in an Array to just creating a new shape and adding it in within the for loop. I'm definitely missing something.

I have done a bit of searching regarding this topic and I found one comment relevant to what I'm trying to do:

Basically, you need need to keep an array of shape objects and push new objects onto the array when you add a new shape. Within the setDrawStage() method of the kin object, just loop through the array and draw each object. I’ll let you know when I get the lab published.

I've looked all over for a setDrawStage() method and I can't find much data associated with it. He also stated to put the for loop inside the method which is a bit confusing as I do not only want to draw the shape but also store it in a layer (as I have done for every other shape).

Does anyone possibly have a solution? Much appreciated in advanced.

kaiwah.ng
  • 267
  • 2
  • 15

2 Answers2

1

I think you're having a JavaScript closure problem. More on that:

How do JavaScript closures work?

Try moving all of the logic inside the for loop into a function to induce scope. Also, instead of using Kinetic.Shape, why not use Kinetic.Circle?

Community
  • 1
  • 1
Eric Rowell
  • 5,191
  • 23
  • 22
  • Thanks! It worked well now, never fully understood the nature of closures. Anyhow, I am using Shape instead of Circle because I was drawing bar graphs (using radius as height) inside a circle, so shape seemed to be the most obvious route to accomplish that. – kaiwah.ng Nov 04 '12 at 02:02
  • 1
    hey, it would be great if you could add a jsfiddle or the code directly. I don't get it to work :/ – Dominik Jul 01 '13 at 13:14
0

X and Y in your script do not change as far as I can tell so your shape will always start from the same position?

Roman C
  • 49,761
  • 33
  • 66
  • 176