在JavaScript中在画布中绘制矩形-定义矩形起始点
这是我的难题。我使用了一些来自在线源代码的代码来使用画布绘制一个矩形,并一直在调整它以满足我的需要。最初的代码运行得很好,但它的代码显然是从窗口的左上角开始的;我从代码中了解到了这一点。因为我的页面要求它相对于画布位置,而不是窗口,这对我来说是个问题。单击矩形开始时,实际矩形开始在光标下方绘制一定距离;然而,画布从(0,0)向右向下延伸。如何将画布视为用于定义起点的窗口 JavaScript:在JavaScript中在画布中绘制矩形-定义矩形起始点,javascript,canvas,dimensions,Javascript,Canvas,Dimensions,这是我的难题。我使用了一些来自在线源代码的代码来使用画布绘制一个矩形,并一直在调整它以满足我的需要。最初的代码运行得很好,但它的代码显然是从窗口的左上角开始的;我从代码中了解到了这一点。因为我的页面要求它相对于画布位置,而不是窗口,这对我来说是个问题。单击矩形开始时,实际矩形开始在光标下方绘制一定距离;然而,画布从(0,0)向右向下延伸。如何将画布视为用于定义起点的窗口 JavaScript: function getarea() { var wid = document
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(通常与JavaScript问题无关,但我将其包括在内,因为HTML中定义的空间量与问题有关。我怀疑这是否重要,但只是以防万一。):
所以,总而言之:我需要能够从一个站点绘制一个矩形,当我这样做的时候,矩形的起点会受到画布与窗口的关系的影响,会把所有的东西弄乱,并将矩形放置在一个与预期不同的点上。我需要矩形从光标开始
谢谢大家! 使用相对于画布的鼠标坐标:
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);
}
您只需要从位置计算中减去画布的左上角位置 将此全局设置添加到您的设置中:
var canvasBox = document.getElementsByTagName('canvas')[0].getBoundingClientRect();
如果已将设置包装在函数中,请使用window.canvasBox使其成为全局设置。
然后使用此函数计算新的相对位置
function getPos(event)
{
return {"x":event.clientX - canvasBox.left,"y":event.clientY-canvasBox.top};
}
像这样使用
var mousePos = getPos(event);
//mousePos.x
//mousePos.y
这里有一个用于触摸的扩展代码段,它是从我的库中编辑的,所以请注意输入错误
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;
}
而不是在处理程序中使用<代码> PAXEX <代码>和<代码> PaGey < /Cuff>属性,考虑使用<代码> OffSExx < /C>和<代码> Office 。它们相对于事件处理程序所附加到的元素的左上角,而不是整个页面本身。感谢您的帮助!不过,您的修复有一个问题。当我开始创建矩形时,它会自动在水平和垂直方向上扩展原始数量的矩形,因此它开始时比预期的要大得多。关于如何解决这个问题有什么想法吗?:)你的意思是原始矩形仍保留在画布上吗?在这种情况下,put
clearRect(rect)
作为StartDraging函数的第一行。它会清洁你的画布。这不是我的意思,尽管这将是我添加的下一件事。:)基本上,在前面,当我点击它时,矩形开始进一步向下和向右,即所描述的数量。现在,它在正确的点开始矩形,但自动开始矩形的高度和长度差相同,因此它开始的长度比预期的要长,略宽。抱歉,我无法重现此问题。你使用哪种浏览器?Chrome。我将用我现在使用的全部代码编辑原始帖子,希望这会有所帮助。:)当然:)这个代码是无关的还是除了hovitya的代码?由于某种原因,我在让它工作时遇到了一些麻烦。也许我把它们添加到了错误的位置?基本上是相同的功能,但我想你可以更好地理解它,像这样分解。我在getPos中输入了一个错误。将函数getPos(e)
更改为函数getPos(event)
将在我找到我的触摸事件版本时在mo中编辑:)嗯…如果是相同的功能,尽管我很难找到这些片段的确切归属(请记住,我一直在调整代码,但原始代码来自第三方),它可能有和hovitya一样的问题。我们正在他的回答下讨论这件事。:)好吧,我已经添加了触摸位,但在更详细的情况下,从中绘制一个矩形不应该是更多的代码方式。。。虽然我们离你的示例代码已经很远了:P你想要一个完整的解决方案吗?谢谢你,谢谢你愿意帮助我。HTML和CSS都很简单,但JavaScript完全是我的笑柄!
var mousePos = getPos(event);
//mousePos.x
//mousePos.y
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;
}