I have created a class in my program which uses KineticJS for the "view" part of my MVC design. One of the instance variables in the class is a group which holds multiple rectangular objects. My problem arises when I try to select a specific rectangle in that group by its ID.
I use this.backgroundGroup.get('#id')[0] with no problem in my subMeasure prototype function, but when I try to use it in my drawMeasures prototype function, it stops my canvas from drawing anything. The console in Chrome says "cannot read properties "ids" of undefined".
The only difference between these to uses of the get method is that the subMeasure function is called on the "click" event, and the drawMeasures function is called when View is instantiated.
function View(){
this.status = 0;
this.stage;
//layers
this.backgroundLayer;
this.lineLayer;
this.noteLayer;
this.scanLayer;
this.editLayer;
this.UILayer;
//groups
this.backgroundGroup;
//edit buttons
this.subMeas;
this.addMeas;
this.edit;
this.backgroundArray;
this.lineArray;
}
View.prototype.initialize = function(){
//Initialize stage
this.stage = new Kinetic.Stage({
container: 'tab',
width:1200,
height: 400
});
//Initialize layers
this.backgroundLayer = new Kinetic.Layer();
this.lineLayer = new Kinetic.Layer();
this.noteLayer = new Kinetic.Layer();
this.scanLayer = new Kinetic.Layer();
this.editLayer = new Kinetic.Layer();
this.UILayer = new Kinetic.Layer();
//Initialize edit layer
this.edit = new Kinetic.Rect({
x:0,
y:5,
width:40,
height:20,
fill: 'gray',
stroke: 'black',
strokeWidth: 2
});
this.subMeas = new Kinetic.Rect({
x:40,
y:5,
width:40,
height:20,
fill: 'blue',
stroke: 'black',
strokeWidth: 2
});
this.addMeas = new Kinetic.Rect({
x:80,
y:5,
width:40,
height:20,
fill: 'red',
stroke: 'black',
strokeWidth: 2
});
this.addEditButtonListeners();
this.editLayer.add(this.edit);
this.editLayer.add(this.subMeas);
this.editLayer.add(this.addMeas);
//Initialize Background Layer
this.initBackgrounds();
this.drawBackgrounds();
this.backgroundLayer.add(this.backgroundGroup);
//Initialize Line Layer
this.initLines();
//Initialize Note Layer
this.initNotes();
//Add everything to the stage and display
this.stage.add(this.backgroundLayer);
this.stage.add(this.lineLayer);
this.stage.add(this.noteLayer);
this.stage.add(this.scanLayer);
this.stage.add(this.editLayer);
this.stage.add(this.UILayer);
}
View.prototype.initBackgrounds = function() {
this.backgroundGroup = new Kinetic.Group({
x:20,
y:80
});
for(var i=0; i<controller.MAX_MEASURES; i++){
this.backgroundGroup.add(new Kinetic.Rect({
x: i*80,
y:0,
width:80,
height:220,
fill: 'gray',
stroke: 'black',
strokeWidth: 1,
id: i + '',
name: i + ''
}));
}
this.drawBackgrounds();
this.backgroundLayer.add(this.backgroundGroup);
}
View.prototype.drawBackgrounds = function() {
var temp;
for (var i=0; i<numMeasures; i++){
temp = this.backgroundGroup.get('#'+i)[0];
temp.setVisible(true);
}
for ( i; i<controller.MAX_MEASURES; i++){
temp = this.backgroundGroup.get('#'+i)[0];
temp.setVisible(false);
}
}
View.prototype.addEditButtonListeners = function() {
this.edit.on('click', function(){
controller.toggleEdit();
});
this.subMeas.on('click', function(){
controller.subMeasure();
});
this.addMeas.on('click', function(){
controller.addMeasure();
});
}
View.prototype.toggleEdit = function() {
if(isEdit){
this.subMeas.setVisible(false);
this.addMeas.setVisible(false);
this.stage.draw();
isEdit = 0;
}else {
this.subMeas.setVisible(true);
this.addMeas.setVisible(true);
this.stage.draw();
isEdit = 1;
}
}
View.prototype.subMeasure = function() {
var temp;
numMeasures--;
temp = this.backgroundGroup.get('#'+numMeasures)[0];
temp.setVisible(false);
this.stage.draw();
}
backgroundGroup is instantiated as a KineticJS group in initBackgrounds, where it gets 8 rectangles added to it, each with id 0 through 7.
The problematic get call occurs in drawBackgrounds. The non-problematic get call occurs in subMeasure.
JSFiddle link:
EDIT: I coded a workaround - I created a backgroundArray that holds the rectangles as well, and access this array in the draw backgrounds method. I don't like it though, I'd rather just keep the rectangles in the group.