How to use css3 translate to move to an absolute position - javascript

How would I use css3 to translate to an absolute position. It seems that it always translates relative to my current location (where my current location is 0,0), but I'd rather it translate it relative to the screen, so that the upper left portion of the screen is 0,0.
http://jsbin.com/qujabe/1/edit
For example, I'd like to be able to move the red box (when clicked) onto the green box using the green box's offset() position. (note: I want to do this with css3 translate not left/top absolute coordinates)

Here, add this before your function "flyToBox2()"
var myVarW = $("#box1").offset().left;
var myVarH = $("#box1").offset().top;
and change
translate('#box1',30,30, '1s');
to
translate('#box1',-myVarW+30,-myVarH+30, '1s');
Unfortunately jsfiddle is down at the moment, otherwise I would include a link to a fiddle as well

Here's how I ended up doing it.
function translateToAbsolute(sel, x, y, dur)
{
var offset = $(sel).offset();
var newX = -offset.left+x;
var newY = -offset.top+y;
$(sel).css('transition','all '+dur+' ease');
$(sel).css('transform','translate('+newX+'px,'+newY+'px)');
}

Related

How to move an unknown object to center screen? HTML/CSS/JS

I am developing a VueJS project and have created a set of cards appearing on the page, when one of these cards is selected, I wish for it to move to centre screen but keep the position it has moved from in the list of options.
I know that by changing the position from 'unset' to 'relative' the card now has move functionality with 'left', 'top' etc. but I still need to find a way to automatically move the card to centre screen regardless of where on the screen the card is moving from.
Does anyone know how to achieve this with the use of JS?
I imagine there is a way of receiving the current location of the node and moving it to the center of the screen, but I am not sure on the specifics of how to achieve it...
Image for context:
CardsProject
EDIT: I have for now gone with rendering an absolute position for the card which means there's no CSS transition from the card's original place to the centre of the screen and the card also temporarily loses its place within the deck.
Before click: click here for image
After click: click here for image
I found the answer after many, many hours of scouring the internet and deepfrying my code.
The answer: Don't use 'relative' positioning!
There's a far nice option to hold the position the element is moving from, but allow for the item to move freely with the use of CSS' top or left etc. and this option is position:sticky;!
With this and the use of JavaScript's coordinates documentation
.getBoundingClientRect()
...I managed to solve the mystery. The function I made to pull a vector between the current object and it the centre of the screen can be found here, returning an array of size 2 of X and Y vectors respectively.
function calcCenterMove(element){
/*
X and Y are the current position of the element to be moved (top left corner).
Width and Height are the width and height of the element to be moved.
CX and CY are the X and Y coordinates of the centre of the screen.
*/
var x = element.getBoundingClientRect().x;
var y = element.getBoundingClientRect().y;
var width = element.getBoundingClientRect().width;
var height = element.getBoundingClientRect().height;
var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2;
var xVector = cx-(width/2)-x;
var yVector = cy-(height/2)-y;
return [xVector, yVector];
}
var xAxisMove = calcCenterMove(element)[0];
var yAxisMove = calcCenterMove(element)[1];
element.style = "transform: translate("+xAxisMove+"px,"+yAxisMove+"px);";
I have paired the above code with a z-index to place the element above all others, and a screen dimming cover, to prevent the user from scrolling elsewhere or interacting with any other options.
Issues still arise here if the user resizes the screen, but I believe that is a different issue to address, possibly by using an event listener to assess a window resize and translate the element from the previous centre to the new centre using the same cx and cy properties above (or perhaps even the entire function!).
Nevertheless, I have come to the answer I was looking for, anyone feel free to use the code above, if needed!
Here are images for reference:
Before click
After click
Regards!

How to reliably get the exact location of a click event on a canvas?

