【问题标题】:How do I add a onClick event handler to a canvas element and control mouse movement actions?如何将 onClick 事件处理程序添加到画布元素并控制鼠标移动操作?
【发布时间】:2021-01-22 23:52:40
【问题描述】:

我在画布中有一个图像,我想单击图像并拖动图像(不抬起鼠标左键)并将图像拖动到释放鼠标左键的位置。现在,只要鼠标图标悬停在画布上,图像就会随之移动,我尝试添加一个 onclick 侦听器事件,但我确信我的新手阻碍了我的进步。

这是我到目前为止的想法。如何使用我现有的代码进行这项工作?

var canvas = document.getElementById('customCanvas');
    var context = canvas.getContext('2d');

    make_base();

    function make_base()
    {
        upload_image = new Image();
        upload_image.src = 'https://lh3.googleusercontent.com/-6Zw-hozuEUg/VRF7LlCjcLI/AAAAAAAAAKQ/A61C3bhuGDs/w126-h126-p/eagle.jpg';
        upload_image.onload = function(){
            context.drawImage(upload_image, 0, 0);
            canvas.addEventListener('click', canvas.onmousemove = function(e) {
                /// correct mouse position so its relative to canvas
                var rect = canvas.getBoundingClientRect(),
                        constantX = 0, constantY = 0,
                        x = e.clientX - rect.left,
                        y = e.clientY - rect.top;

                context.clearRect(0, 0, canvas.width, canvas.height);
                context.drawImage(upload_image, x, y);
            });
        }
    }
* {
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
}

.sidepane {
  height: 100%;
  background: #E8E8EA;
}

.sidepane .form {
  height: 80px;
  margin: 10px 0;
}

.sidepane .assets {
  width: 100%;
}

#assetText {
  font-size: 24px;
}

.assets .text, .assets .image {
  margin: 10px 0;
}
.assets .image ul li {
  width: 50px;
  height: 50px;
  margin-right: 5px;
  float: left;
  overflow: hidden;
}
.assets .image ul li img {
  width: 100%;
  height: 100%;
}

.canvas .block {
  position: relative;
  width: 600px; height: 600px;
  margin: 10px;
  border: 1px solid;
  box-shadow: 0px 0px 5px black;
}

.item {
  border: 1px solid transparent;
  position: absolute;
}

.item.selected {
  border-color: blue;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div class="sidepane col-sm-2 col-md-2 col-lg-2">
    <form method="post" action="/images" enctype="multipart/form-data">
    <!--<div class="form">-->
        <h3>Form</h3>
        <input type="file" class="form-control" placeholder="Upload Your Images" name="filefield">
        <button id="submit" class="btn btn-default">upload</button>
        <!-- Upload Form here -->
        <!--</div>-->
        <hr />
        <div class="assets">
            <h3>Assets</h3>
            <div class="text">
                <h4>Text</h4>
                <input type="text" name="textfield">
                <button id="addText" class="btn btn-default">Add Text</button>
            </div>
            <div class="image">
                <h4>Images</h4>
                <ul class="list-unstyled">
                    <!-- List of images here -->
                    <!-- <li><img src="images/sample.jpeg" class="img-rounded" /></li> -->
                </ul>
            </div>
        </div>

        <input type="submit" >
    </form>
</div>
<!-- canvas -->
<div class="canvas col-sm-8 col-md-8 col-lg-8">
    <div class="block">
        <!-- Add images and texts to here -->
        <canvas id="customCanvas" width="598" height="598" style="border: 1px solid #000000">

        </canvas>
    </div>
</div>

【问题讨论】:

  • 因为你在画布里面,你不能监听画布的绘图事件。您必须手动检查是否按下鼠标按钮并检测您是否通过它的坐标单击了图像。我向您推荐这篇文章,并举了一个很好的例子:stackoverflow.com/questions/9880279/…
  • 更容易使用的面料

标签: javascript jquery canvas html5-canvas


【解决方案1】:

首先,您必须检查鼠标是否在图像上,然后检查您是否尝试拖动图像。为此,您需要一些事件,mousedownmouseupmousemove。要检查您的鼠标指针是否在图像上,您必须获取该图像的X, Y, width, height。最终代码如下。

编辑

还有一些变化。 Image 类没有 XY 属性,因此我必须定义将存储该数据的变量并对 isInside 函数进行一些更改。

var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
canvas.width = 300;
canvas.height = 300;
var upload_image;
var imageX, imageY;
var mouseX, mouseY;
var imageDrag = false;

make_base();

canvas.addEventListener("mousemove", function (evt) {
    var mousePos = getMousePos(canvas, evt);
    mouseX = mousePos.x;
    mouseY = mousePos.y;
});

function getMousePos(canvas, event) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top
    };
}

