SVG to Screen Coordinate - javascript

I was wandering if any one could help me with this svg problem. How do I get the mouse coordinate version of an svg object. Usually when a user clicks on the page, the click event gets trigger and the object has a mouse position in terms of x and y. In my case, I don't want to do it with an event. Is getting the mouse position possible by simply examining the svg object's properties like the x and y coordinate? I put together an example page, hope it makes it clearer. http://jsfiddle.net/kenny12/XBCHF/ is the link. Excerpt is:
var svg = document.getElementsByTagName('svg')[0];
var pt = svg.createSVGPoint();
var el1 = document.getElementsByTagName('rect')[0];
var log_svgcursorPoint,
log_mouseclick,
log_mousecoord;
function svgcursorPoint(evt){
pt.x = evt.clientX; pt.y = evt.clientY;
var a = svg.getScreenCTM();
log_svgcursorPoint = "offset based on svg"+ " x:" + a.e +" y:" + a.f;
var b = a.inverse();
return pt.matrixTransform(b);
};
(function(elem){
elem.addEventListener('mousedown',function(e){
log_mouseclick = "mouse clicked at"+ " x:" + e.clientX +" y:" + e.clientY ;
var svgmouse = svgcursorPoint(e);
log_mousecoord = "svg mouse at"+ " x:" + svgmouse.x +" y:" +svgmouse.y;
document.getElementById('op').innerHTML = log_svgcursorPoint + "<br>" + log_mouseclick + "<br>" + log_mousecoord;
},false);
})(el1);
(function calc_manually(){
var rec = document.getElementsByTagName("rect")[0];
var root = document.getElementsByTagName("svg")[0];
var x = rec.getAttribute("x");
var y = rec.getAttribute("y");
var CTM = root.getScreenCTM();
// How to get the mouse position these information without using events is the problem.
})();

Why don't you want an event? That's what they're for. If you're dealing with mouse coordinates, just stick standard DOM event listeners on your objects and then when they trigger, use the event.target.getBoundingClientRect() function for the element's position on-screen, and the event.offsetX/screenX and event.offsetY/screenY properties for the mouse coordinates.
simple demonstrator: http://jsfiddle.net/HBmYV/1/

you can use event layer as well which works better if the svg element is positioned some where besides 0,0 on the page p.x =event.layerX || event.clientX;

Related

Set focus on element using jQuery coordinates/offset values

jQuery.fn.getCoord = function(){
var elem = $(this);
var x = elem.offset().left;
var y = elem.offset().top;
console.log('x: ' + x + ' y: ' + y);
return {
x,
y
};
};
The above function can be used to extend jQuery, it returns an object with the x and y coordinate of a given element, left and top value respectively.
Is there a way to set focus to an element based on these x, and y coordinates.
E.g
//Get button coordinates
let coords = $("#gridButton3").getCoord();
//Get height of current element in focus
let itemHeight = $("#gridButton").scrollHeight;
//Delta value representing some space in between elements
const delta = 30;
//coords.x = 200
//coords.y = 50
//itemHeight = 200
Given the above values in a n x n grid, lets say I want to set focus to a grid button just below gridButton3.
I would do the following :
let {focusX , focusY } = coords;
//Only changing y coordinate because we are navigating down, x coordinates doesn't change
focusY = focusY + itemHeight + delta;
//Here is the part I need some insight on
//scroll to new y location
$('html, body').animate({
scrollTop: focusY
}, 500)
//Now focus on element at coordinates (focusX,focusY)
I know how to set focus via element id or by some selector, I need to figure how to do it based on element at a given x,y .
To get an element from a point in the DOM you can use document.elementFromPoint()

Angular 6 / Typescript property is "undefined" after people assigned a variable

