changing the clicked image in the canvas - javascript

i am making this simple canvas . it has three images in it (identical images). i want to change only the clicked image. what i am trying to do is save the image order in a array . and only the change the index of the image which was clicked .
so far i am clueless how to do so ! i have done it with hard coded but cnt do this in general as i dnt know where the user clicked . if i could get the position of the mouse when it was clicked or the id of the image which was clicked i could do something but i am new in html5 so i have no idea how to do so , can any one point me in the right direction ? here is my code
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 2px solid #9C9898;
}
</style>
<script>
if(window.addEventListener) {
window.addEventListener('load', function ()
{
var my = new Array();
var i=0;
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
var imageObj1 = new Image();
imageObj.onload = function(){
imageObj1.src = "watermelon-duck-outline.png";
for (var x = 0; x <= 1200;x += 400 ) { alert(i,x);
my[i]=imageObj;
context.drawImage(imageObj, x, 0);
++i;
}
context.drawImage(imageObj, 0, 0);
}
imageObj.src = "tomato2.jpg";
change.addEventListener('mousedown', function () {ButtonDown (change)}, false);
function ButtonDown (change)
{ canvas.width = canvas.width;
i--;
for (var x = 800; x >= 0;x -= 400 ) {
if(i!=2){my[i]=imageObj;}else{my[i]=imageObj1;}
context.drawImage(my[i], x, 0);
i--;
}}
init();
}, false); }
</script>
</head>
<body >
<canvas id="myCanvas" width="1250" height="650">
</canvas>
<button id="change" type="button">Change</button>
</body>

Live Demo
This is how I would do it. Basically you need to store the x,y,width,height of each image. You need these values so that when you click within the canvas you can check the bounds of each image against the x and y of the mouse click. After that its easy to reference which image was clicked. Hopefully the following code is enough to get you on the right track.
var canvas = document.getElementById("myCanvas"),
ctx = canvas.getContext("2d");
ctx.fillStyle = "#f00";
ctx.strokeStyle = "#0f0";
var images = [];
images.push({x : 10, y : 10, width:50, height:50}, {x : 70, y : 10, width:50, height:50}, {x : 130, y : 10, width:50, height:50});
//draw some rects, this would be your images
for(var i = 0; i < images.length; i++){
ctx.fillRect(images[i].x, images[i].y, images[i].width, images[i].height);
}
canvas.onclick = function(e){
var x = 0,
y = 0;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
// This is where you go through all the images, and check the x and y from the mouse event against your images.
for(var i = 0; i < images.length; i++){
if(x > images[i].x && x < images[i].x + images[i].width && y > images[i].y && y < images[i].y + images[i].height){
ctx.strokeRect(images[i].x, images[i].y, images[i].width, images[i].height);
alert('Image ' + i + ' selected');
}
}
}

Related

Issue when dragging text on canvas if slightly scrolled down

