I have two objects - parent and child
the parent has some angle , for example: 90 degrees
the child doesn't have angle, but it's also rotated because it's linked to it's parent transforms.
now I need to move the child 100px in the x Axis and -200px in the y Axis ,
but because the parent has angle, the child moved in the wrong directions.
actually, it is the right directions relative to the parent transforms, but I need to move the child relative to the screen.
I need help with the math...
html
<div id="parent">
<div id="child"></div>
</div>
style
#parent {
background: red;
position: absolute;
left: 0px;
top: 0px;
width: 150px;
height: 250px;
-webkit-transform-origin: 75px 200px;
-webkit-transform: translate(300px,160px) rotate(90deg);
}
#child {
background: green;
position: absolute;
left: 0px;
top: 0px;
width: 90px;
height: 120px;
-webkit-transform-origin: 90px 20px;
-webkit-transform: translate(100px,-200px);
}
thanks
As you have seen rotating an element rotates the frame of reference for the element.
In the above diagram the purple axes are the frame of reference for the red rectangle and the green child after a rotation theta clockwise.
You want to move the green rectangle relative to the screen (blue axes), ie translate using the orange vectors.
Given the wanted translation (x,y) relative to screen axes you need to find the translation (xtranslate,ytranslate) relative to the purple axes.
Using the formulas in the diagram with x=100, y=-200 gives xtranslate=-200, ytranslate=-100
Note also that since translate is a move from current position by an amount transforming the origin makes no difference.
So code for child becomes
#child {
background: green;
position: absolute;
left: 0px;
top: 0px;
width: 90px;
height: 120px;
-webkit-transform: translate(-200px,-100px);
}
Related
I'm making a game using React.js, and the player element is a simple image with sprite images implemented in CSS:
.player {
position: absolute;
height: 32px;
width: 32px;
object-fit: none;
transform-origin: 50% 50%;
transform: scale(calc(var(--factor) / 2)) rotate(0.02deg);
image-rendering: pixelated;
}
How would I add the translate() function to make the player's top left corner exactly at (0, 0)?
If you want to be all the way at the top, no matter what else is on the page, position it absolute. This ignores everything up to the next highest positioned element That means it has a position other than the default. You can do that like this.
position: absolute;
top: 0;
left: 0;
/// You might need to adjust for your transform here though
oops... just saw that you already had it absolute. You were 90% of the way there.
For this .player needs a wrapped element with position: relative, and we don't need transform-origin or transform styles:
.parentOfPlayer {
position: relative;
}
.player {
position: absolute;
top: 0;
left: 0;
}
I would like to do something pretty standard in HTML/CSS/javascript I think but somehow I didn't find any solution for now: I want to have multiple images on each other with some of them being clickable. For example:
submarine with red circle button as window in this case the submarine is one img and the red circle is an input type="image" working as a button.
I want those multiple images to behave "as one" in term of responsivness and scaling so that I still see the same overall image independantly of the size of my window.
If I use this trick here: How do I position one image on top of another in HTML? and make both images responsive then the circle is not scaling down simultanuously with the submarine. Moreover, since the red circle is positioned in an absolute way it is not staying at the same place relative to the submarine.
here is my current code:
.div{
position: relative;
}
.responsive {
max-width: 100%;
}
#test2 {
width: 12.3%;
position:absolute;
z-index: 2;
left: 73%;
top: 62%;
}
#test
{
width: 100%;
position:relative;
z-index: 1;
}
<div>
<img src="/submarine.png" id="test" class="responsive" />
<input type="image" src="/red_circle.png" id="test2" class="responsive" />
</div>
In order to achive that, you can work with percentages, so if you reduce the scale of the window the size of the images reduce as well.
CSS:
.submarine {
width: 30%;
height: 55%;
position: relative;
}
.redDot {
width: 2%;
position: absolute;
}
HTML:
<div>
<img src="submarine.jpg" clas="submarine">
<img src="redDot.png" class="redDot">
</div>
Then play with the margins in orther to position the red dot in the submarine.
Dimensions and positions in percentages relate to the dimensions of the parent element. In your case the window of the submarine should be positioned as a percentage of the submarines dimensions. What you should do to make this is work is to put the window as a child in the submarine. Easiest would be to work with divs with background-images and use background-size: 100% to make the background-images scale with the elements.
Also you could use the "padding-bottom trick" to set the "height" of the div to a percentage of the parent's width.
#submarine {
background: yellow;
width: 30%;
padding-bottom: 20%;
position: absolute;
left: 20%;
top: 20%;
}
#window{
position: absolute;
background: red;
width: 20%;
padding-bottom: 20%;
right: 5%;
top: 40%;
background: red;
}
<div id="submarine">
<div id="window"></div>
</div>
As demonstrated here. When changing the width/height of an element that is rotated by some angle. The element moves.
How is it possible to fix and preserve the position of the element at the bottom right or any other corner for that matter when the width or height of the element is changed. And without changing the transform origin.
CSS:
.test{
position: absolute;
top: 200px;
left: 200px;
width: 400px;
height: 200px;
background: red;
transform: rotate(120deg);
}
You can do that by absolutely positioning the .test object using percentages and then offsetting those with transform. By replacing your .test css with the css below you will make the center of the object align to the center of the container no matter what its size is:
.test{
position: absolute;
bottom: 50%;
right: 50%;
transform: translate(50%, 50%) rotate(120deg);
width: 400px;
height: 200px;
background: red;
}
To not make the object centered you will have to play around with the percentages of the bottom, right and translate properties.
I have a div that is centered on the middle of the screen. I need to pass some text to the div and the text will be of various lengths. The problem is that when I pass text to the div, it changes size but wont stay centered. Here's a JSFiddle that demonstrates the problem.
I currently center the div like this:
position: absolute;
top: 50%;
left: 50%;
Add this line:
#divError{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
http://jsfiddle.net/h0d097vp/3/
Your div is not centered. The existing positioning centered the top left corner of the div.
Try this:
#divError{
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%,-50%);
}
JSfiddle Demo
Can you set constant width?, if so here's your answer JSFiddler
Just added
width: 100px;
right: 0;
left: 0;
margin: auto;
Your div is not centered in the beginning either. left: 50% means that the diff starts at 50%, which means that the start of the div is at the center of the page.
When the div has a width of 200px, than still only the start will be at the center.
You can give the div a fixed width, and than add a negative margin of half the width so the div will really be in the center of the page.
Like
#divError{
width: 200px;
margin-left: -100px;
}
When using top and left they position whichever side they are named directly at the position given. So left: 50% will always have the leftmost side positioned directly at the 50% mark. This is not the center, but starts the left side of the div at the center. The same occurs with top: 50%. In order to use top and left you'd need to know the overall width and height and subtract half of their value from their respective top and left (e.g left: calc(50% - ([width of element] / 2)). Since you are using dynamic content you can't know either the height or the width (unless you make them static.)
So what can you do? There are a few ways, but my favorite at the moment is fairly new. It's called flexbox. It's support is decent. There's a nice snippet from css-tricks as well.
The relevant code to center an element both vertically and horizontally would go like this:
$(document).ready(function() {
$("button").click(function() {
$.get("http://lorem.mannfolio.com/", function(data) {
var lorem = data.split("\n\n");
$(".centered").html(lorem[0]);
});
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
border: 1px solid black;
}
button {
position: fixed;
top: 10px;
left: 10px;
}
<button>Change text</button>
<div class="container">
<div class="centered">I'm centered No matter what you put in me.</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have a parent div on which I am applying a rotation transform of -90 deg. Inside the div, one of the child should not transform, I tried transform:none and all its variants but nothing worked and it gets transformed anyways. So, I had to apply a reverse rotation on the child element to set it horizontal.
Now the problem which occurs is that changing the left of child on which reverse rotation was applied actually changes its top and changing top changes its left when altered using Firebug. So the child element is displayed at a wrong position.
if(self._sOrientation == "vertical"){
self.RotatePH($thisComp.closest('.ComponentFrame'),"-90deg");
if(self.isIE==false){
self.RotatePH($thisComp.find('.revertTransform'),"90deg");
// $thisComp.find('.revertTransform').css('-moz-transform', 'none');
}
Actually the component is too complex to provide any usable code on stack overflow
Edit:
I believe the second rotation should be about the axis of the main component instead of rotating about itself. Is it possible to change axis of rotation?
The child has position:fixed; if that matters
I've created a Fiddle to better understand your problem, and i think it's not something related to transformation axis.
More simply, when you alter top, or left position of the child element, it moves correctly referring to it's parent and then the transformation take place.
The child div alter it's position refering to parent div and inheriting it's transformations.
So the final effect that you see is that the object is altering it's left position when you tweak the top and viceversa, but in fact it's not.
Child div seems to moved top and left, but in fact it's not.
I suggest you to change your approach if it's applicable in your situation, and create a fake_parent element that is a child instead (you can see that in the fiddle).
//INSTEAD OF THIS APPROACH
<div class="parent">PARENT DIV
<div class="child">CHILD DIV</div>
</div>
//USE THIS APPROACH
<div class="fake_child">CHILD DIV
<div class="fake_parent">PARENT DIV</div>
</div>
CSS
.parent {
width:100px;
margin:3em;
padding:2em;
transform:rotate(45deg);
-ms-transform:rotate(45deg);
/* IE 9 */
-webkit-transform:rotate(45deg);
background-color:rgb(0, 112, 255);
}
.child {
background-color: #fff;
position: absolute;
padding:1em;
transform:rotate(-45deg);
-ms-transform:rotate(-45deg);
-webkit-transform:rotate(-45deg);
}
.fake_child{
width: 100px;
background-color: #fff;
padding: 1em;
margin: 3em;
position: relative;
}
.fake_parent{
position:absolute;
width:100%;
height:200%;
background-color: rgb(0,121,255);
top:0;
left: 0;
transform:rotate(45deg);
-ms-transform:rotate(45deg);
/* IE 9 */
-webkit-transform:rotate(45deg);
z-index: -1;
}
body {
background-color: #ccc;
font-family: Arial, sans-serif;
}
can't you use transform-origin (http://css-tricks.com/almanac/properties/t/transform-origin/):
-webkit-transform-origin: center center;
-moz-transform-origin: center center;
-o-transform-origin: center center;
transform-origin: center center;
I believe the second rotation should be about the axis of the main component instead of rotating about itself. Is it possible to change axis of rotation?
Yes, if you know the width of the parent (or the ratio of the child's width to the parent's width, I believe). You can use transform-origin to have the child rotate back to its original position by setting transform-origin: hpw hpw, where hpw is half the width of the parent.
If we only rotated the parent and the child was at (0,0) relative to the parent, the child would end up in the bottom left corner of the parent. Imagine a box with its width and height both set to the width of the parent, and positioned at (0,0) relative to the rotated parent. (It follows that the child is in the bottom left corner of this box.) It should be clear that rotating this box will put the child back to it's original position and rotation.
The top and left of the child will still be relative to the rotated parent, so you'll have to position the child with left: your_top * -1 and top: your_left.
Demo: http://jsfiddle.net/HTCwL/1/
Edit: Here's an animated version of the demo to make things clearer http://jsfiddle.net/HTCwL/2/
Relevant CSS:
#parent {
width: 150px;
height: 300px;
border: 1px solid blue;
position: relative;
top: 10px; left: 150px;
-webkit-transform: rotate(-90deg);
}
#child {
position: absolute;
width: 100px;
height: 100px;
left: -10px;
top: 150px;
border: 1px solid red;
-webkit-transform: rotate(90deg);
-webkit-transform-origin: 75px 75px;
}
Edit: Yes, the child having position fixed matters. From https://developer.mozilla.org/en-US/docs/Web/CSS/transform,
If the property has a value different than none [...] the object will act as a containing block for position: fixed elements that it contains.
The containing block for fixed elements is normally the html element (see http://www.w3.org/wiki/CSS_absolute_and_fixed_positioning#Containing_blocks) but when the parent of a fixed element has a transform set it becomes their containing block. I'm not aware of any way to avoid that.