CSS3 Transform only plays first item - css

I am trying to get my div to rotate 360deg every time I click it, using CSS3 transform rotate. However, I'm also using the CSS3 transform translate to vertically align my div.
On the first click, it applies all the required CSS but doesn't actually rotate, however will rotate all clicks after that. It stays vertically aligned the whole time.
Unsure how to solve this and any help is appreciated :)
My css:
#my-div {
height: 300px;
width: 300px;
transition: all 0.5s ease-in-out;
display: block;
margin: auto;
/*to vertically align*/
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
My javascript
var angle = 360
$('#my-div').click(function() {
$(this).css({
'-webkit-transform' : 'translateY(-50%) rotate('+angle+'deg) ',
'transform' : 'translateY(-50%) rotate('+angle+'deg)'
})
angle += 360
});

In fact the transition works properly only when the 2 ends are explicitly set, here intially the rotate transform is not set explicitly, after the first click, it's explicitly set to rotate(360deg) and hence the next clicks work. To solve this, you just need to apply rotate(0deg) for your div initially via the CSS code:
#my-div {
/*...*/
-webkit-transform: translateY(-50%) rotate(0deg);
transform: translateY(-50%) rotate(0deg);
}
Note that I emphasized on the properly word, in fact if you set the initial angle to some angle equal or smaller than 180deg, you'll see it transitions OK. I doubt that if you don't set the initial rotate transform explicitly, the behavior is determined by the browser, that is 360deg won't make any transition, otherwise the rotating transition may be clockwise (if the angle % 360 is less than or equal to 180deg) and counter-clockwise if the angle % 360 is greater than 180deg (note about the modulo operation between angle and 360).
Demo.

Related

CSS Animations: Move elements in flow, if expandable is animated to open state

