简体   繁体   English

在JavaScript中使用Canvas绘制矩形-定义矩形起始Pont

[英]Drawing a Rectangle in Canvas in JavaScript - Defining Rectangle Starting Pont

This is my puzzle. 这是我的难题。 I used some code from an online source to draw a rectangle using canvas and have been adjusting it to suit my needs. 我使用了来自在线资源的一些代码来使用画布绘制矩形,并一直在进行调整以适应我的需求。 The original code worked fine, but it's clearly coded to start in the upper left-hand corner of the window; 原始代码可以正常工作,但是清楚地编码为从窗口的左上角开始。 that much I understand from the code. 我从代码中了解了很多。 Since my page for it requires it to be relative to the canvas location, not the window, this is a problem for me. 由于我的页面要求它相对于画布位置而不是窗口,因此这对我来说是个问题。 When the rectangle is clicked to begin, the actual rectangle starts drawing some distance below the cursor; 单击矩形开始时,实际的矩形开始在光标下方绘制一些距离。 however further down and to the right the canvas is from (0,0). 但是,从(0,0)开始,画布在更下方和右侧。 How do I make it see the canvas as the window to use to define the starting point? 如何使其将画布视为用于定义起点的窗口?

JavaScript: JavaScript:

   function getarea() {
         var wid = document.getElementById('wid').value;
         var hgt = document.getElementById('hgt').value;
         var area = (wid*hgt)
         var perim = (+wid + +hgt + +wid + +hgt)
         window.document.getElementById('area').innerHTML = area;
         window.document.getElementById('perim').innerHTML = perim;
      }


var rect;
var canvas;
var context;
var dragging;

function Point(x, y) {
    this.x = x;
    this.y = y;
}

function Size(width, height) {
    this.width = width;
    this.height = height;
}

function Rectangle(start, size) {
    this.start = start;
    this.size = size;
}

function init() {
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");

    canvas.addEventListener("mousedown", startDragging, false);
    canvas.addEventListener("mouseup", stopDragging, false);
    canvas.addEventListener("mousemove", moved, false);

    var start = new Point(0, 0);
    var size = new Size(0, 0);
    rect = new Rectangle(start, size);


}

function startDragging(event) {
clearRect(rect);
    dragging = true;

    // initialize start point
    var box=canvas.getBoundingClientRect();
    var offsetX=box.left;
    var offsetY=box.top;

    var mouseX = parseInt(event.clientX-offsetX);
    var mouseY = parseInt(event.clientY-offsetY);

    rect.start.x = mouseX;
    rect.start.y = mouseY;


    // initialize size
    rect.size.width = 0;
    rect.size.height = 0;
}

function stopDragging(event) {
    dragging = false;
}

function moved(event) {
    if(!dragging) return;

    var box=canvas.getBoundingClientRect();
    var offsetX=box.left;
    var offsetY=box.top;

    var mouseX = parseInt(event.clientX-offsetX);
    var mouseY = parseInt(event.clientY-offsetY);

    clearRect(rect);
    rect.size.width = event.pageX - rect.start.x;
    rect.size.height = event.pageY - rect.start.y;
    drawRect(rect);
}

function clearRect(rect) {
    context.clearRect(rect.start.x, rect.start.y, rect.size.width, rect.size.height);
}

function drawRect(rect) {
    context.fillRect(rect.start.x, rect.start.y, rect.size.width, rect.size.height);
}

HTML (normally not as relevant to a JavaScript issue, but I'm including it since the amount of space defined in the HTML is related to the problem. I doubt it's important, but just in case.): HTML(通常与JavaScript问题无关,但我将其包括在内,因为HTML中定义的空间量与问题有关。我怀疑它的重要性,但以防万一。):

    <html>
<head>
<script src="week5js.js"></script>
<link rel="stylesheet"href="assignment5.css"/>

<link href="assignment5.css" rel="stylesheet" type="text/css">

</script>

</head>


<header>
<center>
Week 6: Unit 6 - Assignment 5
</center>
</header>


<body onload="init()">

    <form id="areaform">
      <label for="width">Width:</label>
      <input id="wid" name="width" type="number">
      &nbsp
      &nbsp
      <label for="height">Height:</label>
      <input id="hgt" name="height" type="number">
      <br></br>
      <label for="area1">Area:</label>
      <output id="area"></output>
      <br></br>
      <label for="perimeter1">Perimeter:</label>
      <output id="perim"></output>
      <br></br>
      <button onclick="getarea()" type="button">Get Area</button>
    </form>


<canvas id="canvas" width="673" height="550"></canvas>
</body>

</html>

CSS 的CSS

canvas {
    background-color: #F0F0F0;
    border: 1px solid;
}

header{

background-color: yellow;
padding:15px;
margin:30px;
font-family: "Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif;
font-size:25px;
background-color:#F0F0F0;
border: 1px solid;

}

body{
max-width:50%;
padding:25px;
margin:20px;
font-family: "Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif;
font-size:16x;
border: 2px dotted;
box-shadow: 2px 2px 4px #404040;
}

body img{

max-width:100%;

}

