3D Transform around circle on the X axis - css

I'm trying to create a CSS animation where it looks like a div rotates around an image (or another div) on the X axis.
I was able to create a rough idea of it at: http://codepen.io/Kupe517/pen/zBKGev but the animated div does not have the rotation effect I am looking for. I figure I need to add in some kind of rotateX() to the transform and add perspective but I just can't figure out the right combo. I've attached a rough image of the kind of animation I am trying to achieve.
Here is my current animation code:
#keyframes moveBack {
0%{transform:translateY(0); z-index:10;}
25%{transform:translateY(435px); z-index:10;}
26%{z-index:0;}
50%{transform:translateY(0) scale(.8); z-index:0;}
75%{transform:translateY(-435px); z-index:0;}
76%{z-index:10;}
100%{transform:translateY(0); z-index:10;}
}

Here is a simple 3d transition that looks like what you are trying to achieve. The issue is that you are using translate but your aim is to rotate on the X axis.
To launch the transition, hover the div:
div{
position:relative;
width:300px; height:200px;
margin:10% auto;
perspective:500px;
transform-style:preserve-3d;
border:1px solid #000;
}
img{width:100%;}
p{
position:absolute;
left:250px; top:75px;
width:80px; height:40px;
margin:0; padding:5px 10px;
background:gold;
transform: rotateX(0deg) translatez(110px);
transition:transform 2s;
}
div:hover p{
transform: rotateX(360deg) translatez(110px);
}
<div>
<img src="http://i.imgur.com/k8BtMvj.jpg"/>
<p>Hover the div</p>
</div>
If you want the rotating div to always face the user, you can add another rotation after the translatez property like this:
div{
position:relative;
width:300px; height:200px;
margin:10% auto;
perspective:500px;
transform-style:preserve-3d;
border:1px solid #000;
}
img{width:100%;}
p{
position:absolute;
left:250px; top:75px;
width:80px; height:40px;
margin:0; padding:5px 10px;
background:gold;
transform: rotateX(0deg) translatez(130px) rotateX(0deg);
transition:transform 5s;
}
div:hover p{
transform: rotateX(360deg) translatez(130px) rotateX(-360deg);
}
<div>
<img src="http://i.imgur.com/k8BtMvj.jpg"/>
<p>Hover the div</p>
</div>
These work because when you chain transform properties on the same declaration, the last one is made according to the presvious ones. The coordinate system moves with the previous transforms.

I feel bad for this answer; I'll get the animation accurate. One moment-
Edit: Fixed.
A bit sloppy, but here's a working example of the concept you're shooting for. Play with the numbers to get how you want it. Hard to tell from the diagrams for what type of flow you're looking for:
http://codepen.io/anon/pen/JKRxmY?editors=1100
(You had a pesky origin property that I didn't see. Threw in some TranslateZ rules to clean 'er up a bit. )
I also forked this working example after changing the orientation:
http://codepen.io/anon/pen/WxGPpM?editors=0110
(and original) http://codepen.io/pukidepa/pen/nkJmv?editors=0110
The key here is with transform:rotateY(Xdeg);
Try out some of the code. Here's your animation CSS as it stands:
#keyframes moveBack {
0% {
transform: translateY(0) translateZ(100px) rotateX(0deg);
z-index: 10;
}
25% {
transform: translateY(125%) translateZ(-50px) rotateX(-70deg);
z-index: 10;
}
50% {
transform: translateY(0%) translateZ(-100px) rotateX(-180deg);
z-index: 10;
}
75% {
transform: translateY(-125%) translateZ(-50px) rotateX(-270deg);
z-index: 10;
}
100% {
transform: translateZ(25px) translateZ(100px) rotateX(-360deg);
z-index: 10;
}
}
Tip: when working with these types of rotations, it's best to remove the non-essentials like z-index at first and just get the movement down. You can always worry about that stuff later.
For a more circular rotation, you may want to stagger the effects of the rotation with the translation. In other words, try having one of the effects happen slightly before the other at different points of the animation.

Related

Rotate element 50% on hover in, continue rotating in same direction on hover out (CSS only)

I have a button that I want to rotate 50% when I hover over it, and when I move the cursor away, it rotates back to its original position but going the same direction (in other words, it completes a 360 degree rotation). My code is the standard code for this type of thing except that the rotation goes to 180 degrees and goes back on hover off.
.header-popup:hover .link-icon {
transform: rotate(180deg);
}
.header-popup .link-icon {
transition: transform 0.2s ease-in-out;
}
You can achieve this using an extra wrapper. Here is a basic example that you can adapt to your real use case.
.box {
display:inline-block;
width:100px;
height:100px;
transition:0s 1s;
}
.box div {
height:100%;
background:linear-gradient(red 50%,blue 0);
transition:1s;
}
.box:hover {
transform:scaleX(-1);
}
.box:hover div{
transform:rotate(180deg);
}
<div class="box">
<div></div>
</div>

CSS animating breaking clip-path