How do I get the exact point that was clicked on a canvas?
JS-Fiddle: http://jsfiddle.net/IQAndreas/yRMZ6/
None of the "built in" event properties (clientX, pageX, screenX) get the value I am searching for.
Searching Google or previous question reveals several answers, but most of them assume things like "the canvas must be fullscreen", or for some other reason, they fail to work in the test above.
The main problem in your example is padding and real position of canvas start...
You can obtain padding using getComputedStyle function, and find real canvas start on page with this function:
function getPos(el) {
var pl = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left'));
var pt = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-top'));
for (var lx=0, ly=0;
el != null;
lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
return {x: lx + pl,y: ly + pt};
}
Workin' example on JSFiddle
Please note that border affects that aswell, so you may want to add window.getComputedStyle(el, null).getPropertyValue('border-top') and window.getComputedStyle(el, null).getPropertyValue('border-left') aswell.
You can use .getBoundingClientRect to get the canvas element position--including scrolling:
var BB=canvas.getBoundingClientRect();
Then you can get the mouse position relative to the canvas using event.clientX and event.clientY adjusted by the bounding box of the canvas element.
Note about borders and padding: You can click on the border of a canvas element and it will fire a canvas click event. This means [0,0] on the canvas is on the top-left corner of the canvas border. However the drawing area of a canvas is inside the border. Therefore, if you want to get the x,y of a click relative to the canvas drawing area you must also subtract the border size. The same is true about padding. Therefore if you want to get the x,y of a click relative to the canvas drawing area you must also subtract the padding size.
function handleMousedown(e){
var BB=canvas.getBoundingClientRect();
var x=e.clientX-BB.left-borderLeftWidth-paddingLeft;
var y=e.clientY-BB.top-borderTopWidth-paddingTop;
console.log(x,y);
}
To get the border and padding you can use .getComputedStyle:
// a function using getComputedStyle to fetch resolved CSS values
function getStyle(elem,stylename){
return(
window
.getComputedStyle(elem,null)
.getPropertyValue(stylename)
);
}
// Fetch border and padding
var borderLeftWidth=getStyle(canvas,"border-left-width");
var borderTopWidth=getStyle(canvas,"border-top-width");
var paddingLeft=getStyle(canvas,"padding-left");
var paddingTop=getStyle(canvas,"padding-top");

kinetic js : dragBoundFunc property does not work properly

I have a disturbing issue with kinetic js using dragBoundFunc.
I have dragBoundFunc defined on selector group, and it works perfectly not allowing the group overflow on the green rectangle. The erroneous case is follows:
1 - drag an anchor to resize selector rectangle, try to drag the anchor outside green rectangle. It will seem not moving outside bounds.
2 - now move selector rectangle to the edges in order to check bounds. You'll see that as if the green rectangle's position is somehow shifted from its original position.
How can I solve this strange behaviour? Any ideas?
Here is the fiddle.
Because rect and anchors is placed relative to group, you shoud move them after drag. I think best way to keep left top anchor and rectangle coord as {0, 0} in group.
group.on("dragend",function(){
var rect = group.get('#rectangle')[0];
var pos = rect.getPosition();
var dx = pos.x;
var dy = pos.y;
group.children.each(function(child){
child.move(-dx, -dy);
});
group.setPosition({
x : pos.x + group.getPosition().x,
y : pos.y + group.getPosition().y
});
layer.draw();
});
http://jsfiddle.net/lavrton/TfgAV/1/

How to get the correct mouse position in relation to a div that has has a scale transform applied

I am using CSS transform scale to create a smooth zoom on a div. The problem is that I want to be able to get the correct mouse position in relation to div even when scaled up, but I can seem figure out the correct algorithm to get this data. I am retrieving the current scale factor from:
var transform = new WebKitCSSMatrix(window.getComputedStyle($("#zoom_div")[0]).webkitTransform);
scale = transform.a;
When I read the position of the div at various scale settings it seems to report the correct position, i.e. when I scale the div until is is larger the the screen the position left and top values are negative and appear to be correct, as does the returned scale value:
$("#zoom_div").position().left
$("#zoom_div").position().top
To get the current mouse position I am reading the x and y position from the click event and taking away the offset. This works correctly at a scale value of 1 (no scale) but not when the div is scaled up. Here is my basic code:
$("#zoom_div").on("click", function(e){
var org = e.originalEvent;
var pos = $("#zoom_div").position();
var offset = {
x:org.changedTouches[0].pageX - pos.left,
y:org.changedTouches[0].pageY - pos.top
}
var rel_x_pos = org.changedTouches[0].pageX - offset.x;
var rel_y_pos = org.changedTouches[0].pageY - offset.y;
var rel_pos = [rel_x_pos, rel_y_pos];
return rel_pos;
});
I have made several attempts at multiplying dividing adding and subtracting the scale factor to/from from the pageX / Y but without any luck. Can anyone help me figure out how to get the correct value.
(I have simplified my code from the original to hopefully make my question clearer, any errors you may find in the above code is due to that editing down. My original code with the exception for the mouse position issue).
To illustrate what I am talking about I have made a quick jsfiddle example that allows the dragging of a div using translate3d. When the scale is normal (1) the div is dragged at the point where it is clicked. When the div is scales up (2) it no longer drags correctly from the point clicked.
http://jsfiddle.net/6EsYG/12/
You need to set the webkit transform origin. Basically, when you scale up it will originate from the center. This means the offset will be wrong. 0,0 will start in the center of the square. However, if you set the origin to the top left corner, it will keep the correct coordinates when scaling it. This is how you set the origin:
#zoom_div{
-webkit-transform-origin: 0 0;
}
This combined with multiplying the offset by the scale worked for me:
offset = {
"x" : x * scale,
"y" : y * scale
}
View jsFiddle Demo
dont use event.pageX - pos.left, but event.offsetX (or for some browser: event.originalEvent.layerX
div.on('click',function(e) {
var x = (e.offsetX != null) ? e.offsetX : e.originalEvent.layerX;
var y = (e.offsetY != null) ? e.offsetY : e.originalEvent.layerY;
});
see my jsFiddle exemple: http://jsfiddle.net/Yukulele/LdLZg/
You may embed the scaled content within an iframe. Scale outside the iframe to enable scaled mouse events within the iframe as mouse events are document scope.

relative mouse coordinates in a DIV - javascript

I'm moving the mouse over a div and I want to know the mouse coordinates with respect to the div origin. (upper left corner)
I expected the mousemove event to contain the relative (client?) coordinates of the mouse, but apparently it doesn't.
In firefox for instance, none of the event properties* contain relative coordinates
Am I missing something?
*clientX,Y - pageX,Y - screenX, y
You're not missing anything, but you'll need to calculate the relative coordinates yourself.
Something along these lines should do it (substitute jquery with w/e code you want to use to get the position):
var pos = $('div').position();
var relX = event.pageX - pos.left;
var relY = event.pageY - pos.top;
Also see: JS: mouse coordinates relative to an element which covers some of the details on supporting other browsers (though if you're using jquery that may not be needed).

Categories