When I scroll slightly down on my canvas, it does not allow me to drag my text at all. Examples (These are GIFs) -
https://gyazo.com/e60d2efd924ced758c2c6441391804db
GIF explained: So you saw the drag was working when I was on top of the page but when I scrolled slightly down. It completely stopped working. I added a few console.logs around, and what I know is the click event listener for the canvas is working but it isn't detected the text when I slightly scroll down on the page.
I based my drag code from: http://jsfiddle.net/m1erickson/9xAGa/ | What you can see is if you change the canvas size width: 667 and height: 800, and when you scroll slightly down, you will have the same issue I am having.
HTML Code:
<div id="middle_container">
<div class="center_container">
<canvas id="canvas" width="667px" height="800px"></canvas>
</div>
</div>
JavaScript Code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var BB=canvas.getBoundingClientRect();
var offsetX = BB.left;
var offsetY = BB.top;
var mx;
var my;
var texts = [];
var images = [];
var dragF = -1;
var mode = "none";
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(const { text, x, y, width, height } of texts) {
ctx.fillText(text, x, y);
}
}
function addNewText(string_text) {
var y = texts.length * 20 + 20;
var text = {
text: string_text,
x: 20,
y: y
};
ctx.font = "32px verdana";
ctx.textBaseline = "top";
text.width = ctx.measureText(text.text).width;
text.height = 32;
texts.push(text);
draw();
}
function hitDrag(x,y,textIndex) {
var r=texts[textIndex];
return (x>r.x && x<r.x+r.width && y>r.y && y<r.y+r.height);
}
function myDrag(a,e) {
if (a == "down") {
e.preventDefault();
e.stopPropagation();
mx=parseInt(e.clientX-offsetX);
my=parseInt(e.clientY-offsetY);
for(var i=0;i<texts.length;i++){
if(hitDrag(mx,my,i)){
console.log("found");
dragF = i;
}
}
}
}
addNewText("Hello World")
$("#canvas").mousedown(function(e) {
myDrag("down", e);
});
The problem is this line of code:
var BB=canvas.getBoundingClientRect();
which is only populated once at the start of your script. The .getBoundingClientRect() method returns the position of a HTML element relative to the viewport.
Well if you scroll the window, the viewport moves - as the canvas element - but the BB object still holds the position of your canvas at startup.
The fix is rather simple - you need to use the actual position of the canvas element by calling .getBoundingClientRect() again on mouse down and on mouse move.
I've prepared a little sample based on your code and the fiddle you've linked:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var BB = canvas.getBoundingClientRect();
var offsetX = BB.left;
var offsetY = BB.top;
var mx;
var my;
var texts = [];
var images = [];
var dragF = -1;
var mode = "none";
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const {
text,
x,
y,
width,
height
} of texts) {
ctx.fillText(text, x, y);
}
}
function addNewText(string_text) {
var y = texts.length * 20 + 20;
var text = {
text: string_text,
x: 20,
y: y
};
ctx.font = "32px verdana";
ctx.textBaseline = "top";
text.width = ctx.measureText(text.text).width;
text.height = 32;
texts.push(text);
draw();
}
function myDrag(a, e) {
if (a == "down") {
e.preventDefault();
e.stopPropagation();
let rect = canvas.getBoundingClientRect();
mx = parseInt(e.clientX - rect.left);
my = parseInt(e.clientY - rect.top);
for (var i = 0; i < texts.length; i++) {
if (hitDrag(mx, my, i)) {
// console.log("found");
dragF = i;
}
}
}
}
function hitDrag(x, y, textIndex) {
var r = texts[textIndex];
return (x > r.x && x < r.x + r.width && y > r.y && y < r.y + r.height);
}
function handleMouseMove(e) {
if (dragF < 0) {
return;
}
e.preventDefault();
let rect = canvas.getBoundingClientRect();
mouseX = parseInt(e.clientX - rect.left);
mouseY = parseInt(e.clientY - rect.top);
var dx = mouseX - mx;
var dy = mouseY - my;
mx = mouseX;
my = mouseY;
var text = texts[dragF];
text.x += dx;
text.y += dy;
draw();
}
function handleMouseUp(e) {
e.preventDefault();
dragF = -1;
}
addNewText("Hello World")
$("#canvas").mousedown(function(e) {
myDrag("down", e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function(e) {
handleMouseUp(e);
});
body {
background-color: ivory;
}
#canvas {
border: 1px solid red;
}
#theText {
width: 10em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="middle_container">
<div class="center_container">
<canvas id="canvas" width="667px" height="800px"></canvas>
</div>
</div>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>

HTML Canvas draggable texts on downscaled images

I'v encountered a small problem while trying to create an easy-to-use image-editor, where you can add multiple draggable texts on an image and then save the edited image with texts by original resolution.
Everything else works fine, but I want to be able to edit full-hd images and bigger on a non-full-hd resolution canvas (like 800x600px)
I cant use resolutions like 1920x1080 or bigger on the canvas, since it will be to massive and go out of the borders of browser (scrollbars) and also wont be really so easy to manage.
I tried to use percentage value on canvas, and it looks OK, but the text hitbox wont follow the cursor when dragging around.
Any tips or tricks to handle this problem?
Here is a sample how it looks with 1920x1080 canvas & full-hd image.
I would like to fit the image and functionality to a.. lets say 800x600 canvas but save the output as original full-hd.
<canvas id="canvas" width=1920 height=1080></canvas>
 
function draw() {
//ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(imageObj, 0, 0, 1920, 1080);
for (var i = 0; i < texts.length; i++) {
var text = texts[i];
ctx.fillText(text.text, text.x, text.y);
}
}
https://jsfiddle.net/n0mn7bcg/
// 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();
var imageObj = new Image();
imageObj.src = 'https://4.bp.blogspot.com/-lQwIDyafEbI/UxNch2499rI/AAAAAAAAogo/FfZxYSCIXxc/s0/Ships+in+from+the+bottle_2_HD.jpg';
// 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(imageObj, 0, 0, 1920, 1080);
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 = "80px consolas";
text.width = ctx.measureText(text.text).width;
text.height = 80;
// put this new text in the texts array
texts.push(text);
// redraw everything
draw();
});
body {
background: #f3f3f3;
}
#canvas {
border: 1px solid red;
}
#theText {
width: 10em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4>Add text to canvas and drag it</h4>
<input id="theText" type="text">
<button id="submit">Draw text on canvas</button>
<br>
<canvas id="canvas" width=1920 height=1080></canvas>
It works if you use e.pageX in the mousedown and mousemove event handlers:
https://jsfiddle.net/n0mn7bcg/2/
function handleMouseDown(e) {
e.preventDefault();
startX = parseInt(e.pageX - offsetX);
startY = parseInt(e.pageY - offsetY);
// Put your mousedown stuff here
for (var i = 0; i < texts.length; i++) {
if (textHittest(startX, startY, i)) {
selectedText = i;
}
}
}
function handleMouseMove(e) {
if (selectedText < 0) {
return;
}
e.preventDefault();
mouseX = parseInt(e.pageX - offsetX);
mouseY = parseInt(e.pageY - 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();
}
More information: What is the difference between screenX/Y, clientX/Y and pageX/Y?

html5 Canvas display default area in canvas

I would like to display default my "Dedication Text" in the middle of my canvas.
I really can't determine the coordinates nor understand the codes...
Currently my Dedication Text displays here :
As you can see, it displays on the left top corner of the canvas.
Where I would like to automatically display is in the middle
Like this:
I have this code that I got from net:
function updateTotal() {
if (document.getElementById('design3').checked) {
var canvas2 = document.getElementById("displaycake_text");
context = canvas2.getContext("2d");
var $canvas2 = $("#displaycake_text");
var canvasOffset = $canvas2.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas2.scrollLeft();
var scrollY = $canvas2.scrollTop();
var startX;
var startY;
var texts = []; // an array to hold text objects
var selectedText = -1;// this var will hold the index of the hit-selected text
function draw() { // clear the canvas & redraw all texts
context.clearRect(0, 0, canvas2.width, canvas2.height);
for (var i = 0; i < texts.length; i++) { var text = texts[i];
context.fillText(text.text, text.x, text.y); }
}
function textHittest(x, y, textIndex) { // test if x,y is inside the bounding box of texts[textIndex]
var text = texts[textIndex];
return (x >= text.x && x <= text.x + text.width && y >= text.y - text.height && y <= text.y);
}
function handleMouseDown(d) {
d.preventDefault();
startX = parseInt(d.clientX - offsetX);
startY = parseInt(d.clientY - offsetY);
for (var i = 0; i < texts.length; i++) {
if (textHittest(startX, startY, i)) {
selectedText = i; } }
}
function handleMouseUp(d) { // done dragging
d.preventDefault();
selectedText = -1; }
function handleMouseOut(d) { // also done dragging
d.preventDefault();
selectedText = -1; }
function handleMouseMove(d) {
if (selectedText < 0) { return; }
d.preventDefault();
mouseX = parseInt(d.clientX - offsetX);
mouseY = parseInt(d.clientY - offsetY);
var dx = mouseX - startX;
var dy = mouseY - startY;
startX = mouseX;
startY = mouseY;
var text = texts[selectedText];
text.x += dx;
text.y += dy;
draw(); }
$("#displaycake_text").mousedown(function (d) { handleMouseDown(d); }); // listen for mouse events
$("#displaycake_text").mousemove(function (d) { handleMouseMove(d); });
$("#displaycake_text").mouseup(function (d) { handleMouseUp(d); });
$("#displaycake_text").mouseout(function (d) { handleMouseOut(d); });
$("#text_dedi").click(function () {
var y = texts.length * 20 + 20;
var text = { text: $("#dedi_text").val(),
x: 20,
y: y
};
context.font = "30px Roboto";
text.width = context.measureText(text.text).width;
text.height = 16;
text.color = "#ffffff";
texts.push(text); // put this new text in the texts array
draw(); // redraw everything
});
//this is the code for CLEAR BUTTON
document.getElementById('clear').addEventListener('click', function() {
context.clearRect(0, 0, canvas2.width, canvas2.height);
texts = []; },
false);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="displaycake_text" height="300px" width="600px"> </canvas>
<!-- CLICK THE RADIO TO TRIGGER POST -->
<input type="radio" id="design3" name="design_3" onchange="updateTotal()" /> Dedication
<h2> <div class="disp_dedi off"> <input type="text" size="15" id="dedi_text" name="dedicationT" placeholder="Dedication">
<button id="text_dedi"> Post </button> <input type="button" value="Clear" id="clear" size="23" onchange="updateTotal()">
As you can see, I can drag it around... But I'm going to add some features that would decline the dragging part.
Can anyone help me point out which in the JS code that I could set the place of the text to be posted by default somewhere in the middle?
The source doesn't have enough comments for me to understand.
THANK YOU IN ADVANCE!!!
First you need to align the text that you are trying to draw on the canvas by using textAlign property of canvas.
Second you need to set the fillText's x, y coordinates according to half of the canvas width / height, so that you can place the text in the middle of the canvas. So, basically you have to add / change just 2 lines of code in your already existing snippet and that would be :
context.textAlign = 'center';
context.fillText(text.text, canvas2.width / 2, canvas2.height / 2);
and the good thing is it automatically removes the dragging part.
function updateTotal() {
if (document.getElementById('design3').checked) {
var canvas2 = document.getElementById("displaycake_text");
context = canvas2.getContext("2d");
var $canvas2 = $("#displaycake_text");
var canvasOffset = $canvas2.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas2.scrollLeft();
var scrollY = $canvas2.scrollTop();
var startX;
var startY;
var texts = []; // an array to hold text objects
var selectedText = -1; // this var will hold the index of the hit-selected text
function draw() { // clear the canvas & redraw all texts
context.clearRect(0, 0, canvas2.width, canvas2.height);
for (var i = 0; i < texts.length; i++) {
var text = texts[i];
context.textAlign = 'center';
context.fillText(text.text, canvas2.width / 2, canvas2.height / 2);
}
}
function textHittest(x, y, textIndex) { // test if x,y is inside the bounding box of texts[textIndex]
var text = texts[textIndex];
return (x >= text.x && x <= text.x + text.width && y >= text.y - text.height && y <= text.y);
}
function handleMouseDown(d) {
d.preventDefault();
startX = parseInt(d.clientX - offsetX);
startY = parseInt(d.clientY - offsetY);
for (var i = 0; i < texts.length; i++) {
if (textHittest(startX, startY, i)) {
selectedText = i;
}
}
}
function handleMouseUp(d) { // done dragging
d.preventDefault();
selectedText = -1;
}
function handleMouseOut(d) { // also done dragging
d.preventDefault();
selectedText = -1;
}
function handleMouseMove(d) {
if (selectedText < 0) {
return;
}
d.preventDefault();
mouseX = parseInt(d.clientX - offsetX);
mouseY = parseInt(d.clientY - offsetY);
var dx = mouseX - startX;
var dy = mouseY - startY;
startX = mouseX;
startY = mouseY;
var text = texts[selectedText];
text.x += dx;
text.y += dy;
draw();
}
$("#displaycake_text").mousedown(function(d) {
handleMouseDown(d);
}); // listen for mouse events
$("#displaycake_text").mousemove(function(d) {
handleMouseMove(d);
});
$("#displaycake_text").mouseup(function(d) {
handleMouseUp(d);
});
$("#displaycake_text").mouseout(function(d) {
handleMouseOut(d);
});
$("#text_dedi").click(function() {
var y = texts.length * 20 + 20;
var text = {
text: $("#dedi_text").val(),
x: 20,
y: y
};
context.font = "30px Roboto";
text.width = context.measureText(text.text).width;
text.height = 16;
text.color = "#ffffff";
texts.push(text); // put this new text in the texts array
draw(); // redraw everything
});
//this is the code for CLEAR BUTTON
document.getElementById('clear').addEventListener('click', function() {
context.clearRect(0, 0, canvas2.width, canvas2.height);
texts = [];
}, false);
}
}
#displaycake_text {
background-color: lightgrey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="displaycake_text" height="300px" width="600px"> </canvas>
<!-- CLICK THE RADIO TO TRIGGER POST -->
<input type="radio" id="design3" name="design_3" onchange="updateTotal()" /> Dedication
<h2> <div class="disp_dedi off"> <input type="text" size="15" id="dedi_text" name="dedicationT" placeholder="Dedication">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button id="text_dedi"> Post </button> <input type="button" value="Clear" id="clear" size="23" onchange="updateTotal()">

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>
Make Another Meme!
</div>
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 :)

HTML5 canvas, make image rotate around click to select and drag circle

I have completed code that has a user click a button (to the right of the canvas), then the image is added to the canvas and is constrained to only move around the circumference of a circle. In order to move the image the user just needs to click the image and then move the mouse. To release the image the user simply needs to click where the image goes on the canvas.
Here is a fiddle showing what the current code does.
http://jsfiddle.net/smacnabb/68awv7sq/9/
Question: I am looking to be able to have the images that move around the circumference of the circle rotate while moving around the circumference of the circle.
This is what I mean:
Here is a fiddle for the code I added to try and make this happen
http://jsfiddle.net/smacnabb/68awv7sq/11/
in the handlemousemove method, it calls state.draw() every time the mouse move i'm passing mouseX, mouseY to state.draw.
state.draw() is in addstate method and this was the code I added to make the image rotate
var dx = mouseX - centerX;
var dy = mouseY - centerY;
var radianAngle = Math.atan2(dy, dx);
context.save();
context.translate(centerX, centerY);
context.rotate(radianAngle);
if (this.dragging) {
context.strokeStyle = 'black';
context.strokeRect(this.x, this.y, this.width + 2, this.height + 2)
}
context.drawImage(this.image, this.x, this.y);
context.restore();
What am I doing wrong?
You are close...Take a look at this example:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var radianAngle = 0;
var cx = 225;
var cy = 125;
var radius = 50;
// image loader
var imageURLs = [];
var imagesOK = 0;
var imgs = [];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/cars.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/plane.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/cars1.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/plane1.png");
loadAllImages(start);
function loadAllImages(callback) {
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function() {
imagesOK++;
if (imagesOK >= imageURLs.length) {
callback();
}
};
img.onerror = function() {
alert("image load failed");
}
img.crossOrigin = "anonymous";
img.src = imageURLs[i];
}
}
var imagesY = 20;
var targets = [];
var selectedTarget = -1;
function start() {
var n = imgs.length / 2;
for (var i = 0; i < n; i++) {
var target = imgs[i + n];
ctx.drawImage(target, 15, imagesY);
targets.push({
x: 15,
y: imagesY,
width: target.width,
height: target.height,
image: imgs[i]
});
imagesY += target.height + 10;
}
}
function handleMouseDown(e) {
e.preventDefault();
x = parseInt(e.clientX - offsetX);
y = parseInt(e.clientY - offsetY);
for (var i = 0; i < targets.length; i++) {
var t = targets[i];
if (x >= t.x && x <= t.x + t.width && y >= t.y && y <= t.y + t.height) {
selectedTarget = i;
draw(x, y);
}
}
}
function handleMouseMove(e) {
if (selectedTarget < 0) {
return;
}
e.preventDefault();
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
draw(mouseX, mouseY);
}
function draw(mouseX, mouseY) {
var dx = mouseX - cx;
var dy = mouseY - cy;
var radianAngle = Math.atan2(dy, dx);
// Drawing code goes here
var img = targets[selectedTarget].image;
ctx.clearRect(100, 0, canvas.width, canvas.height);
// draw the circle
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.stroke();
// draw the image rotated around the circumference
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(radianAngle);
ctx.drawImage(img, radius - img.width / 2, -img.height / 2);
ctx.restore();
}
$("#canvas").mousedown(function(e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Select an icon on left by clicking<br>
Then move mouse to have icon rotate around circle</h4>
<canvas id="canvas" width=350 height=350></canvas>

Categories

Resources