With this Angular project, i'm trying to create elements that can be dragged to any location within the body. I want these changes to persist.
I tried to style the dragged element with position: relative, left: {the y value of the mouse's position, and top: {the x value of the mouses position}.
This works, but because you can drag an element from its middle, the dragged element jumps because the top left corner is being placed at the location of the mouse rather than the location on the element where the mouse is hovering.
So, I am trying to offset this by finding the distance from the top left corner of the element to the location of the mouse when dragging begins, and then using the difference to slightly alter the top, left styling.
dragx: Number;
dragy: Number;
dragstart(e){
let x = e.pageX;
let y = e.pageY;
let drag = document.getElementById('drag');
let rect = drag.getBoundingClientRect();
let elX = rect.left;
let elY = rect.top;
this.dragx = elX - x;
this.dragy = elY - Y;
console.log("element position" + elX + ", " + elY);
console.log("mouse position:" + x + ", " + y);
console.log("difference" + this.dragx + ", " + this.dragy)
}
In this bit of code, i'm just trying to assign a value to the global variables that represent the difference between the mouse and the element when first dragging. These will be used in the dragover function.
dragover(e){
let mousePosition = document.getElementById('mousePosition');
let drag = document.getElementById('drag');
let dragPosition = document.getElementById('elPosition');
let x = e.pageX;
let y = e.pageY;
mousePosition.innerHTML = x + ", " + y;
let rect = drag.getBoundingClientRect();
dragPosition.innerHTML = rect.left.toString() + ", " + rect.top.toString();
drag.style.position = "absolute";
drag.style.top = y + "px";
drag.style.left = x + "px";
console.log("test" + this.dragy);
}
The problem is that when I try to access these properties, like in the last line, i'm being told that dragy and dragx are undefined.
Maybe, I have a fundamental misunderstanding of global variables or properties or something. My question is why are dragx and dragy undefined?
Also, is this a good way to make draggable elements or am I overcomplicating it, or am I going about it the wrong way?
Thanks.
--- Edit --- Where the listeners get added.
ngOnInit() {
//console.log(document);
this.dataService.getStyling().subscribe((stylings) => {
this.stylings = stylings;
});
this.el = document.getElementById('drag');
let dragP = document.getElementById('elPosition');
let rect = this.el.getBoundingClientRect();
dragP.innerHTML = rect.left.toString() + ", " + rect.top.toString();
this.el.addEventListener('dragstart', this.dragstart);
this.el.addEventListener('ondrag', this.ondrag);
document.addEventListener('dragover', this.dragover);
}
The reason is your context of this is being lost. You can use something like:
this.el.addEventListener('dragstart', this.dragstart.bind(this));
Or
this.el.addEventListener('dragstart', (e) => this.dragstart(e));
Bear in mind you will need to change all of the addEventListeners

Is it possible to send the x and y coordinates of the mouse's current location with a trigger.('mouseup') event?

I'm trying to make a drawing pad that keeps sending the location of the mouse AND registers a "click" every 1 second. I've tried this, but it doesn't seem to be working -
$( "#canvas" ).mouseover(function() {
setInterval(function(){
var mouseLocation = new jQuery.Event("mouseup");
var x = mouseLocation.pageX ;
var y = mouseLocation.pageY ;
$('#canvas').trigger(mouseLocation);
console.log('Interval function is working');
console.log(mouseLocation.pageX);
},400);
});
the console shows the 'Interval function is working', but it says x is not definted
Click events dont have x and y coordinate.
Do grab x and y coordinate you have to attach mousemove or mouseover event to the element.
$(function(){
var canvas = document.getElementsByTagName("canvas")[0];
var offset = $("canvas").offset();
var a = document.getElementById("a");
canvas.addEventListener("mousemove",function(event){
a.innerText = (event.x - offset.left) + " " + (event.y - offset.top)
})
})
since you want continuous polling of x and y coordinates mousemove is better event to be attached.
fiddle:http://jsfiddle.net/BBnuu/

how to get mouse coordinate after transform

How do I get the x and y pixel value of the mouse click on the image after a canvas translate & scale? What's the needed calculation from the event x and y?
I am using panning & zooming code from this answer:
var zoom = function(clicks) {
var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x,pt.y);
var factor = Math.pow(scaleFactor,clicks);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);
redraw();
}
var handleScroll = function(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
Example website
If you're just trying to get the mouse X and Y position after a click, then you should attach a function to the mousedown event in Javascript. This is called event binding. In short, while in the DOM you can bind events to elements within the page. Here's an example I made which shows an event bound to the #box element.
document.getElementById("box").onmousedown = function() {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
alert("Mouse x: " + posx + "\nMouse y: " + posy);
};​
This code finds an element with an ID of box and tells the code in the function to run every time after the mouse is depressed. In this example we also fall back for older system to ensure that it works cross-platform and cross-browser. If you wanted to bind this event to the whole webpage rather than just an element then you can replace document.getElementById("box") with window.
This however does not compute the relative position within a DOM element. There's multiple ways to do that which I won't go into detail on here, but I'll include a few methods below. Best of luck!
RESOURCES
More on handling mouseclicks in Javascript
Relative position of mouse clicks within an element
jQuery solution for the previous link

Click event position (Y) is too high

I have a canvas element and when i click on it i get the click position with e.clientX(Y) or e.screenX(Y). Something strange is happening. Y value is always too high. Please look at this image: http://img840.imageshack.us/img840/268/eventq.jpg. Any ideia why is it so high?
You just need to take the ClientX and Y and subtract the position of the canvas from them.
This example is unnecessarily verbose, just to show the steps:
var canvas = document.getElementById('game');
var canvasX, canvasY;
canvas.addEventListener('click', function(event) {
canvasX = canvas.offsetLeft;
canvasY = canvas.offsetTop;
var eventX = event.clientX;
var eventY = event.clientY;
var relX = eventX - canvasX;
var relY = eventY - canvasY;
alert('X = ' + relX + ', Y = ' + relY);
});
Working sample: http://jsfiddle.net/JfhJF/
I'm pretty sure you can tell what's happening. You do not have the coordinates relative to your canvas, but relative to your viewport. It also depends on your browser whether or not they include padding.
Convert them to normal coordinates. In your case this involves substracting the offset of the canvas.

Categories

Resources