Difference between a transformed div with various point of origin - css

I have one two divs (rectangle) that have each the following transforms applied on:
translate(100px, 100px) scale(2) rotate(20deg)
Those divs are identical except the point of origin varies, one have (0, 0) and the other have (64px, 64px). You can see them here:
http://jsfiddle.net/L7ksC/2/
How can I get the left and top difference between those tho divs?
It can be just a math solution rather then a Javascript one.
Thank you.

I have a solution in a jsfiddle.
I used the position method from jquery, to get top and left. For some angles of rotation the left value will not correspond to the top left corner, but a little trigonometry can sort that out. Please let me know if anything in the jsfiddle is unclear, I'd be happy to explain further.
Keep in mind that the left most point of a box is not the same as the left coordinate of the top point for a 20 degree rotation. In order to calculate the left coordinate I wrote this code:
var scale = 2;
var p_height = 128;
var rotation = 20;
var add_to_left =scale*p_height*Math.sin(rotation*Math.PI/180);
The formula calculates the horizontal distance between the left position and the left coordinate of the top corner. Here is a much simplified fiddle showing the right triangle I am talking about.

Related

Range input thumb gets offset over time

I've looked all over Stackoverflow and it seems that all range sliders with thumb labels have this problem. For example, this answer almost doesn't have it, but still does.
Basically, you can calculate value / max to get the left style for the range value label, so that it's always aligned to the thumb.
The problem is that the further right you slide, the more offset it gets. For example, in the linked answer the label starts off on the left side of the thumb at the 0 value, and it slowly slides to the right side of the thumb by the time it gets to 100.
Why is this happening? I'm implementing my own solution and it suffers from this problem. Also, every answer I've seen on Stackoverflow has this problem. What's causing it, and is there a good solution?
Here's a shitty GIF of the problem:
This is happening because the dot's center does not represent the value. Lets say the dot's size is 10px and the slider is 100px wide. When slider value is 0, the center of the dot is actually at 0px + 5px, i.e. 0 * slider_width + 0.5 * dot_width. When the slider is at 100% then the center of the dot is at 100px - 5px, i.e. 1 * slider_width - 0.5 * dot_width.
To fix this issue you need to subtract an offset value of (percent_as_decimal - 0.5) * dot_width. This will be negative when less than 50% so when subtracted it will add.
Now that above offset will only affect where the leftside of the element is placed. You will also need to place a translate of 50%, via transform: translateX(-50%); to the number's container to address the width of the number element.
To summarize:
1) align left side of number to center of dot
2) translate number to place the center of the number with where the left side was before.

Scale absolute positioned points on a picture map

positioned POIs on a picture map as follows : http://sg-cms.azurewebsites.net/opespe/travel/
I have tried to apply CSS scale and re-positioning in media queries but I can't manage to have a good result. The points are never on the right place.
Do you think it is possible with this method? If not what would you suggest?
Try positioning it with percents - I think it's right direction. Berlin is near top: 21%, left: 49% and scales quite properly at my machine (firefox). Although there is a weird jump near forth zoom level (4 x CTRL + +).

Perspective required for proper rotating animation

I was having an issue where I was attempting to rotate two halves of an image in opposite directions around the y-axis with these two animations:
#-webkit-keyframes first{
0% { -webkit-transform: rotateY(0); }
100% { -webkit-transform: rotateY(-90deg); }
}
#-webkit-keyframes second{
0% { -webkit-transform: rotateY(0);}
100% { -webkit-transform: rotateY(90deg); }
}
Despite the different values for the last keyframe, the two animations rotated in the same direction. Someone rightly pointed out that I needed to apply perspective to my containing space in order to make the effect function (note the checkbox that will apply and remove the perspective from the 3d space to demonstrate):
http://jsfiddle.net/eveQt/12/ - Chrome only
I am curious why this is. From MDN:
The perspective CSS property determines the distance between the z=0 plane and the user in order to give to the 3D-positioned element some perspective. Each 3D element with z>0 becomes larger; each 3D-element with z<0 becomes smaller. The strength of the effect is determined by the value of this property.
From my understanding, perspective moves the viewer along the z plane, making the 3d effect more or less intense. What I don't understand is how moving along the z plane would affect the direction of rotation of an element in such a fashion. I would have thought that perspective would only affect how dramatic the effect is, and not the direction in which the element rotates.
Obviously, application of perspective is a required for the proper rotation direction of each half of the image in my example, but why?
Both halves are rotating correctly around the Y axis, in opposite directions. The trouble is, without perspective, they do not look like they are rotating differently.
Applying perspective in this case basically makes one side of the image larger than the other side, as it rotates around the Y-axis. If there is no perspective, both sides of the image remain the same size, regardless of the direction the image is spinning.
Have a look at the whole image rotating without perspective, and imagine it is rotating in one direction. Then close your eyes, and when you open them again, imagine it is rotating in the other direction. Magic!

