I'm trying to create an animation that simulates a "cut from rope" sort of effect.
Picture an object hanging from two ropes. First, the left one is cut, and a bit after the right one is then cut. I have got pretty close to the desire effect, but my animation isn't as smooth as I would like.
You can see that the object sort of bounces back up, which I tried to minimize by translating the entire object down.
My question is, is there a better way to achieve this effect, or any ways to improve my animation?
HTML
<div id="box"></div>
<div id="bottom"></div>
CSS
#box {
width: 400px;
height: 60px;
background: black;
margin: 100px;
animation: ropecut 1.2s 1 ease-out;
transform: rotateZ(0deg);
transform: rotateZ(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
transform: translateY(50px)
}
#bottom {
width: 600px;
height: 2px;
background: red;
margin-top: -50px;
}
#keyframes ropecut {
0% {transform: rotateZ(0deg);transform-origin: top right;animation-timing-function: ease-in-out;}
50% {transform: rotateZ(-7.5deg);transform-origin: top right;animation-timing-function: ease-in-out;}
70% {transform: rotateZ(-7.5deg);transform-origin: top right;animation-timing-function: ease-in-out;}
100% {transform: rotateZ(0);transform-origin: top left;animation-timing-function: ease-in-out;transform: translateY(50px)}
}
Link to JS Fiddle
Try this, I basically just took out the 70% bit of the keyframe and then removed the rotateZ in the 100% sequence. That will keep the bottom left corner where it should stay.
#box {
width: 400px;
height: 60px;
background: black;
margin: 100px;
animation: ropecut 1.2s 1 ease-out;
transform: rotateZ(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
transform: translateY(50px)
}
#bottom {
width: 600px;
height: 2px;
background: red;
margin-top: -50px;
}
#keyframes ropecut {
0% {transform: rotateZ(0deg);transform-origin: top right;animation-timing-function: ease-in-out;}
50% {transform: rotateZ(-7.5deg);transform-origin: top right;animation-timing-function: ease-in-out;}
100% {animation-timing-function: ease-in-out; transform-origin: top right;}
}
<div id="box"></div>
<div id="bottom"></div>
Related
Trying to smoothly animate a div's background image #bg2 over a short pixel distance (while a clip path animates over it). I'm not able to get the image to move smoothly, it jitters and judders. The clip path animation is fine.
I've tried different easing (linear / ease-in-out etc) suggested in another SO thread, and also extending the distance it needs to move, but it still seems to jump pixel by pixel (sort of), rather than move smoothly. (Although, extending the move distance isn't an option in the actual use case).
How can smooth movement of the cat background image #bg2 be accomplished? Thanks.
** Edit: It's totally smooth for me in Firefox, for me it's jittery in Chrome 91.0.4472.114 on Mojave 10.14.6, and less jittery in Safari. For other it seems to be smooth on Chrome also. Hmmm...
var clickTag = "#";
#main-container {
position: absolute;
width: 970px;
height: 250px;
left:-200px;
box-sizing: border-box;
background: #333;
overflow:hidden; perspective: 800px;
border:1px solid #ccc;
}
div, img {
position: absolute;
background-repeat:no-repeat;
width: 970px;
height: 250px;
z-index: 4;
background-size: 970px 250px;
}
#bg2{
width: 970px;
height: 250px;
z-index:2;
background-image:url('https://i.stack.imgur.com/6EcDu.jpg');
-webkit-clip-path: circle(9% at 682px 110px);
clip-path: circle(9% at 682px 110px);
transform: translateY(20px);
background-position: -5px -10px;
}
#bg2{animation: grow 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;-webkit-animation: groww 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;}
#-webkit-keyframes groww {
0% {opacity:1;transform: translateY(20px);clip-path: circle(9% at 682px 110px);-webkit-clip-path: circle(9% at 682px 110px);background-position: -5px -10px;}
100% {opacity:1;transform: translateY(-4px);clip-path: circle(15% at 682px 128px);-webkit-clip-path: circle(15% at 682px 128px);background-position: 0px 0px;}
}
#keyframes grow {
0% {opacity:1;transform: translateY(20px);clip-path: circle(9% at 682px 110px);background-position: -5px -10px;}
100% {opacity:1;transform: translateY(-4px);clip-path: circle(15% at 682px 128px);background-position: 0px 0px;}
}
<a href="javascript:window.open(window.clickTag)">
<div id="main-container" class="animate">
<div id="bg2"></div>
</div>
</a>
I'm a bit curious about why having a large banner while not displaying it all.
Anyways, I provide another way of animating, basically just changing the height. Hopefully that could give some ideas.
I removed the width to make it slightly more responsive.
The animation somewhat jittery in this solution, but I guess that it depends on your bezier curve. So perhaps that's the issue all along?
var clickTag = "#";
#main-container {
position: relative;
height: 250px;
box-sizing: border-box;
border: 1px solid #ccc;
background-color: #333;
}
#bg2 {
position: absolute;
left: 75%;
top: 50%;
transform: translate(-50%, -50%);
height: 40%;
aspect-ratio: 1;
border-radius: 50%;
background-image: url('https://i.stack.imgur.com/6EcDu.jpg');
background-position: right 25% center;
animation: grow 2.5s 2.5s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;
}
#keyframes grow {
to { height: 80%; }
}
<a href="javascript:window.open(window.clickTag)">
<div id="main-container">
<div id="bg2"></div>
</div>
</a>
I have a working demo. just hover the img and there is the effect I want to have.
http://jsfiddle.net/jxgjhzer/1/
As you can see in css file, I don't use any css animation.
Just using CSS transform, I want my img to achieve same effect without hovering it. It should happen automatically.
So how to zoom-in and zoom-out automatically (without animation if possible)?
Code goes here:
.galleryImg{
height:150px;
width:100%;
transform-origin: 50% 50%;
transition: transform 30s linear;
}
.galleryImg:hover{
transform: scale(2) rotate(0.1deg);
}
that's very simple. you can see DEMO on this link on jsfiddle.net
<div class="cardcontainer">
<img class="galleryImg" src="https://www.google.com/logos/doodles/2014/2014-winter-olympics-5710368030588928-hp.jpg">
</div>
#keyframes zoominoutsinglefeatured {
0% {
transform: scale(1,1);
}
50% {
transform: scale(1.2,1.2);
}
100% {
transform: scale(1,1);
}
}
.cardcontainer img {
animation: zoominoutsinglefeatured 1s infinite ;
}
use animation
.galleryImg{
height:150px;
width:100%;
animation:move 3s infinite ease-in-out;
}
#keyframes move{
0%{
transform: scale(1) rotate(0deg);
}
100%{
transform: scale(2) rotate(0.1deg);
}
}
The below css code will help you out for zoom out effect on hover the particular image. Try this code its very useful to you
figure {
width: 300px;
height: 200px;
margin: 0;
padding: 0;
background: #fff;
overflow: hidden;
}
figure:hover+span {
bottom: -36px;
opacity: 1;
}
.hover04 figure img {
width: 400px;
height: auto;
-webkit-transition: .3s ease-in-out;
transition: .3s ease-in-out;
}
.hover04 figure:hover img {
width: 300px;
}
Refer the html code here.
<div class="hover04 column">
<div>
<figure><img src="1.jpeg" /></figure>
<span>Hover Text</span>
</div>
</div>
Revolution slider have option to set slide up image transition and I'm trying to copy that effect so I can use this without revolution slider..
This is slide transition effect.
This is the page where I'm trying to adopt above transition effect.
I tried this CSS but no luck, I don't know how to use key-frames for animation.
Thanks
.full-img.parallax-yes{
overflow-y: hidden;
max-height: 330px;
transition-property: all;
transition-duration: .5s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
transition: background-position 1s;
transform: matrix(1, 0, 0, 1, 0, 0);
transform-origin: 0% 0% 0px;
}
Here I have given an sample code for using the keyframes
<div class="full-height"> </div>;
.full-height {
max-height: 330px;
min-height: 330px;
background-image: url("http://carbongroup.com.au/wp-content/uploads/2015/10/bridge.jpg");
background-size: cover;
background-position: 0% 0%;
background-repeat: no-repeat;
background-color: green;
animation-name: move;
animation-duration: 10s;
animation-timing-function: linear;
animation-iteration-count: 1;
}
#keyframes move {
0% {
background-position: 0% 0%;
}
100% {
background-position: 100% 100%;
}
}
Hope this what you are trying for, simple background-image slide-up animation using CSS animation.
Define two different class inside of your parent div, one for background image and another for text which is positioned as absolute, position:absolute, to move background-image up-side use background-position-y in keyframes and negative value, for downward background-position-y and positive values.
#-webkit-keyframes ani{
from{
background-position-y:0px;
}
to{
background-position-y:-100px;
}
}
#bx{
width:100%;
height:300px;
overflow:hidden;
position:relative;
}
#bx > .iim{
width:100%;
height:600px;
background:url('https://source.unsplash.com/user/erondu');
background-repeat:no-repeat;
background-size:100% 100%;
background-position:fixed;
animation:an 5s forwards;
transition:5s ease forwards;
}
#-webkit-keyframes an{
from{
background-position-y:0px;
}
to{
background-position-y:-100px;
}
}
#bx > .txt{
width:100%;
height:300px;
overflow:hidden;
position:absolute;
color:black;
font-size:32px;
z-index:6;
top:0;
left:0;
}
<div id="bx">
<div class="iim">
</div>
<div class="txt">
Replace following content by your text.
</div>
</div>
You can do like this, and use at lease window.load() so the animation start only, when your page already loaded.
$(window).load(function(){
$('.banner').addClass('loaded');
});
.banner{
width: 100%;
height: 200px;
background-image: url(https://source.unsplash.com/user/erondu);
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
background-position-y: 100%;
color: #fff;
transition: all 5s cubic-bezier(0.47, 0, 0.745, 0.715);
-webkit-transition: all 5s cubic-bezier(0.47, 0, 0.745, 0.715);
}
.banner.loaded{
background-position-y: 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="banner">
<p>this is banner text</p>
</div>
i have two css3 keyframes and trigger by some button, but the issue is when i try to adding a new keyframe (new class) the transition not change in smooth way, how to make this transition working smooth ?
source in fiddle here
.button {
width:50px;
height:50px;
background:silver;
}
.box {
width: 100px;
height: 100px;
background: green;
position: relative;
top: 10%;
left: 10%;
}
.box {
animation: xx 2s linear infinite;
}
.boxShake {
animation:boxShake 2s linear infinite;
}
One trick to achieve this is not to change the animation.
But make a composite animation transforming both the X and the Y in percentages.
Now, changing the width and the height of the element, we modify the amount of movement in one axis or the other of the unaltered animation
$(".button").click(function(){
$("#mover").toggleClass("alternate");
});
.button {
width:50px;
height:50px;
background:silver;
}
.box {
width: 100px;
height: 100px;
background: green;
position: relative;
top: 10%;
left: 10%;
}
.box {
animation: xx 2s linear infinite;
}
#mover {
width: 0px;
height: 20px;
transition: width 2s, height 2s;
animation: mover 2s linear infinite;
}
#mover.alternate {
width: 5px;
height: 0px;
}
#keyframes mover {
0% {transform:translate( 0%, 0%);}
10% {transform:translate(-100%, 20%);}
20% {transform:translate( 100%, 40%);}
30% {transform:translate(-100%, 60%);}
40% {transform:translate( 100%, 80%);}
50% {transform:translate(-100%, 100%);}
60% {transform:translate( 100%, 80%);}
70% {transform:translate(-100%, 60%);}
80% {transform:translate( 100%, 40%);}
90% {transform:translate(-100%, 20%);}
100% {transform:translate( 0%, 0%);}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Button</div>
<div id="mover">
<div class="box"></div>
</div>
Just play with the width and height of the 2 element states, and the transition between them, to adapt it to your needs
I'm trying to create a 3d navbar using pure CSS with transforms, transitions and perspective.
Here is my code:
.navbar-fixed-bottom {
background: transparent;
}
.navbar-perspective {
width: 100%;
height: 100%;
position: relative;
-webkit-perspective: 1100px;
-moz-perspective: 1100px;
perspective: 1100px;
-webkit-perspective-origin: 50% 0;
-moz-perspective-origin: 50% 0;
perspective-origin: 50% 0;
}
.navbar-perspective > div {
margin: 0 auto;
position: relative;
text-align: justify;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
height: 50px;
font-size:20px;
}
.navbar-primary {
background-color: #cccccc;
z-index: 2;
-webkit-transform-origin: 0% 100%;
-moz-transform-origin: 0% 100%;
transform-origin: 0% 100%;
}
.navbar .navbar-secondary,
.navbar .navbar-tertiary {
background-color: #bfbfbf;
width: 100%;
-webkit-transform-origin: 0% 0%;
-moz-transform-origin: 0% 0%;
transform-origin: 0% 0%;
z-index: 1;
-webkit-transform: rotateX(-90deg);
-moz-transform: rotateX(-90deg);
transform: rotateX(-90deg);
-webkit-transition: top 0.5s;
-moz-transition: top 0.5s;
transition: top 0.5s;
position: absolute;
top: 0;
}
.navbar .navbar-tertiary {
background-color: #b3b3b3;
}
.navbar-rotate-primary {
height: 50px;
}
.navbar-rotate-primary .navbar-primary {
-webkit-transform: translateY(0%) rotateX(0deg);
-moz-transform: translateY(0%) rotateX(0deg);
transform: translateY(0%) rotateX(0deg);
}
.navbar-rotate-primary .navbar-secondary,
.navbar-rotate-primary .navbar-tertiary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(-90deg);
-moz-transform: rotateX(-90deg);
transform: rotateX(-90deg);
}
.navbar-rotate-secondary,
.navbar-rotate-tertiary {
height: 50px;
}
.navbar-rotate-secondary .navbar-primary,
.navbar-rotate-tertiary .navbar-primary {
-webkit-transform: translateY(-100%) rotateX(90deg);
-moz-transform: translateY(-100%) rotateX(90deg);
transform: translateY(-100%) rotateX(90deg);
}
.navbar-rotate-secondary .navbar-secondary,
.navbar-rotate-tertiary .navbar-secondary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(0deg) translateY(-100%);
-moz-transform: rotateX(0deg) translateY(-100%);
transform: rotateX(0deg) translateY(-100%);
}
.navbar-rotate-secondary-fallback .navbar-primary,
.navbar-rotate-tertiary-fallback .navbar-primary {
display: none;
}
.navbar-rotate-tertiary .navbar-secondary {
-webkit-transform: translateY(-100%) rotateX(90deg);
-moz-transform: translateY(-100%) rotateX(90deg);
transform: translateY(-100%) rotateX(90deg);
}
.navbar-rotate-tertiary .navbar-tertiary {
top: 100%;
-webkit-transition: -webkit-transform 0.5s;
-moz-transition: -moz-transform 0.5s;
transition: transform 0.5s;
-webkit-transform: rotateX(0deg) translateY(-100%);
-moz-transform: rotateX(0deg) translateY(-100%);
transform: rotateX(0deg) translateY(-100%);
}
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<nav id="navigation-bottom" class="navbar navbar-fixed-bottom">
<div class="navbar-perspective">
<div class="navbar-primary">
Rotate To Face 2
</div>
<div class="navbar-secondary">
Rotate To Face 3
</div>
<div class="navbar-tertiary">
Rotate Back To Face 1
</div>
</div>
</nav>
</body>
</html>
I've got the first two faces to rotate properly using a 3d effect, but the third face does not look right. You will notice as you rotate from second to third that the top does not rotate correctly and looks flat.
Any help is greatly appreciated.
Fiddle with a flipping box
This is vastly different from where you started, but let me post my CSS and show you the fiddle, and then I'll edit in a longer explanation of how and why this works:
HTML
<section class="container">
<nav id="nav-box" class="show-front">
<div class="front">
Show Bottom
</div>
<div class="bottom">
Show Back</div>
<div class="back">
Show Top</div>
<div class="top">
Show Front</div>
</nav>
</section>
CSS
.container {
position: relative;
perspective: 1000px;
transform: scale(0.95);
}
#nav-box {
width: 100%;
height: 50px;
position: absolute;
transform-origin: center center;
transform-style: preserve-3d;
transition: transform 0.5s;
}
#nav-box div {
width: 100%;
height: 50px;
display: block;
position: absolute;
transition: background-color 0.5s;
}
#nav-box .front { transform: rotateX( 0deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .back { transform: rotateX( 180deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .top { transform: rotateX( 90deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box .bottom { transform: rotateX( -90deg ) translateZ( 25px ); background-color: #ccc; }
#nav-box.show-front { transform: rotateY( 0deg ); }
#nav-box.show-front .bottom { background-color: #a0a0a0; }
#nav-box.show-front .top { background-color: #e0e0e0; }
#nav-box.show-back { transform: rotateX( -180deg ); }
#nav-box.show-back .bottom { background-color: #e0e0e0; }
#nav-box.show-back .top { background-color: #a0a0a0; }
#nav-box.show-top { transform: rotateX( -90deg ); }
#nav-box.show-top .front { background-color: #a0a0a0; }
#nav-box.show-top .back { background-color: #e0e0e0; }
#nav-box.show-bottom { transform: rotateX( 90deg ); }
#nav-box.show-bottom .front { background-color: #e0e0e0; }
#nav-box.show-bottom .back { background-color: #a0a0a0; }
Explanation of the HTML/CSS
Setting up our box
You started thinking about this the wrong way, I hate to say. You approached this as "How can I treat these four sides like a box" rather than "How can I make a box in CSS?"
So let's learn how to make a box.
First, we establish a box container. Since this is a navigation box, let's call it nav-box. All the transforms we apply (save for the shading, which we'll get to later) will be done on our nav-box.
The rules on our nav-box will determine how it behaves as an object. Let's discuss two in particular: transform-origin and transform-style
transform-origin defaults to center center, but I wanted to call it out here. This is basically going to tell our box: Hey, we need you to pivot around your absolute center. If we set this up as transform-origin: center bottom' it would look like the box is spinning around its bottom edge. center top` and it would spin around its top edge. I don't think that's what you want, though.
transform-style needs to be set to preserve-3d. What this does is instruct the browser to not fuss with the elements with transform underneath it. Other options include flat which tells the browser to ignore rotates underneath it. The reason we want to set preserve-3d on our nav-box here is to ensure the transforms we applied to the box sides are preserved when we transform the parent. Neat stuff, huh?
Setting up our sides
We're setting our sides as children of our nav-box and just positioning them in the order that they should be in using rotateX:
0 rotation for the front
180deg for the back
-90deg for the bottom
90deg for the top
We could also set a left and right side right now with .left { transform: rotateY(-90deg); } .right { rotateY(90deg); }. Note that we used the Y axis for those two examples.
Secondly, we set a translateZ value of 25px. So what the hell is this doing? It's telling our boxes they need to move 25px from the center of the parent relative to their respective rotations. Why did we choose 25px? Because it's exactly half the height of each of our boxes. This means that it will flush up nicely with the sides at either edge.
And then the fun part:
We shade the boxes based on their position and what is facing the screen. The background colors are relative to what side of the box we're showing with show-front, show-back, etc. The side on the bottom gets darker, the side on the top gets lighter. I just liked that – totally not necessary to accomplish this task but makes it look a little more realistic.
Hope that helps!
Update for IE
Fiddle Example
So, there's not much pretty about this once we get through fixing it up for IE, but here it is. All preserve-3d is doing is applying the transforms for you when we rotate a container, instead of flattening them. If we can't use preserve-3d, we have to calculate based on the amount of total rotation.
This solution does that. I won't go as in-depth on this one, rather than to highlight how much more JavaScript this requires, and to highlight the .rewind class:
#nav-box.rewind div {
backface-visibility: hidden;
}
Because we have to manually rewind this solution, we'll have to prevent the z-index reordering to be applied at the wrong times. That's where backface-visibility comes in.
Example showing depth in IE
Another example without the need for the rewind class
Hope that solves IE for you.
First of all, thank you to all that commented and answered to this question, especially Josh!
Josh, your example works perfectly for browsers that support preserve-3d. The update you posted without preserve-3d appears flat on IE so it was still not perfected for all browsers.
After three days of headaches, I realized the problem. The origin of the sides was not being set correctly. The sides need to rotate around a point that is half way in on the Z axis.
Once I've updated the origin to :
transform-origin: 25px 25px -25px;
Once this was correct, all you really need to do is update the rotation of the object. No need to use any transformation of the X,Y,Z coordinates.
Here's the fiddle and the solution for a 3D Navigation bar that rotates and works for all browsers including IE10+.
http://jsfiddle.net/tx0emcxe/