There are already some nice posts on animating 3d objects in css. However I wondered whether it is possible to do so from the perspective of being inside the object.
This would be nice to build, for example, a pure css game or street view like application.
After some tweaking with the help of David DeSandro, this css did the trick.
#container {
top: 100px;
width: 1200px;
height: 600px;
position: relative;
perspective: 600px;
/* half the width */
border: 2px solid green;
}
#room {
width: 100%;
height: 100%;
position: absolute;
transform-origin: 50% 80% 600px;
transform-style: preserve-3d;
}
#room figure {
margin: 0;
display: block;
position: absolute;
border: 2px solid green;
font: 400px"calibri";
text-align: center;
}
#room .n,
.e,
.s,
.w {
width: 1196px;
height: 596px;
}
#room .n {
background-color: rgba(255, 0, 0, 0.3);
}
#room .e {
background-color: rgba(255, 255, 0, 0.3);
}
#room .s {
background-color: rgba(0, 255, 255, 0.3);
}
#room .w {
background-color: rgba(0, 0, 255, 0.3);
}
#room .t,
.b {
width: 1196px;
height: 1196px;
top: -300px;
background-color: rgba(200, 200, 200, 0.5);
}
/* transform & inverse */
#room .n {
transform: rotateY(0deg) translateZ(0px);
}
#room .e {
transform: rotateY(-90deg) translateZ(-600px) translateX(600px);
}
#room .s {
transform: rotateY(180deg) translateZ(-1200px);
}
#room .w {
transform: rotateY(90deg) translateZ(-600px) translateX(-600px);
}
#room .t {
transform: rotateX(90deg) translateZ(300px) translateY(600px);
}
#room .b {
transform: rotateX(90deg) translateZ(-300px) translateY(600px);
}
#room .show-n {
transform: translateZ(0px) rotateY(0deg);
}
#room .show-e {
transform: translateX(-600px) translateZ(600px) rotateY(90deg);
}
#room .show-s {
transform: translateZ(1200px) rotateY(180deg);
}
#room .show-w {
transform: translateX(600px) translateZ(600px) rotateY(-90deg);
}
#room .show-t {
transform: translateY(-600px) translateZ(-300px) rotateX(-90deg);
}
#room .show-b {
transform: translateY(-600px) translateZ(300px) rotateX(90deg);
}
#room {
animation: 5s hspinner;
}
#keyframes hspinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<section id="container">
<div id="room">
<figure class="n">N</figure>
<figure class="e">O</figure>
<figure class="s">Z</figure>
<figure class="w">W</figure>
<figure class="t">T</figure>
<figure class="b">B</figure>
</div>
</section>
Enjoy.
Related
I started animation practice today.
I have a 3d box that I am rotating but no matter how big the viewing area is it flies way higher than it needs to and jumps off the page before coming down.
on your particular screen it may just not have enough room but no matter how small I make it , it still overflows the top of the screen.
Also, is it possible to just rotate in place with something like this as well?
Codepen
I don't think this code is gonna tell enough but stack overflow forced me to put something with the codepen.
.perspective {
transform-style: preserve-3d;
--px3d: 50px;
animation: boxanimation 5s linear 1s
infinite;
}
#keyframes boxanimation {
50% {
transform: rotateX(0deg)
rotateY(-360deg);
}
100% {
transform: rotateX(360deg)
rotateY(-360deg);
}
}
If you are looking to rotate your box in place, I would remove the positioning values on the .box elements and put them on the .perspective container, as that is what you are animating. Those positioning values are likely causing some unintended side effects.
Is this what you were looking for?
* {
box-sizing: border-box;
}
body {
background-color: rgb(73, 73, 73);
}
.box {
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 100%;
background-color: rgb(145, 145, 148);
box-shadow: black 1px 1px 7px, black 2px 2px 10px inset;
text-align: center;
text-shadow: black 3px 3px 5px;
font-size: 2rem;
padding-top: 1%;
}
.front {
transform: translate3d(0, 0, var(--px3d));
background-color: rgb(1, 220, 249);
}
.back {
transform: rotateY(180deg) translate3d(0, 0, var(--px3d));
background-color: rgb(232, 232, 232);
}
.top {
transform: rotateX(90deg) translate3d(0, 0, var(--px3d));
background-color: rgba(0, 128, 0);
}
.left {
transform: rotateY(-90deg) translate3d(0, 0, var(--px3d));
background-color: rgba(14, 122, 188);
}
.bottom {
transform: rotateX(-90deg) translate3d(0, 0, var(--px3d));
background-color: rgba(0, 0, 255);
}
.right {
transform: rotateY(90deg) translate3d(0, 0, var(--px3d));
background-color: pink;
}
.perspective {
position: relative;
width: 100px;
height: 100px;
transform-style: preserve-3d;
--px3d: 50px;
animation: boxanimation 5s linear 1s infinite;
transform-origin: center center;
}
#keyframes boxanimation {
50% {
transform: rotateX(0deg) rotateY(-360deg);
}
100% {
transform: rotateX(360deg) rotateY(-360deg);
}
}
<div class="perspective">
<div class="box bottom">Bottom</div>
<div class="box top">Top</div>
<div class="box left">Left</div>
<div class="box right">Right</div>
<div class="box back">Back</div>
<div class="box front">Front</div>
</div>
I've been struggling with this for a week or so, but don't feel close to fixing it. So I'm coming to Stack Overflow for the first time, hello!
I built a nifty little card amount selector that allows users to select a card in a visual way.
If you want to see it in action, please look at my CodePen!
It works fine in Chrome, but when I open it in Safari, the animation of the shadow and the z-index seems to take a moment to catch up.
I've tried adding the below to CSS, to no avail.
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
I'd appreciate anyone's help!
ReactJS
const { useState } = React;
function CardAmount(props) {
const cardAmounts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const [cardAmount, setCardAmount] = useState(1);
function cardClick(e) {
const amount = Number.parseInt(e.target.id) + 1;
if (amount !== cardAmount) {
setCardAmount(amount);
}
}
function cardvCards(num) {
if (num === 0) {
return <p>card</p>;
} else {
return <p>cards</p>;
}
}
function animateCard(cardNumber) {
if (cardNumber < cardAmount) {
return "FrontFacing";
} else {
return "BackFacing";
}
}
//makeCards
function makeCards() {
return cardAmounts.map((d, i) => {
return (
<div className={animateCard(i)} key={"card_" + i}>
<div className="cardFront" id={i} onMouseEnter={cardClick}>
<div className="borderbox">
<h1>{d}</h1>
{cardvCards(i)}
</div>
</div>
<div className="cardBack" id={i} onMouseEnter={cardClick}></div>
</div>
);
});
}
return (
<div className="CardChoice">
<div className="cardAmountDisplay">{makeCards()}</div>
</div>
);
}
ReactDOM.render(<CardAmount />, document.getElementById("app"));
CSS
#app {
background-color: rgb(85, 26, 122);
width: 100vw;
height: 100vh;
}
h1 {
text-align: center;
}
p {
text-align: center;
}
.CardChoice {
display: flex;
align-items: center;
justify-content: center;
height: 180px;
}
.cardAmountDisplay {
display: flex;
position: relative;
}
.FrontFacing,
.BackFacing {
position: absolute;
background-color: white;
border: 1px solid #d4af37;
border-radius: 10px;
margin: 5px;
height: 165px;
width: 115px;
transition: 750ms;
-webkit-transition: 750ms;
-moz-transition: 750ms;
-o-transition: 750ms;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
box-shadow: -8px 2px 8px rgba(0, 0, 0, 0.5);
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
}
.BackFacing {
transform: rotateY(-180deg);
-webkit-transform: rotateY(-180deg);
-moz-transform: rotateY(-180deg);
-o-transform: rotateY(-180deg);
}
.cardFront,
.cardBack {
position: absolute;
width: 100%;
height: 100%;
border-radius: 10px;
background-color: white;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
}
.cardFront {
display: flex;
justify-content: center;
align-items: center;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
}
.borderbox {
background-color: white;
width: 95%;
height: 95%;
border: 1px solid #d4af37;
border-radius: 10px;
margin-left: 1px;
pointer-events: none;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
}
.cardFront h1 {
font-size: 80px;
color: #d4af37;
text-shadow: 1px 0px rgb(0, 0, 0), -1px 0px rgb(0, 0, 0), 0px 1px rgb(0, 0, 0),
0px -1px rgb(0, 0, 0);
margin-top: 15px;
margin-bottom: 0px;
pointer-events: none;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
}
.cardFront p {
font-size: 16px;
font-weight: 600;
color: #d4af37;
text-transform: uppercase;
pointer-events: none;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
}
.cardBack {
transform: rotateY(-180deg);
-webkit-transform: rotateY(-180deg);
-moz-transform: rotateY(-180deg);
-o-transform: rotateY(-180deg);
}
.FrontFacing:nth-child(1) {
margin-left: -280px;
z-index: 1;
}
.FrontFacing:nth-child(2) {
margin-left: -240px;
z-index: 2;
}
.FrontFacing:nth-child(3) {
margin-left: -200px;
z-index: 3;
}
.FrontFacing:nth-child(4) {
margin-left: -160px;
z-index: 4;
}
.FrontFacing:nth-child(5) {
margin-left: -120px;
z-index: 5;
}
.FrontFacing:nth-child(6) {
margin-left: -80px;
z-index: 6;
}
.FrontFacing:nth-child(7) {
margin-left: -40px;
z-index: 7;
}
.FrontFacing:nth-child(8) {
margin-left: 0px;
z-index: 8;
}
.FrontFacing:nth-child(9) {
margin-left: 40px;
z-index: 9;
}
.FrontFacing:nth-child(10) {
margin-left: 80px;
z-index: 10;
}
.BackFacing:nth-child(2) {
margin-left: -140px;
z-index: 9;
}
.BackFacing:nth-child(3) {
margin-left: -100px;
z-index: 8;
}
.BackFacing:nth-child(4) {
margin-left: -60px;
z-index: 7;
}
.BackFacing:nth-child(5) {
margin-left: -20px;
z-index: 6;
}
.BackFacing:nth-child(6) {
margin-left: 20px;
z-index: 5;
}
.BackFacing:nth-child(7) {
margin-left: 60px;
z-index: 4;
}
.BackFacing:nth-child(8) {
margin-left: 100px;
z-index: 3;
}
.BackFacing:nth-child(9) {
margin-left: 140px;
z-index: 2;
}
.BackFacing:nth-child(10) {
margin-left: 180px;
z-index: 1;
}
I want to display a W with an effect of fade out when my W will be written entirely.
I do not know if I got tangled in my Keyframes
.anim {
transform: rotate(90deg);
}
#global {
width: 70px;
margin: auto;
zoom: 1.9;
margin-top: 100px;
position: relative;
cursor: pointer;
height: 60px;
}
.mask {
position: absolute;
border-radius: 2px;
overflow: hidden;
perspective: 1000;
backface-visibility: hidden;
}
.plane {
background: #2a6fed;
width: 400%;
height: 100%;
position: absolute;
transform: translate3d(0px, 0, 0);
/*transition: all 0.8s ease; */
z-index: 100;
perspective: 1000;
backface-visibility: hidden;
}
.animation {
transition: all 0.3s ease;
}
#top .plane {
z-index: 2000;
animation: trans3 3s ease-out infinite 0s backwards;
}
#middle .plane {
transform: translate3d(0px, 0, 0);
background: #2358be;
animation: trans2 3s ease-out infinite 1.5s backwards;
}
#middle-top .plane {
transform: translate3d(0px, 0, 0);
background: #2358be;
animation: trans25 3s ease-out infinite 2s backwards;
}
#bottom .plane {
z-index: 2000;
animation: trans1 3s ease-out infinite 2.6s backwards;
}
#top {
width: 53px;
height: 20px;
left: 40px;
transform: skew(15deg, 0);
z-index: 100;
top: -26px;
}
#middle-top {
width: 33px;
height: 20px;
left: 60px;
top: -10px;
transform: skew(15deg, -45deg);
}
#middle {
width: 33px;
height: 20px;
left: 60px;
top: 15px;
transform: skew(-15deg, 40deg);
}
#bottom {
width: 53px;
height: 20px;
left: 40px;
top: 30px;
transform: skew(-15deg, 0);
}
#loading-texte {
color: white;
position: absolute;
top: 70px;
font-family: Arial;
text-align: center;
font-size: 12px;
}
#keyframes trans1 {
from {
transform: translate3d(-250px, 0, 0);
}
to {
transform: translate3d(53px, 0, 0);
}
}
#keyframes trans2 {
from {
transform: translate3d(33px, 0, 0);
}
to {
transform: translate3d(-250px, 0, 0);
}
}
#keyframes trans25 {
from {
transform: translate3d(-250px, 0, 0);
}
to {
transform: translate3d(33px, 0, 0);
}
}
#keyframes trans3 {
from {
transform: translate3d(53px, 0, 0);
}
to {
transform: translate3d(-250px, 0, 0);
}
}
<section id="global">
<div class="anim">
<div id="top" class="mask">
<div class="plane"></div>
</div>
<div id="middle-top" class="mask">
<div class="plane"></div>
</div>
<div id="middle" class="mask">
<div class="plane"></div>
</div>
<div id="bottom" class="mask">
<div class="plane"></div>
</div>
</div>
<p id="loading-texte"><i>LOADING...</i></p>
</section>
#global {
width: 70px;
margin: auto;
margin-top: 100px;
position: relative;
cursor: pointer;
height: 60px;
}
.mask {
position: absolute;
border-radius: 2px;
overflow: hidden;
perspective: 1000;
backface-visibility: hidden;
}
.anim {
transform: rotate(90deg);
}
#top {
width: 53px;
height: 20px;
left: 40px;
transform: skew(15deg, 0);
z-index: 100;
top: -26px;
}
#middle-top {
width: 33px;
height: 20px;
left: 60px;
top: -10px;
transform: skew(15deg, -45deg);
}
#middle {
width: 33px;
height: 20px;
left: 60px;
top: 15px;
transform: skew(-15deg, 40deg);
}
#bottom {
width: 53px;
height: 20px;
left: 40px;
top: 30px;
transform: skew(-15deg, 0);
}
.plane {
background: #2a6fed;
width: 100%;
height: 100%;
position: absolute;
z-index: 100;
perspective: 1000;
backface-visibility: hidden;
animation-direction: alternate;
animation-duration: 4s;
animation-iteration-count: infinite;
}
#bottom .plane {
z-index: 2000;
animation-name: trans1;
}
#middle .plane {
transform: translate3d(0, 0, 0);
background: #2358be;
animation-name: trans2;
}
#middle-top .plane {
transform: translate3d(0, 0, 0);
background: #2358be;
animation-name: trans3;
}
#top .plane {
transform: translate3d(0, 0, 0);
z-index: 2000;
animation-name: trans4;
}
#keyframes trans1 {
0% {
transform: translate3d(-100%, 0, 0);
}
25% {
transform: translate3d(0%, 0, 0);
}
100% {
transform: translate3d(0%, 0, 0);
}
}
#keyframes trans2 {
0% {
transform: translate3d(100%, 0, 0);
}
25% {
transform: translate3d(100%, 0, 0);
}
50% {
transform: translate3d(0%, 0, 0);
}
100% {
transform: translate3d(0%, 0, 0);
}
}
#keyframes trans3 {
0% {
transform: translate3d(-100%, 0, 0);
}
50% {
transform: translate3d(-100%, 0, 0);
}
75% {
transform: translate3d(0%, 0, 0);
}
100% {
transform: translate3d(0%, 0, 0);
}
}
#keyframes trans4 {
0% {
transform: translate3d(100%, 0, 0);
}
75% {
transform: translate3d(100%, 0, 0);
}
100% {
transform: translate3d(0%, 0, 0);
}
}
#loading-texte {
color: white;
position: absolute;
top: 70px;
font-family: Arial;
text-align: center;
font-size: 12px;
}
<section id="global">
<div class="anim">
<div id="top" class="mask">
<div class="plane"></div>
</div>
<div id="middle-top" class="mask">
<div class="plane"></div>
</div>
<div id="middle" class="mask">
<div class="plane"></div>
</div>
<div id="bottom" class="mask">
<div class="plane"></div>
</div>
</div>
<p id="loading-texte"><i>LOADING...</i></p>
</section>
scale3d(sx, sy, sz)
I can't understand what scale3d() really do when I change (sz) Value
In this below code you can see the value of (sz) is = 1
body{perspective:600px}
div{
width: 300px;
height: 300px;
background-color: burlywood;
margin: auto;
border-radius:40px;
transition: all 5s ease-in-out;
transform: scale3d(1,1,1)
}
<div></div>
In this below code you can see the value of (sz) is = 0.5
but nothing changed the same result
body{perspective:600px}
div{
width: 300px;
height: 300px;
background-color: burlywood;
margin: auto;
border-radius:40px;
transition: all 5s ease-in-out;
transform: scale3d(1,1,0.5)
}
<div></div>
Note : I tried all solutions & values but nothing happened
The third number in scale3d is for the z-axis, which is only applicable to three-dimensional shapes.
Your examples have perspective, but they're still just use two-dimensional shapes, so nothing happens.
You can see the effect with a true cube:
scale3d(1,1,1)
#wrapper {
perspective: 1200px;
width: 200px;
height: 200px;
margin: 80px auto;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transform: rotateX(45deg) rotateY(0deg) rotateZ(45deg) scale3d(1, 1,1);
transition: transform 1s;
}
#cube>div {
width: 100%;
height: 100%;
position: absolute;
display: flex;
}
#cube>div span {
margin: auto;
font-size: 50px;
}
#left {
background-color: rgba(25, 25, 112, 0.7);
transform: rotateY(-90deg) translateZ(100px);
}
#right {
background-color: rgba(47, 79, 79, 0.7);
transform: rotateY(90deg) translateZ(100px);
}
#front {
background-color: rgba(119, 136, 153, 0.7);
transform: rotateY(0deg) translateZ(100px);
}
#back {
background-color: rgba(72, 61, 139, 0.7);
transform: rotateX(180deg) translateZ(100px);
}
#top {
background-color: rgba(0, 128, 128, 0.7);
transform: rotateX(90deg) translateZ(100px);
}
#bottom {
background-color: rgba(70, 130, 180, 0.7);
transform: rotateX(-90deg) translateZ(100px);
}
<div id="wrapper">
<div id="cube">
<div id="left"><span>left</span></div>
<div id="right"><span>right</span></div>
<div id="front"><span>front</span></div>
<div id="back"><span>back</span></div>
<div id="top"><span>top</span></div>
<div id="bottom"><span>bottom</span></div>
</div>
</div>
scale3d(1,1,0.5)
#wrapper {
perspective: 1200px;
width: 200px;
height: 200px;
margin: 50px auto;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transform: rotateX(45deg) rotateY(0deg) rotateZ(45deg) scale3d(1,1,0.5);
transition: transform 1s;
}
#cube > div {
width: 100%;
height: 100%;
position: absolute;
display: flex;
}
#cube > div span {
margin: auto;
font-size: 50px;
}
#left {
background-color: rgba(25,25,112,0.7);
transform: rotateY(-90deg) translateZ(100px);
}
#right {
background-color: rgba(47,79,79,0.7);
transform: rotateY(90deg) translateZ(100px);
}
#front {
background-color: rgba(119,136,153,0.7);
transform: rotateY(0deg) translateZ(100px);
}
#back {
background-color: rgba(72,61,139,0.7);
transform: rotateX(180deg) translateZ(100px);
}
#top {
background-color: rgba(0,128,128,0.7);
transform: rotateX(90deg) translateZ(100px);
}
#bottom {
background-color: rgba(70,130,180,0.7);
transform: rotateX(-90deg) translateZ(100px);
}
<div id="wrapper">
<div id="cube">
<div id="left"><span>left</span></div>
<div id="right"><span>right</span></div>
<div id="front"><span>front</span></div>
<div id="back"><span>back</span></div>
<div id="top"><span>top</span></div>
<div id="bottom"><span>bottom</span></div>
</div>
</div>
What is Scale3d?
(Sample at end, see link)
Your 1st code:
transform: scale3d(1,1,1)
Your 2nd code:
transform: scale3d(1,1,0.5)
This is:
scale3d ( <scaling-value-x> , <scaling-value-y> , <scaling-value-z> )
Your example is a 2d shape with no effect thats why. Z pane is used to make 3d objects.
Try Here and see how it works.
Specifically the perspective and transform properties are not working in css code provided below. Also, the radio buttons work but they do not link to the correct side of the cube. I can't spot the problem.
$size: 500px; // cube length
body {
text-align: center;
padding: 50px;
}
.scene {
display: inline-block;
margin-top: 50px;
width: 500px;
height: 500px;
-webkit-perspective: 600px;
}
.cube3d {
display: inline-block;
position: 500px;
width: 500px;
height: 500px;
-webkit-transform-style: preserve-3d;
-webkit-transition: transform 0.6s;
}
.cube-face {
width: 500px;
height: 500px;
position: absolute;
background: red;
opacity: 0.8;
}
// faces
.cube-face-front {
background: yellow;
transform: translate3d(0, 0, $size/2);
}
.cube-face-back {
background: black;
transform: rotateY(180deg) translate3d(0, 0, $size/2);
}
.cube-face-left {
background: green;
transform: rotateY(-90deg) translate3d(0, 0, $size/2);
}
.cube-face-right {
background: magenta;
transform: rotateY(90deg) translate3d(0, 0, $size/2);
}
.cube-face-top {
background: blue;
transform: rotateX(90deg) translate3d(0, 0, $size/2);
}
.cube-face-bottom {
background: red;
transform: rotateX(-90deg) translate3d(0, 0, $size/2);
}
// controls
#radio-back:checked ~ .scene .cube {
transform: rotateY(180deg);
}
#radio-left:checked ~ .scene .cube {
transform: rotateY(90deg);
}
#radio-right:checked ~ .scene .cube {
transform: rotateY(-90deg);
}
#radio-top:checked ~ .scene .cube {
transform: rotateX(-90deg);
}
#radio-bottom:checked ~ .scene .cube {
transform: rotateX(90deg);
}