我正在创建一个基于Web的注释应用程序,用于通过HTML canvas元素和Javascript注释图像。我希望用户向下鼠标指示矩形的开始,拖动到所需的结束坐标,然后松开指示矩形的另一端。
目前,我可以使用起始坐标和结束坐标在图像上使用 context.rects()函数创建一个矩形,但是由于我不确定如何调整特定的大小画布上的矩形,只有在用户释放鼠标后才会绘制矩形。
如何在拖动时调整在mousedown上创建的特定矩形的大小?
以下是执行该功能的代码片段:
var isMouseDown = false;
var startX;
var startY;
canvas.onmousedown = function(e) {
if(annMode){
isMouseDown = true;
var offset = $(this).offset();
startX = parseInt(e.pageX - offset.left);
startY = parseInt(e.pageY - offset.top);
}
};
canvas.onmousemove = function(e) {
if(isMouseDown) {
var offset = $(this).offset();
var intermediateX = parseInt(e.pageX - offset.left);
var intermediateY = parseInt(e.pageY - offset.top);
console.log(intermediateX);
}
};
canvas.onmouseup = function(e) {
if(annMode&&isMouseDown){
isMouseDown = true;
var offset = $(this).offset();
var endX = parseInt(e.pageX - offset.left);
var endY = parseInt(e.pageY - offset.top);
var width = endX - startX;
var height = endY - startY;
context.strokeStyle = "#FF0000";
context.rect(startX, startY, width, height);
context.stroke();
}
isMouseDown = false
};
答案 0 :(得分:1)
canvas
API不会保留对使用它绘制的特定形状的引用(与SVG不同)。 canvas
API只是提供了方便的功能,可以将操作应用于canvas
元素的各个像素。
您有几个选项可以实现可拖动的矩形:
您可以在用户拖动时将样式化的div
放在画布上。为您的画布和div
创建一个容器,并更新div
的位置和大小。当用户释放时,绘制矩形。您的容器需要position: relative
,div
需要绝对定位。确保div的z-index
高于canvas
。
在您的鼠标按下方法中,将div.style.display
设置为block
。然后在拖动鼠标时更新位置(style.left
,style.top
,style.width
和style.height
)。释放鼠标后,再次隐藏它(style.display = 'none'
)。
您可以手动存储对要绘制的每个项目的引用,清除画布(context.clearRect
),并在每个帧上重绘画布上的每个项目。这种设置通常通过递归使用window.requestAnimationFrame
方法来实现。此方法接受回调并在浏览器的下一个绘制周期执行。
在您的情况下,第一个选项可能更容易实现。如果您计划进一步扩展应用程序的功能,第二个将提供更多功能。基本循环将如下实现:
// setup code, create canvas & context
function mainLoop() {
context.clearRect(0, 0, canvas.width, canvas.height);
/** do your logic here and re-draw **/
requestAnimationFrame(mainLoop);
}
function startApp() {
requestAnimationFrame(mainLoop)
}
本教程详细介绍了HTML canvas的事件循环:http://www.isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing
我的GitHub上还有一个功能齐全的实现,它是我写的渲染引擎的一部分:https://github.com/thunder033/mallet/blob/master/src/mallet/webgl/webgl-app.ts#L115
答案 1 :(得分:1)
这里我方便的前端脚本派上用场了!
当我理解这个问题时,您希望能够将鼠标移动到画布上的任意位置,按住鼠标左键,然后向任意方向拖动以在起点和任何新鼠标位置之间形成一个矩形。当你松开鼠标按钮时它就会停留。
可帮助您完成目标的脚本:
https://github.com/GustavGenberg/handy-front-end/blob/master/README.md#canvasjs https://github.com/GustavGenberg/handy-front-end/blob/master/README.md#pointerjs
这两个脚本只是使代码更清晰,更容易理解,所以我使用了这些。
这是一个简单的小提琴,你可以真正使用
const canvas = new Canvas([]);
和
const mouse = new Pointer();
https://jsfiddle.net/0y8cbao3/
我是否正确理解了您的问题?
你想要一个带有评论的版本描述每一行吗?
目前仍有一些漏洞,但我很快就会解决这些问题!
修改强>
在再次阅读你的问题之后,我做出了反应:“......但是我不确定如何在画布上调整特定矩形的大小...”。
Canvas就像一个图像。一旦你吸引它,你就不能“调整”不同的形状。你只能清除整个画布并重新开始(当然你也可以清除一小部分)。
这就是Canvas助手如此有用的原因。为了能够“动画”画布,你必须创建一个循环,用每个16ms(60 fps)的新帧重绘画布。