Gowthamraj Somanathan
Gowthamraj Somanathan

Reputation: 260

Not Able to drag and drop the text in canvas image

Actually i have tried to drag and drop the canvas text which was created in javascript . But I am not able to drag it properly because selecting the text is not working properly. I kept my code in below snippet.

please help me on this. Thanks in advance.

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);
    ctx.drawImage(window.imageSrc, 0, 0, canvas.width, canvas.height);
    for (var i = 0; i < texts.length; i++) {
        var text = texts[i];
		ctx.strokeText(text.text, text.x, text.y);
        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
    //alert(texts.length);
	
	
    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);
});

$("[id^='memeText']").change(function () {
    // calc the y coordinate for this text on the canvas
    var y = texts.length * 20 + 100;
		var position = $(this).attr('name');
    
    position = position - 1;
    // get the text from the input element
    var text = {
        text: $(this).val(),
        x: 250,
        y: y
    };

    // calc the size of this text for hit-testing purposes
    ctx.font = "32px verdana";
    ctx.textAlign = 'center';
	ctx.lineWidth = 3;
	ctx.fillStyle = "#fff";
	ctx.strokeStyle = "#000";
    text.width = ctx.measureText(text.text).width;
    text.height = 16;
		if(texts[position]==""||texts[position]==null||texts[position]==undefined){
    	texts.push(text);
    } else {
    	console.log(texts[position].text);
    	texts[position].text = $(this).val();
    }
    // put this new text in the texts array
    

    // redraw everything
    draw();

});

function handleFileSelect(evt) {
						//var canvasWidth = 500;
					//	var canvasHeight = 500;
						var file = evt.target.files[0];
						var reader = new FileReader();
						reader.onload = function(fileObject) {
							var data = fileObject.target.result;
							var image = new Image();
							image.onload = function() {
								window.imageSrc = this;
								ctx.drawImage(window.imageSrc, 0, 0, canvas.width, canvas.height);

							};
							document.getElementById('box2').style.display = "block";
							image.src = data;
							// console.log(fileObject.target.result);
						};
						reader.readAsDataURL(file);
					}
          
          document.getElementById('file').addEventListener('change',
							handleFileSelect, false);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" style="">
       
        <input id="file" type="file" autocomplete="off">
        <br><br>
    </div>
    
    <div id="box2" style="display: none;">
        
        <input id="memeText" name="1" autocomplete="off">
        <br><br>
        <input id="memeText" name="2" autocomplete="off">
        <br><br>
        <canvas id="canvas" width="500" height="500"></canvas>
        <br><br>
        <a class="buttonLink" id="downloadLink">Download Meme!</a>
        <br><br>
        <a href="">Make Another Meme!</a>
    </div>

Upvotes: 1

Views: 734

Answers (1)

AgataB
AgataB

Reputation: 647

There is a couple of problems with this.

Firstly, look at how to Get the coordinates of a mouse click on Canvas. Currently your offsets are both 0. Try calling canvas.offsetLeft and canvas.offsetTop - note: canvas, NOT $canvas.

Secondly, text position is set to the middle of the text, not to the top left or bottom left corner. So in your textHittest function, you want this return statement:

return (x >= (text.x - 0.5*text.width) && x <= (text.x + 0.5*text.width) && y >= (text.y - 0.5*text.height) && y <= (text.y + 0.5*text.height));

More on text properties here.

Once that's sorted, double check if the events are registering exactly as you want them to. Hope that's enough to get you started :)

Upvotes: 1

Related Questions