Draw rectangle using Canvas in JavaScript - define rectangle starting Pont
This is my conundrum. I used some code from online sources to draw rectangles using canvas and have been tweaking it to suit my needs. The original code works fine, but clearly encodes it from the top left corner of the window. I learned a lot from the code. This is a problem for me since my page requires it to be relative to the canvas position and not the window position. When you click on the start of the rectangle, the actual rectangle starts to draw some distance below the cursor. However, starting at (0,0), the canvas is further down and to the right. How can I make it see the canvas as a window for defining the starting point?
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 (Not normally relevant to JavaScript issues, but I'm including it because the amount of space defined in HTML is relevant to the issue. I doubt it's important, but just in case.):
<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">
 
 
<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
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, in summary: I need to be able to draw a rectangle from the site, and when I do that, the starting point of the rectangle is affected by the canvas's relationship to the window, and messes everything up and places the rectangle in a different position than it was intended. I need the rectangle to start at the cursor.
Thanks!
Use canvas-relative mouse coordinates:
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);
}