如何在 HTML5 画布周围拖动一段用户生成的文本?
Posted
技术标签:
【中文标题】如何在 HTML5 画布周围拖动一段用户生成的文本?【英文标题】:How can I drag a piece of user generated text around the HTML5 canvas? 【发布时间】:2014-05-12 04:56:05 【问题描述】:基本上,我编写的代码是在文本框中输入单词的能力。当按下按钮提交它时,该词就会被发布到 html5 画布上,以便人们可以看到它。我现在想做的是能够在 HTML5 画布上拖动那个词。我在实现这一点上有一点困难,想知道是否有人可以帮我解决这个问题?这是我到目前为止所做的代码:
var fname;
var canvas;
var ctx;
var canvasX;
var canvasY;
var mouseIsDown;
function addTitle2()
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
document.body.addEventListener("mouseup", mouseUp, false);
var fname = document.forms[0].fname.value;
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
ctx.font = "35px Arial";
ctx.fillText(fname, Math.random() * 500, Math.random() * 400);
ctx.stroke();
function mouseUp()
mouseIsDown = 0;
mouseXY();
function mouseDown()
mouseIsDown = 1;
mouseXY();
function mouseXY(e)
e.preventDefault();
canvasX = e.pageX - canvas.offsetLeft;
canvasY = e.pageY - canvas.offsetTop;
ShowPos();
function ShowPos()
if(mouseIsDown)
ctx.fillText(fname, canvasX, canvasY);
【问题讨论】:
请添加JFiddle或显示html 上面注释了示例代码。 【参考方案1】:拖动文本主要是响应鼠标事件。
演示:http://jsfiddle.net/m1erickson/9xAGa/
首先创建要引用的文本对象
// some text objects
var texts=[];
// some test texts
texts.push(text:"Hello",x:20,y:20);
texts.push(text:"World",x:20,y:70);
鼠标按下时
遍历每个文本对象,看看鼠标是否在里面。
// handle mousedown events
// iterate through texts[] and see if the user
// mousedown'ed on one of them
// If yes, set the selectedText to the index of that text
function handleMouseDown(e)
e.preventDefault();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
for(var i=0;i<texts.length;i++)
if(textHittest(startX,startY,i))
selectedText=i;
// test if x,y is inside the bounding box of texts[textIndex]
function textHittest(x,y,textIndex)
var text=texts[textIndex];
return(x>=text.x &&
x<=text.x+text.width &&
y>=text.y-text.height &&
y<=text.y);
在鼠标移动中
通过鼠标拖动的距离改变选定文本的 x,y:
// handle mousemove events
// calc how far the mouse has been dragged since
// the last mousemove event and move the selected text
// by that distance
function handleMouseMove(e)
if(selectedText<0)return;
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousemove stuff here
var dx=mouseX-startX;
var dy=mouseY-startY;
startX=mouseX;
startY=mouseY;
var text=texts[selectedText];
text.x+=dx;
text.y+=dy;
draw();
在 mouseup 中
拖拽结束:
// done dragging
function handleMouseUp(e)
e.preventDefault();
selectedText=-1;
注释代码:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body background-color: ivory;
#canvasborder:1px solid red;
#theTextwidth:10em;
</style>
<script>
$(function()
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// variables used to get mouse position on the canvas
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
// variables to save last mouse position
// used to see how far the user dragged the mouse
// and then move the text by that distance
var startX;
var startY;
// an array to hold text objects
var texts=[];
// this var will hold the index of the hit-selected text
var selectedText=-1;
// clear the canvas & redraw all texts
function draw()
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<texts.length;i++)
var text=texts[i];
ctx.fillText(text.text,text.x,text.y);
// test if x,y is inside the bounding box of texts[textIndex]
function textHittest(x,y,textIndex)
var text=texts[textIndex];
return(x>=text.x &&
x<=text.x+text.width &&
y>=text.y-text.height &&
y<=text.y);
// handle mousedown events
// iterate through texts[] and see if the user
// mousedown'ed on one of them
// If yes, set the selectedText to the index of that text
function handleMouseDown(e)
e.preventDefault();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
for(var i=0;i<texts.length;i++)
if(textHittest(startX,startY,i))
selectedText=i;
// done dragging
function handleMouseUp(e)
e.preventDefault();
selectedText=-1;
// also done dragging
function handleMouseOut(e)
e.preventDefault();
selectedText=-1;
// handle mousemove events
// calc how far the mouse has been dragged since
// the last mousemove event and move the selected text
// by that distance
function handleMouseMove(e)
if(selectedText<0)return;
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousemove stuff here
var dx=mouseX-startX;
var dy=mouseY-startY;
startX=mouseX;
startY=mouseY;
var text=texts[selectedText];
text.x+=dx;
text.y+=dy;
draw();
// listen for mouse events
$("#canvas").mousedown(function(e)handleMouseDown(e););
$("#canvas").mousemove(function(e)handleMouseMove(e););
$("#canvas").mouseup(function(e)handleMouseUp(e););
$("#canvas").mouseout(function(e)handleMouseOut(e););
$("#submit").click(function()
// calc the y coordinate for this text on the canvas
var y=texts.length*20+20;
// get the text from the input element
var text=text:$("#theText").val(),x:20,y:y;
// calc the size of this text for hit-testing purposes
ctx.font="16px verdana";
text.width=ctx.measureText(text.text).width;
text.height=16;
// put this new text in the texts array
texts.push(text);
// redraw everything
draw();
);
); // end $(function());
</script>
</head>
<body>
<input id="theText" type="text">
<button id="submit">Draw text on canvas</button><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
【讨论】:
请查看我编辑的答案,现在包含从输入元素检索文本并将其添加到画布的代码。 我知道已经 5 年了,但你的小提琴已经不行了 :)【参考方案2】:在canvas
上创建一个透明的div
,并将其定位为仅覆盖您填充文本的区域。制作这个div
draggable
。在 div 位置更改清除画布并根据 div
的新位置在画布上重绘文本。
【讨论】:
【参考方案3】:你应该在鼠标按下时重复所有的填充文本内容,并且在每次绘制之前清除屏幕
function drawText()
ctx.clearRect(0, 0, 500, 400);
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
ctx.font = "35px Arial";
ctx.fillText(fname, canvasX, canvasY);
ctx.stroke();
这是jsfiddle
【讨论】:
是的,单击和拖动有效,但文本框不存在是有原因的。正如我在主要问题中解释的那样,您在按下按钮的文本框中键入一段文本,它应该提交输入的文本并将其显示在画布上。【参考方案4】:好的,我只想指出 markE
的以下 jsfiddle 解决方案中的一个问题Dragging text is largely responding to mouse events
问题是,如果您的页面不适合窗口并且可以滚动,如果您滚动了页面并且现在正在拖动文本,则它将不起作用,因为鼠标事件将返回无法计算的 clientY保存的坐标。
通过将高度指定为复制
<canvas id="canvas" width=300 height=3000></canvas>
滚动后拖动文本。
【讨论】:
链接失效,请检查您的答案预览并修复它以上是关于如何在 HTML5 画布周围拖动一段用户生成的文本?的主要内容,如果未能解决你的问题,请参考以下文章