1

I have an image within a canvas, I want to be to click the image and drag the image(without lifting the left mouse button) and the image at the position where the left mouse button was released. For now as soon as the mouse icon hovers over the canvas, the image moves with it, I tried to add an onclick listener event but I am sure my newbie-ness got in the way of my progress.

Here is what I had come up with so far. How can I make this work with my existing code?

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>
  • Since you are inside a canvas, you can't listen for a canvas' drawing event. you have to manualy check if the mouse button is pressed and detect if you clicked on the image by it's coordiante. I refer you to this post with a good exemple of this : http://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element – Remy Grandin Apr 12 '17 at 12:23
  • easier to use fabric – Daniel Lizik Apr 12 '17 at 12:23

3 Answers3

0

The event you're looking for would be https://developer.mozilla.org/en/docs/Web/Events/mousedown - AFAIK (correct me if I'm wrong) but the click event would only fire when a complete click event has completed (both down and up).

Here's some sample code for this;

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
})

Inside this event listener, you can check for your current mouse position...

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

Use these variables when drawing your image to the canvas to determine the image's x and y position. These should change as your mouse moves around the canvas. I.e, pass them to your make_base() function;

make_base(mouseX, mouseY)

Update your drawing function to account for them;

 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);
            });
        }
    }

PLEASE NOTE that the code above is not complete, for example, the X and Y will be based on where your mouse is on the PAGE, not the CANVAS. there are separate calculations needed to account for this.

Lewis
  • 3,479
  • 25
  • 40
0

First, you have to check if your mouse is on the image, and then check if you are trying to drag the image. To do that, you need some events, mousedown, mouseup and mousemove. To check if your mouse pointer is on the image, you have to get the X, Y, width, height of that image. Final code below.

Edit

Some more changes. Image class has no X and Y properties so I had to define variables that will store that data and make some changes to isInside function.

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);
Oen44
  • 3,156
  • 1
  • 22
  • 31
-1

Or, you can just embed an external link under the image to take you to wherever you want!

  • 1
    please include more detail in your answers, with examples or a possible working solution – Jad Jan 22 '21 at 16:14