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 :)
Related
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>
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?
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()">
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>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Currently i am working on html5 drag and drop applications but i found this code on jsfidle site. It is working fine but when i used in webstroms editor at my local system then it is not working. So please tell me what can i do and how can i resolved this problems.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js" type="text/javascript"></script>
<script type="text/javascript">
// get reference to the canvas and its context
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "16px helvetica";
// variables
// some text objects defining text on the canvas
var texts = [];
// 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;
// this var will hold the index of the selected text
var selectedText = -1;
// make the <li> draggable
$("ul li").draggable({
helper: 'clone'
});
// drop on canvas
$("#canvas").droppable({
accept: "ul li",
drop: function (event, ui) {
ctx.fillText($(ui.draggable).clone().text(), ui.position.left - event.target.offsetLeft, ui.position.top - event.target.offsetTop);
var text = $(ui.draggable).clone().text();
var x = ui.position.left - event.target.offsetLeft;
var y = ui.position.top - event.target.offsetTop;
var width = ctx.measureText(text).width;
var height = 16;
// save this text info in an object in texts[]
texts.push({
text: text,
x: x,
y: y,
width: width,
height: height
});
// draw all texts to the canvas
draw();
}
});
// clear the canvas draw all texts
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
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);
});
</script>
<style type="text/css">
body {
background-color: ivory;
}
#canvas {
border:1px solid red;
}
</style>
</head>
<body>
<ul id="drag">
<li class="new-item">Drag me down1</li>
<li class="new-item">Drag me down2</li>
<li class="new-item">Drag me down3</li>
</ul>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Your script is running before the elements on the page have been created - you should run it on load instead.
You have jQuery, so you can use it to do that. Just change the code as follows:
$(function() {
// the javascript
}
You can apply script in the body.You can use this code.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js" type="text/javascript"></script>
<style type="text/css">
body {
background-color: ivory;
}
#canvas {
border:1px solid red;
}
</style>
</head>
<body>
<ul id="drag">
<li class="new-item">Drag me down1</li>
<li class="new-item">Drag me down2</li>
<li class="new-item">Drag me down3</li>
</ul>
<canvas id="canvas" width=300 height=300></canvas>
<script type="text/javascript">
// get reference to the canvas and its context
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "16px helvetica";
// variables
// some text objects defining text on the canvas
var texts = [];
// 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;
// this var will hold the index of the selected text
var selectedText = -1;
// make the <li> draggable
$("ul li").draggable({
helper: 'clone'
});
// drop on canvas
$("#canvas").droppable({
accept: "ul li",
drop: function (event, ui) {
ctx.fillText($(ui.draggable).clone().text(), ui.position.left - event.target.offsetLeft, ui.position.top - event.target.offsetTop);
var text = $(ui.draggable).clone().text();
var x = ui.position.left - event.target.offsetLeft;
var y = ui.position.top - event.target.offsetTop;
var width = ctx.measureText(text).width;
var height = 16;
// save this text info in an object in texts[]
texts.push({
text: text,
x: x,
y: y,
width: width,
height: height
});
// draw all texts to the canvas
draw();
}
});
// clear the canvas draw all texts
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
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);
});
</script>
</body>
</html>