- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在 html Canvas 上画了一些圆圈,我的代码如下所示:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebTunings</title>
<link href="index.css" rel="stylesheet">
<script src="index.js"></script>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<div id="controls">
<p><label>Fill: <input id="fillBox" type="checkbox" checked="checked"></label></p>
<div class="lightBorder">
<p><input type="radio" name="shape" value="circle" checked="checked">Circle</p>
</div>
<p><input id="clearCanvas" type="button" value="reset"></p>
</div>
</body>
</html>
Javascript:
var canvas,
context,
dragging = false,
dragStartLocation,
snapshot;
function getCanvasCoordinates(event) {
var x = event.clientX - canvas.getBoundingClientRect().left,
y = event.clientY - canvas.getBoundingClientRect().top;
return {x: x, y: y};
}
function takeSnapshot() {
snapshot = context.getImageData(0, 0, canvas.width, canvas.height);
}
function restoreSnapshot() {
context.putImageData(snapshot, 0, 0);
}
function drawCircle(position) {
var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
context.beginPath();
context.arc(dragStartLocation.x, dragStartLocation.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = getRndColor();
}
function draw(position) {
var fillBox = document.getElementById("fillBox"),
shape = document.querySelector('input[type="radio"][name="shape"]:checked').value;
if (shape === "circle") {
drawCircle(position);
}
if (fillBox.checked) {
context.fill();
} else {
context.stroke();
}
}
function dragStart(event) {
dragging = true;
dragStartLocation = getCanvasCoordinates(event);
takeSnapshot();
}
function drag(event) {
var position;
if (dragging === true) {
restoreSnapshot();
position = getCanvasCoordinates(event);
draw(position, "polygon");
}
}
function dragStop(event) {
dragging = false;
restoreSnapshot();
var position = getCanvasCoordinates(event);
draw(position, "polygon");
}
function getRndColor() {
var r = 255*Math.random()|0,
g = 255*Math.random()|0,
b = 255*Math.random()|0;
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
function eraseCanvas(){
context.clearRect(0, 0, canvas.width, canvas.height);
}
function init() {
canvas = document.getElementById("canvas");
context = canvas.getContext('2d');
context.strokeStyle = 'green';
context.lineWidth = 4;
context.lineCap = 'round';
clearCanvas = document.getElementById("clearCanvas");
canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
clearCanvas.addEventListener("click", eraseCanvas, false);
}
window.addEventListener('load', init, false);
现在我想做的是,每当我绘制多个圆圈时,我想选择一个随机圆圈并将其拖动到 Canvas 上的另一个位置,适用于每个圆圈。我只想使用 html5
和 javascript
没有其他第三方库。有什么办法吗?任何帮助都会很棒......
最佳答案
Canvas 不会“记住”它在何处绘制您的圆圈或矩形,因此您必须进行内存。这通常是通过在 javascript 对象中定义每个圆或矩形并将所有这些形状保存在 shapes[] 数组中来完成的。
// an array of objects that define different shapes
var shapes=[];
// define 2 rectangles
shapes.push({x:10,y:100,width:30,height:30,fill:"#444444",isDragging:false});
shapes.push({x:80,y:100,width:30,height:30,fill:"#ff550d",isDragging:false});
// define 2 circles
shapes.push({x:150,y:100,r:10,fill:"#800080",isDragging:false});
shapes.push({x:200,y:100,r:10,fill:"#0c64e8",isDragging:false});
然后你就可以在javascript中监听鼠标事件了。当浏览器发出鼠标事件时,您可以调用一个函数作为响应。这是告诉浏览器你想监听鼠标事件的方法:
// listen for mouse events
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.onmousemove = myMove;
您可以使用鼠标事件函数(myDown、myUp、myMove)进行拖动。
在发生 mousedown 事件(由 myDown 函数处理)时,您测试每个形状以查看鼠标是否位于数组中的其中一个形状内。如果鼠标在 1+ 个形状内,则在这 1+ 个形状上设置 isDragging
标志,并设置 dragok
标志以指示您需要跟踪鼠标以进行拖动.
在发生 mousemove 事件(由 myMove 函数处理)后,您可以移动被拖动的任何形状,距离为自上次 mousemove 以来鼠标拖动的距离。
在发生 mouseup 事件(由 myUp 函数处理)时,您可以通过清除 dragok 标志来停止拖动操作。
这是带注释的示例代码和演示:
// get canvas related references
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
// drag related variables
var dragok = false;
var startX;
var startY;
// an array of objects that define different shapes
var shapes=[];
// define 2 rectangles
shapes.push({x:10,y:100,width:30,height:30,fill:"#444444",isDragging:false});
shapes.push({x:80,y:100,width:30,height:30,fill:"#ff550d",isDragging:false});
// define 2 circles
shapes.push({x:150,y:100,r:10,fill:"#800080",isDragging:false});
shapes.push({x:200,y:100,r:10,fill:"#0c64e8",isDragging:false});
// listen for mouse events
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.onmousemove = myMove;
// call to draw the scene
draw();
// draw a single rect
function rect(r) {
ctx.fillStyle=r.fill;
ctx.fillRect(r.x,r.y,r.width,r.height);
}
// draw a single rect
function circle(c) {
ctx.fillStyle=c.fill;
ctx.beginPath();
ctx.arc(c.x,c.y,c.r,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
// clear the canvas
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
// redraw the scene
function draw() {
clear();
// redraw each shape in the shapes[] array
for(var i=0;i<shapes.length;i++){
// decide if the shape is a rect or circle
// (it's a rect if it has a width property)
if(shapes[i].width){
rect(shapes[i]);
}else{
circle(shapes[i]);
};
}
}
// handle mousedown events
function myDown(e){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// get the current mouse position
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
// test each shape to see if mouse is inside
dragok=false;
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
// decide if the shape is a rect or circle
if(s.width){
// test if the mouse is inside this rect
if(mx>s.x && mx<s.x+s.width && my>s.y && my<s.y+s.height){
// if yes, set that rects isDragging=true
dragok=true;
s.isDragging=true;
}
}else{
var dx=s.x-mx;
var dy=s.y-my;
// test if the mouse is inside this circle
if(dx*dx+dy*dy<s.r*s.r){
dragok=true;
s.isDragging=true;
}
}
}
// save the current mouse position
startX=mx;
startY=my;
}
// handle mouseup events
function myUp(e){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// clear all the dragging flags
dragok = false;
for(var i=0;i<shapes.length;i++){
shapes[i].isDragging=false;
}
}
// handle mouse moves
function myMove(e){
// if we're dragging anything...
if (dragok){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// get the current mouse position
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
// calculate the distance the mouse has moved
// since the last mousemove
var dx=mx-startX;
var dy=my-startY;
// move each rect that isDragging
// by the distance the mouse has moved
// since the last mousemove
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
if(s.isDragging){
s.x+=dx;
s.y+=dy;
}
}
// redraw the scene with the new rect positions
draw();
// reset the starting mouse position for the next mousemove
startX=mx;
startY=my;
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>Drag one or more of the shapes</h4>
<canvas id="canvas" width=300 height=300></canvas>
关于javascript - 使用 html5 Canvas 创建形状后使用鼠标拖动形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28284754/
我正在使用 gridstack 来显示我的小部件。拖动和调整大小适用于 gridstack 卡,但当我将卡拖到底部时,卡的容器不会滚动。我想在拖动卡片时滚动那个容器。该容器只是一个 div 元素,所有
我目前正在构建一个多个处理的 slider 小部件,并且目前正在实现手势检测器。我有一个问题,如果您用第二根手指触摸/拖动屏幕,检测器会识别它并调用 onDragUpdate 函数,这是我试图禁用的功
我是 AngularJS 的新手,我对当前的项目有点压力,这就是我在这里问的原因。 我看到 AngularJS 有 ng-dragstart 事件( http://docs.ng.dart.ant.c
关于缩放大图像和平移有什么建议吗?最好内联在页面上。 我一直在使用PanoJS(又名GSV2),但是现在越来越多的人使用iPhone/iPad/Android类型的设备,这个库要么太慢,要么旧版本不支
我在尝试拖动 JPanel 时遇到问题。如果我纯粹在 MouseDragged 中将其实现为: public void mouseDragged(MouseEvent me) { me.getS
我有一个需要与屏幕底部对齐的 ImageButton,当我单击并拖动它时,它会随着我的手指移动一定距离,超过该距离它不会远离原点,而是继续跟随我的手指从原点开始的方向。 当我松手时,按钮必须滑回原点。
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我需要一个解决方案来实现拖动和缩放,在不使用矩阵的情况下围绕屏幕 onTouch 事件路由 ImageView。我搜索了很多但所有答案都是用矩阵完成的,因为我在屏幕矩阵中有多个对象不适合我,我想拖动和
我需要一些帮助来拖动 UIView 以显示主视图下方的菜单 View 。 我有两个 UIView。menuView - 包括菜单按钮和标签 和 mainView - 位于 menuView 之上。 我
谷歌地图即使设为 true 也不可拖动/拖动。 重现步骤:在新选项卡中加载带有 map 的页面,检查并在不执行任何操作的情况下转到移动 View 。现在在移动 View 中左右上下拖动 map ,它将
我在绘制和缩放 ImageView 时遇到问题。请帮帮我.. 当我画一些东西然后拖动或缩放图像时 - 绘图保留在原处,如您在屏幕截图中所见。而且我只需要简单地在图片上绘图,并且可以缩放和拖动这张图片。
所以我试图模拟鼠标左键单击和鼠标左键释放来执行一些自动拖放操作。 它目前在 C# Winforms(是的,winforms :|)中并且有点笨拙。 基本上,一旦发送了点击,我希望它根据 Kinect
我有一个巨大的 HTML5 Canvas,我希望它像谷歌地图一样工作:用户可以拖动它并始终只看到它的一小部分(屏幕大小)。它只呈现您在屏幕上可以看到的部分。我该怎么做?你有想法吗? 最佳答案 2 个简
我有以下拖放应用程序代码,它在桌面上按预期工作,但是当我想在移动设备上使用该应用程序时,拖动事件无法按预期工作。我知道触摸事件是必需的,但我不确定如何设置它们和实现这些功能。 .object
我正在使用 react-leaflet map ,我用状态改变了很多 map 属性,但是当使用状态来改变拖动属性时它不起作用。 { this.map = map}}
我知道我可以轻松地允许用户在OpenLayers中选择多个功能/几何图形,但是随后我希望使用户能够轻松地同时拖动/移动所有选定的功能。 使用ModifyFeature控件一次只能移动一个要素...是否
我有一个 Windows Phone 运行时应用程序,我使用 xaml 在 map 上显示图钉。 当我拖动 map 时,控件试图保持在相同位置时会出现一些滞后。 任何帮助,将不胜感
我通常不会提出此类问题/答案,但我想我会这样做,因为我已经看到这个问题被问了 20 多次,但没有一个答案真正有效。简而言之,问题是,如果您在可拖动 jQuery 项目内的任何位置有可滚动内容(over
我确信一定有一种简单的方法可以做到这一点,但到目前为止,我已经花了很长时间在各种兔子洞中没有成功。 我有一个支持拖放的 Collection View 。被拖动的单元格有 UIImageView在 c
如何在两个virtualtreeview之间复制以复制所有列,而不仅仅是第一列? 复制前: 复制后: 最佳答案 树控件不保存任何数据。它不包含要显示的列数据,因此无法复制它。而是,当树控件想要显示任何
我是一名优秀的程序员,十分优秀!