In my application, I draw an image to the canvas, then add circles and text for labels. I moved my extra drawing code to the load method of drawImage and have discovered that the same code is called repeatedly when moving the mouse over the canvas. I've tried to selectively comment out different blocks to pinpoint the issue but have not really narrowed it down.
This block is the main code that draws the image. Many of the variables are self explanatory. The different IDs used are for database identification. I've noticed that "callback" gets printed repeatedly when moving the mouse over the canvas.
canvasObject.drawImage({
layer: true,
name: 'image',
source: imageSize.url,
x: (600-imageSize.width)/2,
y: 0,
fromCenter: false,
data: {
id : image.id
},
load: function() {
// now draw the labels and stuff on top
console.log("callback")
for (var imageLabelIndex in image.image_label_locations) {
var labelLocation = image.image_label_locations[imageLabelIndex]
console.log("draw " + imageLabelIndex)
drawLabelLine(canvasObject, {
index : imageLabelIndex,
from : {
x : labelLocation.location_x,
y : labelLocation.location_y
},
to : {
x : labelLocation.label.location_x,
y : labelLocation.label.location_y
}
})
drawSmallLabel(canvasObject, {
index : imageLabelIndex,
x : labelLocation.location_x,
y : labelLocation.location_y,
id : labelLocation.id
})
drawLargeLabel(canvasObject, {
index : imageLabelIndex,
x : labelLocation.label.location_x,
y : labelLocation.label.location_y,
id : labelLocation.label.id
})
}
},
click: function(layer) {
console.log("click")
// check whether the mouse is on an existing object
var canvasObject = $(layer.canvas)
var parentOffset = canvasObject.offset();
var canvasWidth = canvasObject.attr("width")
var space = 24
mouseDownPosition = {"x" : layer.eventX, "y" : layer.eventY }
var labelPosition = { "x" : (mouseDownPosition.x < canvasWidth/2) ? space : canvasWidth-space, "y" : mouseDownPosition.y }
drawLabelLine(canvasObject, {
index : countAnswers(),
from: {
x : labelPosition.x,
y : labelPosition.y
},
to: {
x : mouseDownPosition.x,
y : mouseDownPosition.y
}
})
drawSmallLabel(canvasObject, {
index : countAnswers(),
x : mouseDownPosition.x,
y : mouseDownPosition.y
})
drawLargeLabel(canvasObject, {
index : countAnswers(),
x : labelPosition.x,
y : labelPosition.y
})
// also add an answer to the question page
addLabelAnswer(countAnswers(), mouseDownPosition, labelPosition)
}
})
The code runs as you move the mouse because jCanvas is redrawing the canvas on mousemove
. This is due to the presence of a draggable layer or a layer with a mousemove
callback defined somewhere. Additionally, the load()
callback runs whenever the image is drawn or redrawn (not just when it is initially drawn).
The fix is actually quite simple:
Store a boolean property (initially set to false
) in the data
object of your image layer. Then, in your load()
callback, wrap your code in an if
statement which checks if the property's value is false
then. If so, set its value to true
and run the code. If not, then you know the callback has already run, and therefore you don't do anything.
canvasObject.drawImage({
layer: true,
name: 'image',
source: imageSize.url,
x: (600-imageSize.width)/2,
y: 0,
fromCenter: false,
data: {
id : image.id,
loaded: false
},
load: function(layer) {
if (layer.data.loaded === false) {
layer.data.loaded = true;
// now draw the labels and stuff on top
console.log("callback")
for (var imageLabelIndex in image.image_label_locations) {
var labelLocation = image.image_label_locations[imageLabelIndex]
console.log("draw " + imageLabelIndex)
drawLabelLine(canvasObject, {
index : imageLabelIndex,
from : {
x : labelLocation.location_x,
y : labelLocation.location_y
},
to : {
x : labelLocation.label.location_x,
y : labelLocation.label.location_y
}
})
drawSmallLabel(canvasObject, {
index : imageLabelIndex,
x : labelLocation.location_x,
y : labelLocation.location_y,
id : labelLocation.id
})
drawLargeLabel(canvasObject, {
index : imageLabelIndex,
x : labelLocation.label.location_x,
y : labelLocation.label.location_y,
id : labelLocation.label.id
})
}
}
},
click: function(layer) {
console.log("click")
// check whether the mouse is on an existing object
var canvasObject = $(layer.canvas)
var parentOffset = canvasObject.offset();
var canvasWidth = canvasObject.attr("width")
var space = 24
mouseDownPosition = {"x" : layer.eventX, "y" : layer.eventY }
var labelPosition = { "x" : (mouseDownPosition.x < canvasWidth/2) ? space : canvasWidth-space, "y" : mouseDownPosition.y }
drawLabelLine(canvasObject, {
index : countAnswers(),
from: {
x : labelPosition.x,
y : labelPosition.y
},
to: {
x : mouseDownPosition.x,
y : mouseDownPosition.y
}
})
drawSmallLabel(canvasObject, {
index : countAnswers(),
x : mouseDownPosition.x,
y : mouseDownPosition.y
})
drawLargeLabel(canvasObject, {
index : countAnswers(),
x : labelPosition.x,
y : labelPosition.y
})
// also add an answer to the question page
addLabelAnswer(countAnswers(), mouseDownPosition, labelPosition)
}
})