Adding depth to a 2D rotated element

In essence, I need to have my div transformed to position itself like the top side of this box (ignoring the radius border, logo, gradient, etc.)
In order to do so, I need to
Rotate the element to the proper angle, which I know how to do using transform:rotate(45deg). Example here. The problem with this is that there is no depth, it just looks like a rotated square because that's what it is. I want it to look like a plane that something could be set on
Add the perception of depth on the element, which I also know how to do using Craig Buckler's approach. Example here
Combine the two effects on the element at the same time. This is the part that I cannot seem to get correct
My basic code
/* HTML */
<div id='square'></div>
/* CSS (without any transforms) */
#square {
width:150px;
height:150px;
background:black;
position:absolute;
top:50%; left:50%;
margin-left:-75px;
margin-top:-75px;
}
I thought I could get the effect I'm looking for by simply combining the two, using
transform: rotate(45deg) perspective(300px) rotateX(25deg);
but I found it was not so. Example here. The problem with this one is that it still does the rotateX based on the original orientation of the element, not the rotated version. Thus, it does not have the proper effect
I thought I could make it take the rotated angle of 45deg into consideration for the rotateX if I applied the rotate(45deg) to a container element, but this was also to no avail. Example here
I have tried variations of these approaches but (of course) have yet to get the effect I'm looking for
Do you have any idea how I can properly achieve this effect?
The correct transform is
perspective(300px) rotateX(25deg) rotate(45deg);
You want the plane where the element is to be always facing you, so first of all you rotate in X. This sets a plane that at the bottom is near you and at the top is far from you, and you don't want this plane to rotate, so you can't place a rotation before it.
Once you have set this plane, then, inside it, you rotate the div.
Maybe this fiddle makes it more clear, hover the div to see the rotation plane.

Calculate translateZ for CSS Transform

I've run into an issue when using the transform property.
I have 1 simple DIV the fills the screen, and another DIV that sits on top of it.
I'm applying the following transform to the DIV on top:
'transform':'rotateX(Xdeg) rotateY(Ydeg)';
I'm also using preserve-3d
This works perfectly in all browsers except Safari. From what I've read, Safari is the only one that actually gets this correct, and clips the top DIV which the transform is being applied to. The other browsers don't clip the DIV. Basically, when the DIV is rotated, it's going inside/behind the bottom layer DIV.
So, I'm assuming that I need to use translateZ to pull the top DIV forward?
My question is, how would I go about calculating how much I need to translate the div forward along the Z axis, or getting this to work in Safari? The rotate X and Y will be variables, so users might be able to rotate the element along either the X, Y, both or none at all.
Any help on this would be amazing. Thanks!
Are your X and Y values always positive ?
In this case,
transform-origin 0% 0%
should do the trick (making the rotation center be the point that will be the lower in the result)
if not, you only need a little logic:
if your X angle is positive, x origin is 0%, else x origin is 100%
if your Y angle is positive, y origin is 0%, else y origin is 100%
and then, apply
transform-origin x-origin y-origin
I am unable to reproduce your problem without a jsFiddle. You could use a function like element.getBoundingClientRect(). This will give you the current coordinates of the second transformed div. If you compare these with the coordinates of the first div you should find the needed translateZ. You need to compare all 4 corners of the transformed div. A negative DELTA means that that corner is intersecting the first div.

Resources