Canvas lineTo() 在错误的位置绘制 y 坐标
Canvas lineTo() drawing y coordinate in wrong place
我正在尝试使用 ctx.lineTo() 在 canvas 上绘制一些矩形。他们被画出来了,但是 y 坐标永远不对。矩形变得太高并且位于 y 轴上的错误位置。当我逐步使用调试器时,它显示 lineTo() 方法中的 y 坐标是正确的,但我创建了一个 canvas.click 事件来提醒坐标(这是正确的,因为我点击左上角并提醒(0,0))。单击事件显示 y 坐标实际上并不在它声明将在 lineTo() 方法中绘制的位置。然而,x 坐标总是正确的。需要考虑的一件事是,我通过将 html 附加到具有 javascript 的元素来创建我的 canvas,并向其添加我绘制的图像。我重新缩放矩形的坐标,以便将它们适当地放置在 canvas 上,该 canvas 缩放为适合设备大小的图像大小。这是我从 canvas 创建到使用 lineTo() 方法的所有代码。
Canvas 在此方法的早期阶段创建(在 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);
}
}
}
这里是 appendPicture,它创建 canvas html 并将其附加到一个元素。
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();
}
});
}
这是我画矩形的地方(我在这个函数中调用矩形热点)
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();
}
Canvas'宽高与其CSS宽高不同!
这意味着 canvas 被拉伸以与 CSS 大小对齐。这对缩放很有用,但可能会导致像 width: 100%.
这样的问题
两种方案(看你需要什么):
- 读取 canvas' DOM 元素大小并将其应用于 canvas 本身(参见下面示例中的第 4 个 canvas)
- 根据canvas的实际大小修改其CSS样式(见下文第5条canvas)
简单示例:
function buildCanvas(w, h, sizeFromDOM, changeCSS, looksFine) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
canvas.style.borderColor = looksFine ? "green" : "red";
if (sizeFromDOM) {
// read its size from the DOM
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
} else {
// or simply apply what was given
canvas.width = w;
canvas.height = h;
}
// change CSS styles if needed
if (changeCSS) {
canvas.style.width = canvas.width + 'px';
canvas.style.height = canvas.height + 'px';
}
// draw the same 80x80 square on each
ctx.strokeStyle = looksFine ? "green" : "red";
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(90, 10);
ctx.lineTo(90, 90);
ctx.lineTo(10, 90);
ctx.lineTo(10, 10);
ctx.stroke();
}
buildCanvas(200, 200, false, false, true); // this canvas is fine as it matches the CSS sizes
buildCanvas(300, 200); // this canvas is stretched horizontally
buildCanvas(200, 300); // this canvas is stretched vertically
buildCanvas(200, 300, true, false, true); // let's fix this one
buildCanvas(300, 200, false, true, true); // this one too, but by changing its CSS
canvas {
width: 200px;
height: 200px;
border: 1px solid #aaa;
margin: 4px;
}
这是一个不错的小工具,可以将所有 canvas
元素的高度和宽度设置为等于它们的 CSS 设置。
var canvases = document.getElementsByTagName("canvas");
for(var i=0; i<canvases.length; i++)
{
canvas = canvases[i];
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
现在您可以通过 CSS 继续设置 canvas 个维度!
(如果没有@Shomz 的回答,我不会想到这一点。)
我正在尝试使用 ctx.lineTo() 在 canvas 上绘制一些矩形。他们被画出来了,但是 y 坐标永远不对。矩形变得太高并且位于 y 轴上的错误位置。当我逐步使用调试器时,它显示 lineTo() 方法中的 y 坐标是正确的,但我创建了一个 canvas.click 事件来提醒坐标(这是正确的,因为我点击左上角并提醒(0,0))。单击事件显示 y 坐标实际上并不在它声明将在 lineTo() 方法中绘制的位置。然而,x 坐标总是正确的。需要考虑的一件事是,我通过将 html 附加到具有 javascript 的元素来创建我的 canvas,并向其添加我绘制的图像。我重新缩放矩形的坐标,以便将它们适当地放置在 canvas 上,该 canvas 缩放为适合设备大小的图像大小。这是我从 canvas 创建到使用 lineTo() 方法的所有代码。
Canvas 在此方法的早期阶段创建(在 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);
}
}
}
这里是 appendPicture,它创建 canvas html 并将其附加到一个元素。
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();
}
});
}
这是我画矩形的地方(我在这个函数中调用矩形热点)
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();
}
Canvas'宽高与其CSS宽高不同!
这意味着 canvas 被拉伸以与 CSS 大小对齐。这对缩放很有用,但可能会导致像 width: 100%.
这样的问题两种方案(看你需要什么):
- 读取 canvas' DOM 元素大小并将其应用于 canvas 本身(参见下面示例中的第 4 个 canvas)
- 根据canvas的实际大小修改其CSS样式(见下文第5条canvas)
简单示例:
function buildCanvas(w, h, sizeFromDOM, changeCSS, looksFine) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
canvas.style.borderColor = looksFine ? "green" : "red";
if (sizeFromDOM) {
// read its size from the DOM
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
} else {
// or simply apply what was given
canvas.width = w;
canvas.height = h;
}
// change CSS styles if needed
if (changeCSS) {
canvas.style.width = canvas.width + 'px';
canvas.style.height = canvas.height + 'px';
}
// draw the same 80x80 square on each
ctx.strokeStyle = looksFine ? "green" : "red";
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(90, 10);
ctx.lineTo(90, 90);
ctx.lineTo(10, 90);
ctx.lineTo(10, 10);
ctx.stroke();
}
buildCanvas(200, 200, false, false, true); // this canvas is fine as it matches the CSS sizes
buildCanvas(300, 200); // this canvas is stretched horizontally
buildCanvas(200, 300); // this canvas is stretched vertically
buildCanvas(200, 300, true, false, true); // let's fix this one
buildCanvas(300, 200, false, true, true); // this one too, but by changing its CSS
canvas {
width: 200px;
height: 200px;
border: 1px solid #aaa;
margin: 4px;
}
这是一个不错的小工具,可以将所有 canvas
元素的高度和宽度设置为等于它们的 CSS 设置。
var canvases = document.getElementsByTagName("canvas");
for(var i=0; i<canvases.length; i++)
{
canvas = canvases[i];
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
现在您可以通过 CSS 继续设置 canvas 个维度!
(如果没有@Shomz 的回答,我不会想到这一点。)