I'm trying to draw some rectangles on a canvas using ctx.lineTo(). They get drawn but the y coordinate is never right. The rectangles become too tall and on the wrong place on the y axis. When I step through with the debugger it shows the y coordinates within the lineTo() methods as being correct, but I made a canvas.click event to alert the coordinates (which are correct as I click in the top left and it alerts (0,0)). The click event shows that the y coordinate is not actually where it states it will be drawn in the lineTo() method. The x coordinate is however always correct. One thing to be considered is I create my canvas by appending html to an element with javascript, and I add an image to it that I draw on. I rescale the coordinates of the rectangles so they are appropriately place on the canvas which is scaled to the image size that works for the size of the device. Here is all my code from canvas creation to using the lineTo() method.
Canvas gets created in early stages of this method (in appendPicture()):
function appendSection(theSection, list) {
list.append('<label class="heading">' + theSection.description + '</label><br/><hr><br/>');
if (theSection.picture) {
appendPicture(list, theSection);
var canvas = document.getElementById('assessmentImage');
var ctx=canvas.getContext("2d");
canvas.addEventListener("mousedown", relMouseCoords, false);
var img=new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0,canvas.width,canvas.height);
}
img.src = "data:image/jpeg;base64,"+ theSection.picture;
img.addEventListener('load', function() {
if(theSection.allHotSpots.length > 0) {
for( var x = 0; x < theSection.allHotSpots.length; x++) {
appendHotSpot(theSection.allHotSpots[x], theSection.thePicture, ctx);
}
}
}, false);
}
appendSectionQuestions(theSection, list);
if (theSection.allSubSections) {
for (var x = 0; x < theSection.allSubSections.length; x++) {
var theSectionA = theSection.allSubSections[x];
appendSection(theSectionA, list);
}
}
}
Here is appendPicture which creates the canvas html and appends it to an element.
function appendPicture(list, theSection) {
list.append('<div id="wrapper' + platform + '" style="width:100%; text-align:center">
<canvas class="assessmentImageSmall" style="width:100%;height:' + Math.round(theSection.thePicture.ySize * (document.getElementById('assessmentSectionForm' + platform).clientWidth / theSection.thePicture.xSize)) + 'px" id="assessmentImage' + platform + '" align="middle" ></canvas>
<!--<p style="color:#666;" id="imageInstruction">Tap image to enlarge.</p>-->
</div>');
$("#wrapper").kendoTouch({
tap: function (e) {
switchImage();
}
});
}
Here is where I draw the rectangle (I call rectangles hotspots in this function)
function appendHotSpot(HotSpot, picture, ctx) {
var imageWidth = document.getElementById('assessmentImage' + platform).clientWidth;
var scale = imageWidth / picture.xSize;
HotSpot.topLeft = [Math.round(HotSpot.topLeft[0] * scale), Math.round(HotSpot.topLeft[1] * scale)];
HotSpot.bottomRight = [Math.round(HotSpot.bottomRight[0] * scale), Math.round(HotSpot.bottomRight[1] * scale)];
var rect = {x1: HotSpot.topLeft[0], y1: HotSpot.topLeft[1], x2: HotSpot.bottomRight[0], y2: HotSpot.bottomRight[1]};
ctx.strokeStyle="red";
ctx.beginPath();
ctx.moveTo(rect.x1, rect.y1);
ctx.lineTo(rect.x2, rect.y1);
ctx.lineTo(rect.x2, rect.y2);
ctx.lineTo(rect.x1, rect.y2);
ctx.lineTo(rect.x1, rect.y1);
ctx.stroke();
}
See Question&Answers more detail:
os