function isInsideImage(rect) {
    var pos = { x: mouseX, y: mouseY };
    return pos.x > imageX && pos.x < imageX + rect.width && pos.y < imageY + rect.height && pos.y > imageY;
}

function make_base()
{
    upload_image = new Image();
	imageX = 0;
	imageY = 0;
    upload_image.onload = function(){
        context.drawImage(upload_image, 0, 0);
    }
    upload_image.src = 'https://lh3.googleusercontent.com/-6Zw-hozuEUg/VRF7LlCjcLI/AAAAAAAAAKQ/A61C3bhuGDs/w126-h126-p/eagle.jpg';
}

canvas.addEventListener("mousedown", function (evt) {
    if(isInsideImage(upload_image)) {
        imageDrag = true;
    }
});

canvas.addEventListener("mouseup", function (evt) {
    if(imageDrag)
        imageDrag = false;
});

setInterval(function() {
    if(imageDrag) {
		context.clearRect(0, 0, canvas.width, canvas.height);
		imageX = mouseX;
        imageY = mouseY;
        context.drawImage(upload_image, imageX, imageY);
    }
}, 1000/30);

【讨论】:

    【解决方案2】:

    您要查找的事件将是 https://developer.mozilla.org/en/docs/Web/Events/mousedown - AFAIK(如果我错了,请纠正我)但点击事件只会在完整的点击事件完成(向下和向上)时触发。

    这里有一些示例代码;

    var mouseX;
    var mouseY; // Accessible outside the function. Easier access to canvas drawing.
    
    var canvas = ''; // Complete this to get canvas element
    
    canvas.addEventListener("mousedown", function(mouse){
      // Get mouse co-ordinates
    })
    

    在这个事件监听器中,你可以检查你当前的鼠标位置...

    var canvasElement = element.getBoundingClientRect()
    mouseX = mouse.pageX - canvasElement.left;
    mouseY = mouse.pageY - canvasElement.top;
    

    在将图像绘制到画布时使用这些变量来确定图像的 x 和 y 位置。这些应该随着鼠标在画布上移动而改变。即,将它们传递给您的 make_base() 函数;

    make_base(mouseX, mouseY)
    

    更新您的绘图功能以解决它们;

     function make_base(mouseX, mouseY)
        {
            upload_image = new Image();
            upload_image.src = 'https://lh3.googleusercontent.com/-6Zw-hozuEUg/VRF7LlCjcLI/AAAAAAAAAKQ/A61C3bhuGDs/w126-h126-p/eagle.jpg';
            upload_image.onload = function(){
                context.drawImage(upload_image, 0, 0);
                canvas.addEventListener('click', canvas.onmousemove = function(e) {
                    /// correct mouse position so its relative to canvas
                    var rect = canvas.getBoundingClientRect(),
                            constantX = 0, constantY = 0,
                            x = mouseX,
                            y = mouseY
    
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    context.drawImage(upload_image, x, y);
                });
            }
        }
    

    请注意上面的代码并不完整,例如,X 和 Y 将基于鼠标在 PAGE 上的位置,而不是 CANVAS。对此需要进行单独的计算。

    【讨论】:

    • 现在当我移动鼠标时我的图像消失了。
    • @TheBrokenSpanner 您是否考虑了页面位置与画布位置?
    • 不,如果您有时间可以编辑您的答案并显示给我看吗?做不到也没关系。
    • @TheBrokenSpanner 已更新以考虑画布顶部,左侧。
    • 非常感谢,很遗憾,我无法理解它,但感谢您的努力
    【解决方案3】:

    或者,您可以在图片下方嵌入外部链接,将您带到任何您想去的地方!

    【讨论】:

    • 请在您的答案中包含更多细节,并附上示例或可能的工作解决方案
    猜你喜欢
    • 2019-05-17
    • 2012-04-10
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    相关资源
    最近更新 更多