I am currently building a css transition for an expandable component.
Now I add a scale(Y) transform on the element when opening (scale 0 > 1) or reverse the animation on close:
/*
* Animation: Slide In from Top
*/
.u-slide-from-top-enter-active,
.u-slide-from-top-leave-active {
transition-duration: $s-animation-duration-default;
transition-property: transform, opacity;
transform-origin: top;
overflow: hidden;
}
.u-slide-from-top-enter,
.u-slide-from-top-leave-to {
transform: scaleY(0);
opacity: 0;
}
.u-slide-from-top-enter-to,
.u-slide-from-top-leave {
transform: scaleY(1);
opacity: 1;
}
This works all great, but Now the element below in the flow in the DOM jumps from one position to the other.
I first thought I could animate the height, but this does not work, then I thought I could animate the max-height, but this would not work with a value of max-height: auto.
So my question:
If I open the the expandable, can I somehow add some transition classes to the following elements in the DOM to transition their position (although I don't set a position property explicitely.
I find some help here:
https://css-tricks.com/using-css-transitions-auto-dimensions/
But I don't want to use Javascript. If you see the javascript example you see the wanted behaviour, but I want it to make with css.
Thanks for inputs on that.
Cheers

transform: rotateY() making element disappear

I am trying to apply a simple transform: rotateY(90deg) on an div but it's (the div) disappearing as a result, dev tools is not throwing any error on that line, any suggestions or anything I might be missing?
This happens because when you rotate something on the Y axis by 90 degrees it has spun so that it's essentially facing a different direction. In the below example I've added a transition to show how the element changes over time (hover over it):
figure {
background: red;
height: 100px;
transition: 1s;
width: 100px;
}
div:hover figure {
transform: rotateY(90deg);
}
<div>
<figure></figure>
</div>
As our viewport looks directly onto the element and features no depth, it appears that the element has disappeared altogether.
If we do add some depth, it's easier to visualise what's happening:
The cube on the left is our pre-transform cube and the cube on the right is our cube after it's had rotateY(90deg) applied to it. As we have no depth at all and we're looking at our element front on, we can't see anything when it gets rotated by 90 degrees.

Strange animation with transition on transform matrix

I'm getting a weird behaviour in my animation when I'm using transition on transform:matrix(). I'm only changing one parameter, but in the transition it looks like it's handling multiple parameters.
Hard to explain, so here's an example:
div {
width: 200px;
height: 400px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
span {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: red;
transform: matrix(1, -.5, 0, 1, 0, 0);
transform-origin: left bottom;
transition: transform .5s ease;
}
div:hover span {
transform: matrix(1, 0, 0, 1, 0, 0);
}
<div>
<span></span>
</div>
External jsbin link
As you can see, it's only supposed to animate the bottom right corner (the top left is animated too, but out of view), but it seems to be doing something strange in the upper left hand corner. Any ideas how to get around this? Is there some trick to transitioning between transform:matrix?
You can use transform: skewY(-28deg); rather than transform: matrix(1,-.5,0,1,0,0); and transform: skewY(0); rather than transform: matrix(1,0,0,1,0,0);
Like I say here
When animating or transitioning transforms, the transform function lists must be interpolated. Two transform functions with the same name and the same number of arguments are interpolated numerically without a former conversion. The calculated value will be of the same transform function type with the same number of arguments.
Special rules apply to rotate3d(), matrix(), matrix3d() and perspective(). The transform functions matrix(), matrix3d() and perspective() get converted into 4x4 matrices first and interpolated. If one of the matrices for interpolation is singular or non-invertible (iff its determinant is 0), the transformed element is not rendered and the used animation function must fall-back to a discrete animation according to the rules of the respective animation specification.
maybe at some point in the transition(you'll have to do the math) appears a singular matrix and the animation function must fall-back to a discrete animation
Here is the full information
What you can do is to increase the scaleX and scaleY then decrease the translateX:
transform: matrix(1.2, 0, 0, 1.2, -30, 0);
DEMO
Trick? I don't think so, but it behaves like using skew in a photo editor (e.g Photoshop).
If you skew an element and then skew it again to bring it back to its original state(by doing it slowly) you may see the same behaviour

CSS3 Transforms: Multiple Origins?

Is it possible to specify an origin at the top left (0%, 0%) for scaling, and a different origin (center) for rotation in CSS3? I am only working with webkit, if that helps.
I am currently using a transform list (i.e. -webkit-transform: scale(newScale) rotate(newRotate)
but it seems like it isn't possible to change the origin in-between passes. Is there a better way to look at this? Presently, if I scale an object and rotate it with an origin at the default center, the position of the element is now off and so when you drag the element, the cursor is still at the top left of the element, whereas it should be at the center. Changing the origin to the center to scale it fixes this, but presents new problems with rotation and flipping.
Found a good solution to the problem... by creating a parent/child relationship as follows:
<div class="container">
<img src="" />
</div>
I can now setup two classes as follows:
.container {
-webkit-transform-origin: 0% 0%;
-webkit-transform: scale(0.5);
}
.container img {
-webkit-transform-origin: 50% 50%;
-webkit-transform: rotate(45deg);
}
This will do exactly what I want: scale with an origin at the top left, then rotate with the origin at the center. Voila!
Instead think of the scaling with origin (0,0) as a scaling+translation with origin center. In isolation the following:
-webkit-transform-origin: top left;
-webkit-transform: scale(1.5);
is the same as:
-webkit-transform-origin: center;
-webkit-transform: scale(1.5) translate3d(16.66%, 16.66%, 0);
In theory the rotation origin center should leave the corners sticking out by sqrt(1/2)-0.5 requiring us to move the origin down and right by 20.71%, but for some reason the webkit transform algorithm moves things down for us (but not quite enough) and scales the origin for us (again not quite). Thus we need to move right by 50% and make some adjustments for this odd behavior:
-webkit-transform-origin: center;
-webkit-transform: scale(1.5) rotate(45deg) translate3d(52.5%, 0.5%, 0);
-webkit-transition: all 2s ease-in;
Note: my original answer was using a div with width:100px; and height100px; which requires a translate3d(54px, 0, 0).
What about that: http://jsfiddle.net/22Byh/1/

How to determine direction of rotation in CSS3 transitions?

I'd like to rotate an object from -180 degrees to 180 degrees via CSS3 transforms and transitions. This works fine, but I'd like to control the direction of rotation. How to determine if it will be going clockwise or counter clockwise?
0 .. 180 is clockwise, 0 .. -180 is counterclockwise. So, positive number rotates clockwise, negative - other way around. You can also keep increasing/decreasing the number to continue rotation, the browser will remove additional 360s.
I created an example of how to rotate:
<html>
<style type="text/css">
.rotatedDiv {
margin-top: 200px;
margin-left: 200px;
-webkit-transition: -webkit-transform 3s ease-in;
-webkit-transform: rotate(1deg);
-moz-transform: rotate(1deg);
}
</style>
<body>
<div class="rotatedDiv" onclick="this.style.webkitTransform='rotate(-100deg)'">
This div will do a spin when clicked!
</div>
</body>
</html>
First we display rotated div. When you click on it, it will rotate. Depending on the value - negative or positive it will rotate counter-clockwise or clockwise.
It seems that you also need to remember to put in the "from" initial concrete values, otherwise the +/- direction sign won't behave well.

Resources