I'm struggling with the following situation: I have an element which has a clip path to mask it's content. This is later used for an animation, revealing the content. However, there's another element inside which has an animation of it's own, which is not being masked due to the animation.
Have a look here: https://jsfiddle.net/wne2z1m4/
So basically: -webkit-clip-path:inset(-10% 50% 98% 50%); and animation:animation 1s linear 0s infinite; don't seem to be working well together. If you disable the animation on the button element, you can see it will be masked by the container.
Does anyone know if there's a way to keep the button element animating, but also have it masked?
Thanks!
Just add
overflow: hidden;
In the example below I've made some additional changes to make example more clear, but you don't need them. Just add overflow to element with clip-path.
.foo {
outline: 1px dotted red;
}
.bar {
padding:30px;
background: silver;
-webkit-clip-path: inset(1em 1em 1em 2em);
clip-path: inset(1em 1em 1em 2em);
overflow: hidden;
}
.button {
display:inline-block;
background:red;
animation: animation 1s linear 0s infinite;
}
#keyframes animation {
0% { transform: translateY(50px); }
50% { transform: translateY(0); }
100% { transform: translateY(50px); }
}
<div class="foo">
<div class="bar">
<div class="button">
Test
</div>
</div>
</div>

Flip image and stop at a certain angle

I have this CSS:
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
-webkit-transform: scaleY(-1);
transform: scaleY(-1);
filter: FlipV;
-ms-filter: "FlipV";
that flips and image upside down.
All I want is the image to stop when has flipped 90° and so it's invisible.
Is that possible in any way?
If your need is to flip and image by 90 degrees such that it becomes invisible then you should look at using rotate(90deg) transforms (rotateX(90deg) in this case) like in the below snippet.
I am not sure on when you would be making the element become invisible (like :hover, click etc) but if you make it invisible on :hover then put the :hover selector on a container element instead of the image itself. This is because once the image is hovered and becomes invisible due to rotation then the mouse pointer is technically no longer over the image (in other words, hover is no longer applicable). This would mean that the image immediately reverts back to original state automatically.
div {
border: 1px solid #777;
height: 100px;
width: 200px;
}
img {
transition: all 1s;
}
div:hover img {
transform: rotateX(90deg);
}
<div>
<img src="http://lorempixel.com/200/100/nature/1" />
</div>
On the other hand if you are insistent on using scaleY() transform to achieve this effect, then you would have to use scaleY(0) in-order to make the element invisible. scaleY(-1) will always end up at -180deg and there is no way to stop this in the middle.
div {
border: 1px solid #777;
height: 100px;
width: 200px;
}
img {
transition: all 1s;
}
div:hover img {
transform: scaleY(0);
}
<div>
<img src="http://lorempixel.com/200/100/nature/1" />
</div>
http://davidwalsh.name/demo/css-flip.php
Take a look at this demo from great David Walsh :)
I think for you the vertical flip is more interesting
Just change the .front and .back # :hover to 90deg and you get the result you want!

transition scale relative to parent

I am using transition:scale(1.2) to hide a div in the bottom left corner of the viewport.
My current approach is scaling from the center as expected:
Fiddle for 'CURRENTLY'
I want to scale it as if the div would take up the whole screen:
Fiddle for 'DESIRED'
The above is done by scaling the whole body. But instead of using another parent, I was wondering if there is another way to tell CSS in which direction the scaling should occur.
How to use transition:scale(1.2) as seen in DESIRED without using a full-size div?
You can change the transform-origin:
Something like this should be close to what you are looking for:
-webkit-transform-origin: 120% -40%;
Demo Fiddle
Modified CSS:
#clock {
position:fixed;
bottom:8%;
left:7%;
color:#fff;
transition:all .8s;
-webkit-transition:all .8s;
transform-origin: 120% -40%;
-webkit-transform-origin: 120% -40%;
}
body {
overflow:hidden;
}
body:hover #clock {
-webkit-transform:scale(1.2);
transform:scale(1.2);
opacity:0;
}
Edit Because you are using left/bottom percentage based positioning for the clock, this may be closer to the effect you are looking for. Going back to a center based transform origin and transitioning left/bottom closer to the corner will provide a bit more of the affect that it is being scaled from the upper right corner of the parent.
Demo Fiddle 2
Modified CSS:
#clock {
position:fixed;
bottom:8%;
left:7%;
color:#fff;
transition:all .8s;
-webkit-transition:all .8s;
transform-origin: center center;
-webkit-transform-origin: center center;
}
body {
overflow:hidden;
}
body:hover #clock {
-webkit-transform: scale(1.2);
transform: scale(1.2);
bottom: 1%;
left: 0%;
opacity:0;
}

How to center keyframe animation?

I have a keyframe animation using CSS, and I would like to (automatically) make it centered for all resolutions, browsers, etc. I've tried doing margin: auto, etc. But that always results in my animation not working. Perhaps I am inserting it incorrectly, but I don't know. This is what I currently have, without any auto margins.
Here is my CSS code:
#image {
text-align:center;
width:276px;
position:absolute;
left:50%;
margin-left: -130px; /*this is what works for me, I'd imagine it's not */
margin-top: -240px; /*centered for everyone */
animation:dampe 0.3s infinite;
-webkit-animation:dampe 0.3s infinite;
}
#keyframes image {
0% { top:45%; }
50% { top:50%; }
100% { top:45%; }
}
#-webkit-keyframes image {
0% { top:45%; }
50% { top:50%; }
100% { top:45%; }
}
Here is my HTML code:
<div id="image">
<img src="image.png" />
</div>
By aligning the element using the margin-left property and offsetting by a fixed px value like in Joseph's solution you will not achieve a centered effect on all resolutions.
To achieve the centered effect on all resolutions offset your element by 50% from the left side and afterwards set the transform:translate3d(-50%,0,0). This will ensure that your element is always centered on the X axis, no matter the screen size.
/*CSS Markup*/
.centerX{
left:50%;
-webkit-transform:translate3d(-50%,0,0);
}

Resources