画布lineTo()绘制y坐标在错误的地方 [英] Canvas lineTo() drawing y coordinate in wrong place

查看:115
本文介绍了画布lineTo()绘制y坐标在错误的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用ctx.lineTo()在画布上绘制一些矩形。他们得到绘制,但y坐标是从来没有正确。矩形变得太高,在y轴上的错误位置。当我使用调试器的步骤,它显示在lineTo()方法中的y坐标是正确的,但我做了一个canvas.click事件提醒坐标(这是正确的,因为我点击左上角,它警告(0 ,0))。点击事件显示y坐标实际上不是它的状态,它将在lineTo()方法中绘制。然而,x坐标总是正确的。需要考虑的一件事是我通过使用javascript将一个html添加到一个元素来创建我的画布,并且我添加一个图像到它上面。我重新调整矩形的坐标,以便它们适当地放置在画布上,缩放到适合于设备大小的图像大小。这里是我从canvas创建到使用lineTo()方法的所有代码。

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在此方法的早期阶段创建(在appendPicture()中):

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);
        }
    }
}

这里是appendPicture canvas html并将其附加到元素。

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();
}


推荐答案

不同于它的CSS宽度和高度!



这意味着画布被拉伸以与CSS大小对齐。这对缩放有好处,但可能导致类似于您使用width:100%的问题。

Canvas' width and height are different from its CSS width and height!

This means that the canvas gets stretched to align to CSS sizes. This is good for scaling, but can result in issues like the ones you're having with width: 100%.

两种解决方案(取决于您的需要):

Two solutions (depending on what you need):


  • 读取画布的DOM元素大小,并将其应用于

  • 根据画布的实际尺寸修改其CSS样式(请参见下面的第五个画布)

简单示例:

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;
}

这篇关于画布lineTo()绘制y坐标在错误的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