So, to sum: I need to be able to draw a rectangle from a site, when I do the rectangle starting point is being affected by the canvas' relation to the window and messing everything up and placing the rectangle at a different point than intended. 因此,总而言之:我需要能够从站点绘制一个矩形,当我这样做时,矩形的起点正受到画布与窗口的关系的影响,并将所有东西弄乱,并将矩形放置在与预期位置不同的位置。 I need the rectangle to start at the cursor. 我需要矩形从光标处开始。

Thank you! 谢谢!

Use mouse coordinates which are relative to your canvas: 使用相对于画布的鼠标坐标:

var rect;
var canvas;
var context;
var dragging;

function Point(x, y) {
    this.x = x;
    this.y = y;
}

function Size(width, height) {
    this.width = width;
    this.height = height;
}

function Rectangle(start, size) {
    this.start = start;
    this.size = size;
}

function init() {
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");

    canvas.addEventListener("mousedown", startDragging, false);
    canvas.addEventListener("mouseup", stopDragging, false);
    canvas.addEventListener("mousemove", moved, false);

    var start = new Point(0, 0);
    var size = new Size(0, 0);
    rect = new Rectangle(start, size);
}

function startDragging(event) {
    dragging = true;

    // initialize start point
    var box=canvas.getBoundingClientRect();
    var offsetX=box.left;
    var offsetY=box.top;

    var mouseX = parseInt(event.clientX-offsetX);
    var mouseY = parseInt(event.clientY-offsetY);

    rect.start.x = mouseX;
    rect.start.y = mouseY;

    // initialize size
    rect.size.width = 0;
    rect.size.height = 0;
}

function stopDragging(event) {
    dragging = false;
}

function moved(event) {
    if(!dragging) return;

    var box=canvas.getBoundingClientRect();
    var offsetX=box.left;
    var offsetY=box.top;

    var mouseX = parseInt(event.clientX-offsetX);
    var mouseY = parseInt(event.clientY-offsetY);

    clearRect(rect);
    rect.size.width = mouseX - rect.start.x;
    rect.size.height = mouseY - rect.start.y;
    drawRect(rect);
}

function clearRect(rect) {
    context.clearRect(rect.start.x, rect.start.y, rect.size.width, rect.size.height);
}

function drawRect(rect) {
    context.fillRect(rect.start.x, rect.start.y, rect.size.width, rect.size.height);
}

You just need to subtract the top left position of the canvas from your position calculation. 您只需要从位置计算中减去画布的左上角位置即可。

Add this global to your set up: 将此全局添加到您的设置中:

var canvasBox = document.getElementsByTagName('canvas')[0].getBoundingClientRect();

If you've wrapped your set up in a function use window.canvasBox instead to make it global. 如果您将设置包装在函数中,请使用window.canvasBox使其全局。 Then use this function to calculate your new relative position. 然后使用此函数来计算新的相对位置。

function getPos(event)
{
    return {"x":event.clientX - canvasBox.left,"y":event.clientY-canvasBox.top};
}

Used like so 像这样使用

var mousePos = getPos(event);
//mousePos.x
//mousePos.y

Here's an extended snippet for working with touches, it has been edited from my library so look out for typos! 这是用于触摸操作的扩展代码段,已从我的库中进行了编辑,因此请注意输入错误!

function init()
{
    window.canvas = document.getElementsByTagName('canvas')[0];
    window.context = canvas.getContext('2d');
    window.canvasBox = canvas.getBoundingClientRect();
    canvas.ontouchstart = function(event){start(event);};
    canvas.ontouchmove = function(event){update(event);};
    canvas.ontouchleave = function(event){end(event);};
    canvas.onmousedown = function(event){start(event);};
    canvas.onmousemove = function(event){update(event);};
    window.addEventListener('mouseup',function(event){end(event);},false);
    window.addEventListener('touchend',function(event){end(event);},false);
    window.addEventListener('touchcancel',function(event){end(event);},false);
}

function start(event)
{
    var position = getPos(event);
}
function update(event)
{
    var position = getPos(event);
}
function end(event)
{
    var position = getPos(event);
}

function getPos(event)
{
    event.preventDefault(); //stops a touch from scrolling the page etc
    var pos = {};
    if(typeof event.changedTouches !== "undefined") // check for preferred touch data
    {   if(event.changedTouches.length !== 0){ // check to see if there are any touches available
            pos.x = event.changedTouches[0].clientX;
            pos.y = event.changedTouches[0].clientY;
    }   }
    else if(typeof event.touches !== "undefined") // check for other touch data
    {   if(event.touches.length !== 0){ // check to see if there are any touches available
            pos.x = event.touches[0].clientX;
            pos.y = event.touches[0].clientY;
    }   }
    else if(typeof event.clientX !== "undefined") //check for mouse location
    {
        pos.x = event.clientX;
        pos.y = event.clientY;
    }
    else //set to null as a fallback
    {
        pos.x = null;
        pos.y = null;
    }
    if(pos.x!==null) // if we have a position, make it in canvas relative space
    {
        pos.x -= canvasBox.left; 
        pos.y -= canvasBox.top;
    }
    return pos; 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM