I have the following HTML and CSS code to draw the top of a cube. So it moves down and I want it to animate as if it is opening up. I am unable to figure out how to transform the top so that it appears to open up.
I have included the entire code for the cube. With respect to this, I want the top to open up.
.pers500 {
perspective: 500px;
-webkit-perspective: 500px;
-moz-perspective: 500px;
}
/* Define the container div, the cube div, and a generic face */
.container {
width: 25%;
margin: 0 auto;
margin-top: 2em;
border: none;
animation-name: moveDown;
animation-duration: 2s;
animation-timing-function: linear;
transform: translate(0px, 110px);
}
.cube {
width: 70%;
height: 70%;
backface-visibility: visible;
perspective-origin: 150% 150%;
transform-style: preserve-3d;
-webkit-backface-visibility: visible;
-webkit-perspective-origin: 150% 150%;
-webkit-transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
}
/* Define each face based on direction */
.front {
width: 3.64em;
height: 3.43em;
background-color: rgba(0, 255, 0, 0.7);
transform: translateZ(50px) translateX(171px) translateY(222px);
-webkit-transform: translateZ(50px) translateX(171px) translateY(222px);
-moz-transform: translateZ(50px) translateX(171px) translateY(222px);
}
.left {
width: 2em;
height: 3.4em;
background-color: rgba(0, 0, 255, 0.7);
margin: 70px;
transform: skewY(40deg) translateZ(50px);
-webkit-transform: skewY(40deg) translateZ(50px) translateY(65px) translateX(-20px);
-moz-transform: skewY(40deg) translateZ(50px) translateY(62px) translateX(-20px);
}
.top {
width: 3.65em;
height: 1.7em;
background-color: rgba(255, 0, 0, 0.7);
margin: 100px;
transform: skewX(50deg) translateZ(50px) translateX(-14px) translateY(20px);
-webkit-transform: skewX(50deg) translateZ(50px) translateX(-14px) translateY(20px);
;
-moz-transform: skewX(50deg) translateZ(50px) translateX(-14px) translateY(20px);
;
animation-name: openTop;
animation-duration: 2s;
animation-timing-function: linear;
}
#-webkit-keyframes moveDown {
0% {
transform: translate(0px, 10px);
}
50% {
transform: translate(0px, 55px);
}
100% {
transform: translate(0px, 110px);
}
}
#keyframes moveDown {
0% {
transform: translate(0px, 10px);
}
50% {
transform: translate(0px, 55px);
}
100% {
transform: translate(0px, 110px);
}
}
#keyframes openTop {
/*0% {transform:rotateX(30deg);}
50% {transform:rotateX(30deg);}
100% {transform:rotateX(30deg);} commented code here doesn't work*/
}
<div class="container">
<div class="cube pers500">
<div class="face front"></div>
<div class="face top"></div>
<br>
<br>
<br>
<div class="face left"></div>
</div>
</div>
To make the cube open up, you first need to set the transform-origin property (as mentioned in the other answer) to top. This setting would make the top side of the .face.top remain fixed when the rotation is being performed. Then you need to add the rotation using rotateX(). This would rotate the top face to produce the opening effect. Note that the transform property should contain the entire list of transforms for it to open correctly. You cannot just add the rotateX() alone within the animation.
.pers500 {
perspective: 500px;
}
/* Define the container div, the cube div, and a generic face */
.container {
width: 25%;
margin: 0 auto;
margin-top: 2em;
border: none;
animation-name: moveDown;
animation-duration: 2s;
animation-timing-function: linear;
transform: translate(0px, 110px);
}
.cube {
width: 70%;
height: 70%;
backface-visibility: visible;
perspective-origin: 150% 150%;
transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
border: 1px solid brown; /* just for testing */
}
/* Define each face based on direction */
.front {
width: 3.64em;
height: 3.43em;
background-color: rgba(0, 255, 0, 0.7);
transform: translateZ(50px) translateX(171px) translateY(222px);
}
.left {
width: 2em;
height: 3.43em;
background-color: rgba(0, 0, 255, 0.7);
margin: 70px;
transform: skewY(40deg) translateZ(50px) translateY(64px) translateX(-20px);
}
.top {
width: 3.65em;
height: 1.69em;
background-color: rgba(255, 0, 0, 0.7);
margin: 100px;
transform: skewX(50deg) translateZ(50px) translateX(-74px) translateY(20px) rotateX(0deg);
transform-origin: top;
animation-name: openTop;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#-webkit-keyframes moveDown {
0% {
transform: translate(0px, 10px);
}
50% {
transform: translate(0px, 55px);
}
100% {
transform: translate(0px, 110px);
}
}
#keyframes moveDown {
0% {
transform: translate(0px, 10px);
}
50% {
transform: translate(0px, 55px);
}
100% {
transform: translate(0px, 110px);
}
}
#keyframes openTop {
0% {
transform: skewX(50deg) translateZ(50px) translateX(-74px) translateY(20px) rotateX(0deg);
}
100% {
transform: skewX(50deg) translateZ(50px) translateX(-74px) translateY(20px) rotateX(200deg);
}
}
<div class="container">
<div class="cube pers500">
<div class="face front"></div>
<div class="face top"></div>
<br>
<br>
<br>
<div class="face left"></div>
</div>
</div>
Note:
Setting a transform-origin will affect the position of the top face in the demo and so the values that you've used for translateX() and translateY() on the top face need to be modified a bit like in the above demo.
The vendor prefixed versions of properties should always be added before the standard property in order to be future proof.
I have removed the vendor prefixed versions in the above snippet just to keep it simple.
Set the transform origin to tbe edge of the cube with
transform-origin: 0 50% 0;
Then rotate it around the z axis:
transform: rotateZ(90deg);
I hope this works for you, I didn't have the chance to test it.
Related
I am trying to rotate a cube with keyframes so it keeps rotating in the same direction with no rotation backwards and keeps rotating horizontally in one direction without reverse on infinite.
<div class="cube">
<div class="cube-face front"></div>
<div class="cube-face back"></div>
<div class="cube-face right"></div>
<div class="cube-face left"></div>
<div class="cube-face top"></div>
<div class="cube-face bottom"></div>
</div>
CSS degrees run over 360 and don't seem to stop... As you can see with the current keyframes the cube will rotate backwards, is there a solution to keep it going with CSS?
.cube {
width: 250px;
height: 250px;
position: relative;
transform-style: preserve-3d;
transform: rotateX(315deg) rotateY(-45deg);
animation: rotate-cube 5s infinite;
margin-bottom: 50px;
cursor: pointer;
}
.cube-face {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 250px;
height: 250px;
border: 2px solid black;
font-size: 90px !important;
font-weight: bold;
color: #000;
}
.cube .front {
background: #f15d2a;
transform: rotateY(0deg) translateZ(125px);
}
.cube .right {
background: #0063a6;
transform: rotateY(90deg) translateZ(125px);
}
.cube .back {
background: #ed1652;
transform: rotate(0deg) rotateY(180deg) translateZ(125px);
}
.cube .left {
background: #12b259;
transform: rotateX(0) rotateY(-90deg) translateZ(125px);
}
.cube .top {
background: #fff;
transform: rotateY(0deg) rotateX(90deg) translateZ(125px);
}
.cube .bottom {
background: #ffd54c;
transform: rotatey(90deg) rotateX(-90deg) translateZ(125px);
}
#keyframes rotate-cube {
0% {
transform: rotateX(315deg) rotateY(-45deg);
}
33.33% {
transform: rotateX(315deg) rotateY(-135deg);
}
66.66% {
transform: rotateX(315deg) rotateY(-225deg);
}
100% {
transform: rotateX(315deg) rotateY(-45deg);
}
}
See example on codepen
Assuming you want the end and start to have the same rotation, you can set the final rotation to -405deg (360 + 45).
This should make sure the animation continues in the correct direction.
0% {
transform: rotateX(315deg) rotateY(-45deg);
}
33.33% {
transform: rotateX(315deg) rotateY(-135deg);
}
66.66% {
transform: rotateX(315deg) rotateY(-225deg);
}
100% {
transform: rotateX(315deg) rotateY(-405deg);
}
I have a css file which makes circle border fill animation perfectly. Its in 100px width and height. But i need only in 50px width and height circle with the same animation. I tried many more times to minimize the size, but the circle not get correctly fix with animation. please help me to smaller this circle.
My need:
Width-50px
Height -50px
border size as per the image file attached -circle border fill sample image
My code
#loading
{
width: 100px;
height: 100px;
margin: 30px auto;
position: relative;
}
.outer-shadow, .inner-shadow
{
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow
{
top: 50%;
left: 50%;
width: 80px;
height: 80px;
margin-left: -40px;
margin-top: -40px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold
{
position: absolute;
width: 100%;
height: 100%;
clip: rect(0px, 100px, 100px, 50px);
border-radius: 100%;
background-color: #fff;
}
.fill, .dot span
{
background-color: #f50;
}
.fill
{
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
}
.left .fill
{
z-index: 1;
-webkit-animation: left 1s linear ;
-moz-animation: left 1s linear ;
animation: left 1s linear both;
}
#keyframes left
{
0%{-webkit-transform:rotate(0deg);}
100%{transform:rotate(180deg);}
}
#-webkit-keyframes left
{
0%{-webkit-transform:rotate(0deg);}
100%{-webkit-transform:rotate(180deg);}
}
.right
{
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill
{
z-index: 3;
-webkit-animation: right 1s linear ;
-moz-animation: right 1s linear ;
animation: right 1s linear both ;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right
{
0%{-webkit-transform:rotate(0deg);}
100%{transform:rotate(180deg);}
}
#-webkit-keyframes right
{
0% {transform: rotate(0deg);}
100% {transform: rotate(180deg);}
}
My code in jsfiddle...!
You need to divide by 2 every values involved, even the clip(); ones (fiddle updated)
#loading {
width: 50px;
height: 50px;
margin: 30px auto;
position: relative;
}
.outer-shadow,
.inner-shadow {
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow {
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold {
position: absolute;
width: 100%;
height: 100%;
clip: rect(0px, 50px, 50px, 25px);
border-radius: 100%;
background-color: #fff;
}
.fill,
.dot span {
background-color: #f50;
}
.fill {
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px, 25px, 50px, 0px);
}
.left .fill {
z-index: 1;
-webkit-animation: left 1s linear;
-moz-animation: left 1s linear;
animation: left 1s linear both;
}
#keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
.right {
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill {
z-index: 3;
-webkit-animation: right 1s linear;
-moz-animation: right 1s linear;
animation: right 1s linear both;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes right {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
.inner-shadow img {
margin-left: 8px;
margin-top: 7px;
}
<div id='loading'>
<div class='outer-shadow'>
</div>
<div class='inner-shadow'>
</div>
<div class='hold left'>
<div class='fill'></div>
</div>
<div class='hold right'>
<div class='fill'></div>
</div>
</div>
edit: in respond to comment #Filipe
How would the change from clip to clip-path be? I tried (also changing rect to inset), but the animation stops working.
Possible example with clip-path instead clip .
#loading {
width: 50px;
height: 50px;
margin: 30px auto;
position: relative;
}
.outer-shadow,
.inner-shadow {
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow {
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold {
position: absolute;
width: 100%;
height: 100%;
clip-path: polygon(50% 0, 0 0, 0 100%, 50% 100%);
border-radius: 100%;
background-color: #fff;
}
.fill,
.dot span {
background-color: #f50;
}
.fill {
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip-path: polygon(50% 0, 100% 0, 100% 100%, 50% 100%);
}
.left .fill {
z-index: 1;
-webkit-animation: left 1s linear;
-moz-animation: left 1s linear;
animation: left 1s linear both;
}
#keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
.right {
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill {
z-index: 3;
-webkit-animation: right 1s linear;
-moz-animation: right 1s linear;
animation: right 1s linear both;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes right {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
.inner-shadow img {
margin-left: 8px;
margin-top: 7px;
}
<div id='loading'>
<div class='outer-shadow'>
</div>
<div class='inner-shadow'>
</div>
<div class='hold left'>
<div class='fill'></div>
</div>
<div class='hold right'>
<div class='fill'></div>
</div>
</div>
is this what you expect,hope this will help to you.try this.I only concerned about the circle size of 50 px with inside circle.if this is not the case tell me.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jquery</title>
<style type="text/css">
div.circleone{
width: 50px;
height: 50px;
border-radius: 25px;
box-shadow: 1px 2px 1px black;
}
div.circletwo
{
width: 25px;
height: 25px;
border-radius: 12.5px;
box-shadow: 1px -1px 1px black;
position: relative;
top: 25%;
left: 25%;
}
</style>
</head>
<body>
<div class="circleone">
<div class="circletwo"></div>
</div>
</body>
</html>
I have this pen which tries to emulate an object revolving around something. This works, but it isn't smooth. While revolving it pauses around the left and right edges.
I thought it had something to do with animation-timing-function but can't get the desired result with any of the in-built functions like ease-in-out or linear or a custom cubic-bezier function.
How can I make the animation feel smooth? If there are better ways something like this can be done, feel free to let me know.
.overlay {
background-image: -webkit-repeating-linear-gradient(0deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
height: 200px;
position: relative;
width: 40%;
margin: auto;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 0;
display: inline-block;
}
.move {
-webkit-animation: moveAndGlow 2s infinite ease-in-out;
animation: moveAndGlow 2s infinite ease-in-out;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
#keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
<div class="overlay">
<span class="circle move"></span>
</div>
If you want to move you element in a 3d environement, you can use the perspective property and actual 3d rotation.
Right now you are animating on straight lines between positions so simulating a rotation is almost imposible. I built the following example, you will need to tweak the size to fit it into your project but you should get the idea.
Also note that I put the gradient background in a pseudo element so it appear in front of the moving object :
.overlay {
height: 200px;
position: relative;
width: 40%;
margin: auto;
perspective:500px;
margin-top:50px;
}
.overlay:after{
content:'';
position:absolute;
top:-100px; left:-10%;
width:120%; height:100%;
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 50%;
margin-left:-50px;
transform: rotateY(0deg) translateX(-100px) rotateY(0deg);
display: inline-block;
}
.move {
animation: moveAndGlow 2s infinite linear;
}
#keyframes moveAndGlow {
to{ transform:rotateY(360deg) translateX(-100px) rotateY(-360deg); }
}
<div class="overlay">
<span class="circle move"></span>
</div>
I found this made it smoother
.move {
-webkit-animation: moveAndGlow 2s infinite linear;
animation: moveAndGlow 2s infinite linear;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
-webkit-animation-timing-function:ease-out;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
}
I've got some boxes (think oblong chocolate boxes) that I want to unfold and show the contents of. The content will be another div with text, video etc., but I'm currently concerned with the unfolding animation itself.
I've got it sort of working, but the top two divs leave a gap between them while animating. Is there some way I can link them together while 'unfolding' them?
Demo: JSFiddle
HTML:
<section>
<div class="block3d">
<div class="front">
<h4>CHOCOLATE</h4>
</div>
<div class="top"><h4></h4></div>
<div class="back">
<ul>
<li>Chocolate</li>
<li>Milk</li>
<li>Nuts</li>
<li>Oranges</li>
</ul>
<a class="infolink" href="#">Open me</a>
</div>
<div class="bottom"><h4></h4></div>
</div>
</section>
Javascript:
$(document).ready(function(){
$(".block3d .infolink").click(function(e){
openBlock(this, e);
});
});
function openBlock(element, event)
{
event.preventDefault();
$(element).closest('section').addClass('open');
$.scrollTo($(element).closest('section'), {duration: 1000});
}
CSS:
section
{
-webkit-perspective: 800px;
-webkit-perspective-origin: 50% 100px;
-moz-perspective: 800px;
-moz-perspective-origin: 50% 100px;
-ms-perspective: 800px;
-ms-perspective-origin: 50% 100px;
perspective: 800px;
perspective-origin: 50% 100px;
width: 960px;
height: 240px;
margin: 10px auto;
transition-property: height;
transition-timing-function: linear;
transition-duration: 0.5s;
transition-delay: 100ms;
}
section.open
{
height: 960px;
}
.block3d
{
position: relative;
width: 960px;
height: 200px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
margin: 0 auto;
-webkit-transform-origin: 0 100px;
-moz-transform-origin: 0 100px;
-ms-transform-origin: 0 100px;
transform-origin: 0 100px;
transition-property: transform, display;
transition-timing-function: linear;
transition-duration: 0.5s;
transition-delay: 100ms;
}
.block3d:hover, .open .block3d
{
-webkit-transform: rotateX(-180deg);
-ms-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
/* Positioning of the different faces of the block */
.block3d div
{
position: absolute;
width: 960px;
height: 200px;
background-color: rgba(0,0,0,0.4);
color: #FFFFFF;
}
.block3d .back
{
-webkit-transform: translateZ(-100px) rotateX(180deg);
-moz-transform: translateZ(-100px) rotateX(180deg);
-ms-transform: translateZ(-100px) rotateX(180deg);
transform: translateZ(-100px) rotateX(180deg);
background-color: #323232;
}
.block3d .top
{
-webkit-transform: rotateX(-270deg) translateY(-100px);
-webkit-transform-origin: top center;
-moz-transform: rotateX(-270deg) translateY(-100px);
-moz-transform-origin: top center;
-ms-transform: rotateX(-270deg) translateY(-100px);
-ms-transform-origin: top center;
transform: rotateX(-270deg) translateY(-100px);
transform-origin: top center;
}
.block3d .bottom
{
-webkit-transform: rotateX(-90deg) translateZ(100px);
-moz-transform: rotateX(-90deg) translateZ(100px);
-ms-transform: rotateX(-90deg) translateZ(100px);
transform: rotateX(-90deg) translateZ(100px);
}
.block3d .front
{
-webkit-transform: translateZ(100px);
-moz-transform: translateZ(100px);
-ms-transform: translateZ(100px);
transform: translateZ(100px);
}
/* Div content styling */
.block3d h4, .block3d ul
{
margin-left: 480px;
background-color: #323232;
margin-top: 0;
}
.block3d h4
{
font-size: 20px;
text-align: center;
padding-top: 90px;
height: 110px;
width: 300px;
}
.block3d ul
{
padding: 40px;
height: auto;
width: 220px;
}
.block3d .infolink
{
display: block;
margin-left: 455px;
height: 30px;
width: 100px;
color: #ffffff;
text-align: center;
padding: 2px;
border: 1px dashed #FFFFFF;
border-top-right-radius: 30px;
border-top-left-radius: 30px;
border-bottom: 0;
}
/* Open animations for the different parts */
.open .block3d .top
{
-webkit-transform: rotateX(-360deg) translateY(-200px) translateZ(100px);
-moz-transform: rotateX(-360deg) translateY(-200px) translateZ(100px);
transform: rotateX(-360deg) translateY(-200px) translateZ(100px);
transition-property: transform;
transition-timing-function: linear;
transition-duration: 0.5s;
transition-delay: 0s;
}
#-webkit-keyframes openback
{
0% {-webkit-transform: translateZ(-100px) rotateX(180deg) translateY(0)}
50% {-webkit-transform: rotateX(270deg) translateZ(300px)}
100% {-webkit-transform: rotateX(360deg) translateY(400px) translateZ(100px)}
}
#-moz-keyframes openback
{
0% {-moz-transform: translateZ(-100px) rotateX(180deg) translateY(0)}
50% {-moz-transform: rotateX(270deg) translateZ(300px)}
100% {-moz-transform: rotateX(360deg) translateY(400px) translateZ(100px)}
}
#keyframes openback
{
0% {transform: translateZ(-100px) rotateX(180deg) translateY(0)}
50% {transform: rotateX(270deg) translateZ(300px)}
100% {transform: rotateX(360deg) translateY(400px) translateZ(100px)}
}
.open .block3d .back
{
-webkit-animation: openback 1s 1 linear forwards;
-moz-animation: openback 1s 1 linear forwards;
animation: openback 1s 1 linear forwards;
}
.open .block3d .bottom
{
-webkit-transform: rotateX(-360deg) translateZ(100px) translateY(200px);
-moz-transform: rotateX(-360deg) translateZ(100px) translateY(200px);
transform: rotateX(-360deg) translateZ(100px) translateY(200px);
transition-property: transform;
transition-timing-function: linear;
transition-duration: 0.5s;
transition-delay: 0.0s;
}
/* Move the block into place */
.open .block3d
{
-webkit-transform: translateZ(100px) rotateX(180deg) translateY(-440px);
-moz-transform: translateZ(100px) rotateX(180deg) translateY(-440px);
transform: translateZ(100px) rotateX(180deg) translateY(-440px);
transition-property: transform;
transition-timing-function: linear;
transition-duration: 1s;
transition-delay: 0s;
}
If you are looking for cool paper fold/unfolding animations take a look at this tutorial and here is the code on git. I'd look specifically the pfold.jquery.js file in order to achieve this sort of animation.
Although it might take a little tweaking of the js/css to get it to look how you want since this is for unfolding paper instead of unwrapping a box, but the basic animation is there.
You can add a 1px pseudo element to the top and bottom of the intersecting elements. You may want to add this during the animation and then remove it after so you don't see extra space when it has stopped.
Here is a JSFiddle
Relevant CSS
.back {
position: absolute;
top: -1px;
margin-top: 1px;
margin-bottom: 1px;
}
.block3d h4
{
display: block;
position: absolute;
top: -1px;
font-size: 20px;
text-align: center;
padding-top: 90px;
height: 110px;
width: 300px;
margin-top: 1px;
margin-bottom: 1px;
}
.block3d h4:before,
.block3d h4:after,
.back:before,
.back:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 1px;
background: #323232;
}
.block3d h4:before,
.back:before {
top: -1px;
}
.block3d h4:after,
.back:after {
bottom: -1px;
}
I would like to reproduce this jsfiddle I that prepared based on this awesome tutorial (please check the demo). But I don't want the keys functionality, just on hover.
http://jsfiddle.net/b5rmW/5/
But that only uses 2 faces (front and back).
I tried, like this:
#cube {
position: relative;
margin: 100px auto 0;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform .5s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform .5s linear;
-moz-transform-style: preserve-3d;
}
.face {
position: absolute;
height: 300px;
width: 300px;
padding: 0px;
background-color: rgba(50, 50, 50, 1);
font-size: 27px;
line-height: 1em;
color: #fff;
border: 1px solid #555;
border-radius: 3px;
}
#cube .one {
-webkit-transform: rotateX(90deg) translateZ(150px);
-moz-transform: rotateX(90deg) translateZ(150px);
background:red;
}
#cube .two {
-webkit-transform: translateZ(150px);
-moz-transform: translateZ(150px);
background:gold;
}
#cube .three {
-webkit-transform: rotateY(90deg) translateZ(150px);
-moz-transform: rotateY(90deg) translateZ(150px);
background:blue;
}
#cube .four {
-webkit-transform: rotateY(180deg) translateZ(150px);
-moz-transform: rotateY(180deg) translateZ(150px);
background:green;
}
#cube .five {
-webkit-transform: rotateY(-90deg) translateZ(150px);
-moz-transform: rotateY(-90deg) translateZ(150px);
background:orange;
}
#cube .six {
-webkit-transform: rotateX(-90deg) rotate(180deg) translateZ(150px);
-moz-transform: rotateX(-90deg) rotate(180deg) translateZ(150px);
}
#cube:hover{
transform:rotateY(90deg);
}
http://jsfiddle.net/5XTeU/1/
But the effect seems not to be the same.
What do you think is the minimum divs needed to achieve this first fiddle??
Thanks.
Update: So a slight misunderstanding on which faces need to exist… so this update is for a front and side face rotation.
However, in the original answer below, points 1) and 2) are still valid problems with the code. Points 3) and 4) no longer apply since they were concerned with the back face. The remaining CSS rules can be removed. You could also pull in the perspective wrapper to give the cube a "less flat" look - see updated demo.
HTML
<div id="experiment">
<div class="cube">
<div class="face front">
front face
</div>
<div class="face side">
side face
</div>
</div>
</div>
CSS
#experiment {
-webkit-perspective: 800;
-webkit-perspective-origin: 50% 200px;
-moz-perspective: 800;
-moz-perspective-origin: 50% 200px;
}
.cube {
position: relative;
margin: 100px auto 0;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform .5s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform .5s linear;
-moz-transform-style: preserve-3d;
}
.face {
position: absolute;
height: 300px;
width: 300px;
padding: 0px;
font-size: 27px;
line-height: 1em;
color: #fff;
border: 1px solid #555;
border-radius: 3px;
}
.cube .front {
-webkit-transform: translateZ(150px);
-moz-transform: translateZ(150px);
background-color:red;
}
.cube .side {
-webkit-transform: rotateY(-90deg) translateZ(150px);
-moz-transform: rotateY(-90deg) translateZ(150px);
background-color:orange;
}
.cube:hover{
-webkit-transform:rotateY(90deg);
}
Original Answer
There are 4 problems with the demo code, so let's look at them individually and see what the solution to each one is:
1) the HTML has a typo on class for the front face - it is missing an r
<div class="face font"> instead of <div class="face front">
2) For Webkit browsers you need to use the prefixed property for transform
-webkit-transform:rotateY(90deg); instead of transform:rotateY(90deg);
3) The back face you have chosen is the wrong face. You have repurposed the left face by accident. The front face is correct, which is a <div> translated 150px outwards. So the corresponding back face should be the one translated -150px inwards. However, if we just do that, the position would be correct but when rotated around the centre of the cube the back face would end up backwards. So the correct back face is the one that is initially rotated by 180° around the Y axis. However, by rotating around the Y axis the translation along Z still needs to be +150px and not -150px.
.cube .back{
-webkit-transform: rotateY(180deg) translateZ(150px);
-moz-transform: rotateY(180deg) translateZ(150px);
background:orange;
}
4) The rotation to get the back face into the position where the front starts should be a rotation of 180° and not 90°
.cube:hover{
-webkit-transform:rotateY(180deg);
}
Putting all those changes together gives this demo.
HTML
<div class="cube">
<div class="face front">
front face
</div>
<div class="face back">
back face
</div>
</div>
CSS
.cube {
position: relative;
margin: 100px auto 0;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform .5s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform .5s linear;
-moz-transform-style: preserve-3d;
}
.face {
position: absolute;
height: 300px;
width: 300px;
padding: 0px;
font-size: 27px;
line-height: 1em;
color: #fff;
border: 1px solid #555;
border-radius: 3px;
}
.cube .front {
-webkit-transform: translateZ(150px);
-moz-transform: translateZ(150px);
background-color: red;
}
.cube .back {
-webkit-transform: rotateY(180deg) translateZ(150px);
-moz-transform: rotateY(180deg) translateZ(150px);
background:orange;
}
.cube:hover{
-webkit-transform:rotateY(180deg);
-moz-transform: rotateY(180deg);
transform:rotateY(180deg);
}