I am trying to create a canvas that allows me to draw on it rectangles using mouse events. Very similar to the way selection works in windows, I want to be able to click down anywhere on my page, drag left/right/up/down, then once I release, a rectangle is drawn with the starting coordinates (x1 and y1) on mousedown and the ending coordinates (x2, y2) on mouseup.
I've been trying to create eventListeners bound to my canvas that return the starting and ending coordinates on mousedown and mouseup respectively, but my variables stay undefined.
My canvas spans the entire length of my window so no need to take into account relative positioning. Also the solution has to be implemented using purely Javascript, no JQuery allowed.
Thank you for your help!
UPDATE
Ignore most of what is underneath, re-reading your question, it seems like you have the theory nailed. Your problem is most likely the mousedown and mouseup function parameters are missing. Try the following;
document.getElementsByTagName('canvas')[0].addEventListener('mousedown', function(e){
// I THINK IT'S THE e ON THE LINE ABOVE THIS THAT YOU'RE MISSING.
// YOU CAN THEN ACCESS THE POSITION OF THE MOUSE USING;
mouse.x = e.pageX;
mouse.Y = e.pageY;
})
I won't write the code for you, but I can give you theory.
Store your mouse x & y variables in an object such as mouse = {}.
Add an event listener to the canvas for mouse down (click) and store the e.pageX and e.pageY in mouse.firstX and mouse.firstY. Use something like:
document.getElementsByTagName('canvas')[0].addEventListener('mousedown', function(e){
mouse.firstX = e.pageX;
mouse.firstY = e.pageY;
})
Create a second event listener for the canvas for mouseup and store this set of e.pageX and e.pageY in mouse.secondX and mouse.secondY.
Calculate the difference between firstX and secondX, firstY and secondY to work out big your rectangle sound be.
var width = mouse.firstX + mouse.secondX // rect width
var height = mouse.firstY + mouse.secondY // rect height
Then, using these calculations, draw a rectangle on your canvas using firstX and firstY as the position parameters.
I hope this is relatively clear and helpful for you. If not, this might help;
http://simonsarris.com/blog/140-canvas-moving-selectable-shapes
Related
In my react project i would like to get current position of this div that i can drag around on screen. I mean current X Y coordinates
I think you want to listen to is the Drag Event - take a look at the Mozilla Documentation for good examples
Remember in React the events will be referred to in camel case - onDragStart, onDragEnd, etc.
// A sample drag handler where you are getting the elements coordinates
function onDragStartHandler (ev) {
var rect = ev.target.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
}
I have this code that let me draw rectangle on canvas:
https://jsfiddle.net/6u7bLkwc/4/
In order to draw a rectangle on the canvas, click on the image and then drag your mouse.
To reproduce my problem please follow this steps:
Draw a rectangle like mentionned in the top.
And then click on ADD TEXT button.
Now try to draw another rectangle, you will see that your cursor are not in the same way with the rectangle.
How to make my code work even if i add or remove any elements on the page dynamically?
I tried to do like this:
var shape = new Shape(mouseDownX - canvasOffset.left, mouseDownY - canvasOffset.top, mouseX - mouseDownX, mouseY - mouseDownY, color);
But didn't resolved it.
Something like updating new positions will solve it, but not have idea about how to process.
check the solution over here : https://jsfiddle.net/6u7bLkwc/9/
the problem is that you are not calculating the PageX and PageY relative to the canvas position, but instead to the whole page which is giving you wrong coordinates.
I have just changed these:
mouseDownX = e.pageX;
mouseDownY = e.pageY;
to this:
mouseDownX = e.pageX - this.offsetLeft;
mouseDownY = e.pageY - this.offsetTop;
UPDATE
For some other cases you should just use getBoundingClientRect() method on the canvas to get the element position relative to the viewport as the following jsfiddle shows sfiddle.net/dkboaq7p/2
// Get Element's relative position
var canvasPosition=document.getElementById("canvas").getBoundingClientRect();
mouseDownX = e.pageX - canvasPosition.left;
mouseDownY = e.pageY - canvasPosition.top;
I want to be able to click and drag to draw a rectangle on a javascript canvas.
I need to be able to see the rectangle as I'm dragging to change size as I'm dragging like a "rubber band" as I've heard it been called. And then it creates on mouseup.
I'm having serious difficulties with this, any help is appreciated, thanks!
An algorithm to investigate would be to
Use animation frame callback to clear and write a new rectangle to the canvas. ( See requestAnimationFrame )
Use mousedown and mouseup events over the canvas to initiate tracking mouse movement. The mousedown event could start animation calls to draw a 1x1 pixel rectangle.
mousemove events record the position of the mouse for use by animation frame drawing code - and may call requestAnimationFrame if no callback is pending.
If you can clear the canvas of previous content to create the rubber band effect, the last drawn rectangle on mouseup is the result.
If existing content needs to be preserved, investigate making a copy of the canvas on mousedown, and copying it back to the canvas before drawing new rectangles. See questions like how to copy a canvas locally and/or how to (deep) clone a canvas
Happy coding, there's a lot to learn!
First of all, to draw rect on drag (or mouse move), you just clear the canvas, and draw a new rect. Second of all, canvas shapes are not object, so you can't interact with them as far as I know, if you want interactivity, consider using svg. Here is a sloppy implementation of drawing on dragging.
$("canvas").mousedown(function(event){
var ctx = this.getContext("2d");
ctx.clearRect(0,0,$(this).width(),$(this).height());
var initialX = event.clientX - this.getBoundingClientRect().left;
var initialY = event.clientY - this.getBoundingClientRect().top;
$(this).mousemove(function(evt) {
ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY);
});
});
I am a beginner in Javascript/jQuery. I have a set of coordinates belonging to an area element and I am wondering if the following is possible: when I mouse over the area element, does jQuery have a method that would draw the rectangle defined by those coordinates? Or is there some library/plugin you know of that could do this?
I know I can't use the jQuery .show() method on an area element, but that is the effect I am looking for.
One way is to use the jQuery offset method to translate the event.pageX and event.pageY coordinates from the event into a mouse position relative to the parent. Here's an example:
$("body").hover(function(e){
var offset = $(this).offset();
var relX = e.pageX - parentOffset.left;
var relY = e.pageY - parentOffset.top;
//You have your rectangle and the mouse position, Now you can check if mouse is in the area or not
//Do something...
});
I would like to have a function run when the mouse is X distance away from an element.
I assume mousemove event should be moved, but since the element may not always be in the same place I'm not sure how to get the mouse position relative to the element?
Does anyone have an example of something similar?
var mX, mY, distance;
$element = $('#YourElementID');
function calculateDistance(elem, mouseX, mouseY) {
return Math.floor(Math.sqrt(Math.pow(mouseX - (elem.offset().left+(elem.width()/2)), 2) + Math.pow(mouseY - (elem.offset().top+(elem.height()/2)), 2)));
}
$(document).mousemove(function(e) {
mX = e.pageX;
mY = e.pageY;
distance = calculateDistance($element, mX, mY);
// do your stuff with distance
});
You will need to bind to the mousemove event, store the coordinates of your elements corners in a global variable and keep checking at every pixel the mouse moved until the vector between current mouse position and your objects coordinates is of length X. that would then be the moment to trigger your custom event which you bound some function to.
i am unaware of a plugin that already does that, so make sure to post a link to the plugin you write here. :)