How to position rotated element to the right edge - javascript

I am trying to align an absolute element (image in this case) to the right edge of the container.
It works if the element is not rotated, but when a transformation is involved, the left property is not calculated correctly.
Maybe I am missing something, but the solution I am using right now is getBoundingClientRect() to get the width and then subtract it from the container width.
Here is a JSFiddle that demonstrate what I am doing.

getBoundingClientRect is a good approach, the problem is that when you set css left, it positions it without the rotation calculated. The order in which you set it doesn't change the fact the the rotation is applied in relation to the css, not in relation to the current position of the rotated div. So when you calculate dimensions using getBoundingClientRect you're taking into account the rotation, then you use it on a css that doesn't take it into account.
One easy way to get proper coordinates, would be to calculate the x difference between before rotation and after and adjust you left accordingly. You'll have prevDimension.x - dimension.x giving you the difference in x that the rotation is creating, which allows you to adjust newLeft.
Like this:
$('#rotate-align').click(function () {
var prevDimensions = $('.element')[0].getBoundingClientRect();
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - dimensions.width - dimensions.x + prevDimensions.x;
$('.element').css('left', newLeft);
});
http://jsfiddle.net/jgcynwmp/3/
Another approach would be to calculate the x difference based on the width difference between the non rotated element and the rotated element. This can be done using offsetWidth (which doesn't take the rotation into account) and the getBoundingClientRect. The difference between the 2 will tell you how much width is lost with the rotation. Note that for this calculation, the transform origin is important. For example, with a centered rotation, you'll need to divide by 2 the width difference to get the x difference, but with another origin it would be something else.
Like this:
$('#rotate-align').click(function () {
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - $('.element')[0].offsetWidth + (($('.element')[0].offsetWidth - dimensions.width) / 2);
$('.element').css('left', newLeft);
});
http://jsfiddle.net/jgcynwmp/4/

There is a JSFiddle here.
When the image is rotated, the bounding rectangle remains in the place of the rotation, instead of being to the transformed coordinates.
I added a 'bcr' <div> element which then is matched to the bounding client rectangle.
After the rotation we can move the image into place (477 is the absolute right of bounds).
There appears to be a small problem if you repeatedly click the button, but I guess that's the magic of CSS transforms!
$('#align').click(function () {
var newLeft = $('#bounds').width() - $('.element').outerWidth();
$('.element').css('left', newLeft);
});
$('#rotate-align').click(function () {
$('.element').css('transform', 'rotate(0.69923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
$('.element').css('left',477-dimensions.width-dimensions.left);
$('#bcr').css('left',dimensions.left);
$('#bcr').css('top',dimensions.top);
$('#bcr').css('width',dimensions.width);
$('#bcr').css('height',dimensions.height);
});
#bounds {
width:427px;
height:354px;
left:50px;
top:38px;
border: 1px solid red;
position: absolute;
}
#bcr {
width:327px;
height:254px;
left:150px;
top:138px;
border: 1px solid green;
position: absolute;
}
.element {
top: 100px;
z-index: 102;
line-height: 82px;
width: 312px;
height: 82px;
#transform: rotate(0.99923rad);
left: 0;
position:absolute;
border: 1px solid green;
}
.element-img {
width: 100%!important;
height: 100%!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bounds">
<div class="element">
<img class="element-img" src="https://www.google.com/logos/doodles/2014/2014-winter-olympics-5710368030588928-hp2x.jpg"> </div>
</div>
<input type="button" id="align" value="Align right" style="width:100%;" />
<input type="button" id="rotate-align" value="Rotate and align right" style="width:100%;" />
<div id="bcr"></div>

Related

Get (x,y) coordinates of cursor while typing in text area

I want to display something e.g div under text area where user typing
I managed to obtain where he's currently typing via selectionStart/End, but how can I actually calculate coordinates (x,y) of his cursor?
I suppose there are other ways of achieving that than these two:
Calculating in which row user is (based on font size, text area width and characters count in that text area).
x as textarea.X + selectionStart in this row
y as textarea.Y + rows * font size
I found this, but it is almost 10 years old
https://github.com/Codecademy/textarea-helper
$('textarea').on('keyup paste cut mouseup', function () {
// Get the textarea's content height.
var contentHeight = $(this).textareaHelper('height')
// Set the textarea to the content height. i.e. expand as we type.
$(this).height(contentHeight);
// Follow the caret arounbd.
$('.tail').css(
$(this).textareaHelper('caretPos')
);
});
// Call it manually at first.
$('textarea').keyup();
.tail {
background: red;
width: 50px;
min-height: 50px;
position: absolute;
}
textarea {
width: 250pxpx;
min-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://rawgit.com/Codecademy/textarea-helper/master/textarea-helper.js"></script>
<textarea></textarea>
<div class="tail"></div>

Margin-left animate to the end of div

I have one wrapper div (the grey background) and 5 squares inside it. After the press of a button, the blue one moves and has to stop at the end of the wrapper div, but it goes behind it. How do I make it go to the end of the div, and not behind it?
There is what I've tried so far:
<button id = "start">
Start
</button>
<div style="background-color:rgb(201, 201, 201);width:80%;height:250px" id="horsewrapper">
<div style="height: 50px; width: 100px; text-align: center; background-color: blue;" id="horse1">1</div>
<div style="background-color:red;text-align:center;height:50px;width:100px" id="horse2">1</div>
<div style="background-color:green;text-align:center;height:50px;width:100px" id="horse3">1</div>
<div style="background-color:yellow;text-align:center;height:50px;width:100px" id="horse4">1</div>
<div style="background-color:orange;text-align:center;height:50px;width:100px" id="horse5">1</div>
</div>
Demo can be found here:
https://jsfiddle.net/wqrun6ny/2/
Thanks
https://jsfiddle.net/wqrun6ny/3/
Margin 100% adds margin to widh of element. To avoid this you should add to your animate function left property which is equal to width of element:
$('#horse1').animate({"margin-left":"100%", 'left': -100} ....
but it will works only if element has position:relative
You can make a calculation before start the animation. It takes the width of the wrapper and substract it the width of the "horse":
https://jsfiddle.net/wqrun6ny/4/
$('#start').click(function(){
var margin = $('#horsewrapper').width() - $('#horse1').width();
$('#horse1').animate({"margin-left": margin},{"duration":1000,"easing":"linear"});
});
Edit
According with the request in comments, you can use stop()method and then reinitialise the animation, it works perfectly:
https://jsfiddle.net/wqrun6ny/15/
$('#start').click(function(){
animate($('#horse1'));
});
$(window).on('resize', function() {
$('#horse1').stop();
animate($('#horse1'));
});
var animate = function(element) {
var margin = $('#horsewrapper').width() - element.width();
element.animate({"margin-left": margin},{"duration":5000,"easing":"linear"});
};
You will notice a problem, if you don't push the button but you resize the window, it will start the animation. To avoid this you can add a flag or check if the div is in the initial position.
You have to calculate margin first, then animate according to margin.
Try like this:
$('#start').click(function(){
var mar = $('#horsewrapper').width() - $('#horse1').width();
$('#horse1').animate({"margin-left": mar}, {"duration":1000,"easing":"linear"});
});
https://jsfiddle.net/wqrun6ny/14/
You could calculate the width of the container, and subtract the width of the boxes your moving. Pushing it 100% will result in what your demo is displaying.
If its a static box width the same width, you can just use a static pixel value as well.
var horsewrapperWidth = $('#horsewrapper').width() -100;
100 is the width of your "horses".
$('#horse1').animate({"margin-left": horsewrapperWidth + 'px'},{"duration":5000,"easing":"linear"});
Simplest way !
$('#start').click(function() {
// added this variable to get width of box
var box = $('#horsewrapper').width();
$('#horse1').finish().css("margin-left", "initial");
$('#horse1').animate({
"margin-left": box - 100 // box - width of horse (100%-100px)
}, {
"duration": 5000,
"easing": "linear"
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="start">
Start
</button>
<div style="background-color:rgb(201, 201, 201);width:80%;height:250px" id="horsewrapper">
<div style="height: 50px; width: 100px; text-align: center; background-color: blue;" id="horse1">1</div>
<div style="background-color:red;text-align:center;height:50px;width:100px" id="horse2">1</div>
<div style="background-color:green;text-align:center;height:50px;width:100px" id="horse3">1</div>
<div style="background-color:yellow;text-align:center;height:50px;width:100px" id="horse4">1</div>
<div style="background-color:orange;text-align:center;height:50px;width:100px" id="horse5">1</div>
</div>

How to find a position somewhere in div tag using jquery

Also please view the attached image for clarification. I have a div container what I want to to find a position somewhere in that div container using jquery or javascript or both. The attached image shows everything. Please help.
Update
The reason I want to find this position is that I want to animate container towards that point and eventually disappear. Secondly I would like to find position on the opposite side too so that I could animate container from that position.
Second update
In other words how can we find the point of intersection of two lines?
Given you need to find the intersection between two lines inside a div, your markup could look like this:
<div id="container" style="position:absolute; width: 100%; height: 200px;">
<div style="width: 2px; height: 100%; left: 20%; position:absolute; background-color: red; top: 0;"></div>
<div style="height: 2px; width: 100%; left: 0; position:absolute; background-color: blue; top: 25%;"></div>
</div>​
Using jQuery, you can find the coordinates for the intersection like this:
var x = $('#container div:first').position().left;
var y = $('#container div:last').position().top;
console.log(x,y);
x and y would be the coordinates in pixels relative to the container element.
http://jsfiddle.net/sAsmj/
I dont see the image, however if you are looking at getting the position, which is ideally caret position, you can use the jquery plugin http://plugins.jquery.com/project/jCaret
You can find the poiter position by using this, try it
$(document).ready(function(){
$("div#container").on("mousemove", function(e){
var self = $(this);
var dx = e.pageX;
var dy = e.pageY;
var x = dx - self.offset().left ;
var y = dy - self.offset().top ;
console.log(x);
console.log(y);
});
});
If you want the X, Y of the mouse you can read this question:
getting the X/Y coordinates of a mouse click on an image with jQuery
Here is an excerpt from the question which is based upon an img but you can change it for your container:
$(document).ready(function() {
$('img').click(function(e) {
var offset = $(this).offset();
alert(e.clientX - offset.left);
alert(e.clientY - offset.top);
});
});

jQuery animate width from centered x coordinates of the element

Is possible to animate() the width of an element making a smooth center animation?
I mean animate making the element fixed on itself centered on himself x coordinates?
if i do :
<a class="animate">hey</a>
$('.animate').animate({'width':'+=1%'},500);
it works but the element is animated on the right and not from the center of himself
Yes, you'll have to move the element also.
<a class="animate" style="display:block; width:300px; border:1px solid #000; position:fixed; top:50px; left:50px;">hey</a>
jQuery(".animate").animate({'width':'0px', 'left':'200px'});
http://jsfiddle.net/7Ysbg/
New Information
So you mean something like this: http://jsfiddle.net/7Ysbg/2/
jQuery(".animate").click( function(){
var w = jQuery(".animate").width();
var new_w = jQuery(".animate").width()*1.5;
var left = jQuery(".animate").offset().left - ((new_w - w)/2);
jQuery(".animate").animate({'width':new_w+'px', 'left':left+'px'}, 'fast');
});
Just animate not only the width but also the position of the element. For example you can animate the left property. In this case you element should have position set to relative or absolute.
var width = $('.animate').width();
$('.animate').animate({
width: width*1.01,
left: width*0.005
},500);

How to get the maximum possible width of a div?

I need to know how one can get the maximum possible width of a div. Generally, a <div>'s width is limited by it's parent, meaning that it can not be larger than a certain amount. How that certain amount can be calculated?
I need this to calculate if the text inside the current <div> has overflown, (since the only way to detect a text overflow is to compare it's current width to its current clientWidth).
Thanks!
A couple ways to do this, let's start with your div...
<div id='mr_cleaver'>
<div id='beaver'>Blah</div>
</div>
...and then someJavascript:
//Method One: Find the width of the div's parent
var max_beaver_width = $('mr_cleaver').offsetWidth
//Method Two: Max out the div, find length, return to original size.
var beaver_width = $('beaver').offsetWidth;
$('beaver').style.width = "100%";
var max_beaver_width = $('beaver').offsetWidth;
$('beaver').style.width = beaver_width + 'px';
//Method Three: Check for overflow
$('beaver').scrollWidth > $('beaver').offsetWidth ? alert("Over") : alert("Within")
Thanks Steve!
Your suggestions were very helpful. Although none of them worked for me(probably I didn't explain my situation very well), but using your hints, I could find a way to detect text overflow:
/* specifying the height of 'beaver'*/
var font_size= $('beaver').css("font-size");
font_size = parseInt(font_size.replace(/[a-z]*/gi,''));
var maxHeight = font_size + 4; // 4 is to make sure that the font fits in the maxHeight
/*now calculate current height*/
$('beaver').style.overflow-y:visible;
$('beaver').style.overflow-x:hidden;
var cuurentHeight = $('beaver').clientHeigth;
/* check whether overflow is occured*/
if(cuurentHeight > maxHeight){
//overflow has been occured
}
If you want the div to be 100 % in width with no space between the edges, you can try to add this simpel CSS style to the div:
<style type="text/css">
#FullWidthDiv { // EDIT
position: absolute; // If you use 'fixed' as position, then the div
display: block; // won't become smaller when the screen is at is smallest.
float: left; // The fixed position is good when you for example want the
width: 100%; // menu to stay in place.
background-color: #06F;
height: auto;
left: 0px;
top: 0px
}
</style>
<html>
<body>
<div id="FullWidthDiv"></div>
</body>
</html>
You can append a div into parent element to measure it.
var test = document.querySelector('#test');
var div = document.createElement('div');
div.style.width = '10000px';
test.appendChild(div);
var maxWidth = test.offsetWidth;
test.removeChild(div);
alert(maxWidth);
#test {
display: inline-block;
max-width: 100px;
}
<div id="test"></div>

Categories