weird animation with rotateX and rotateY in 2D transform - css

I don't understand why rotateX and rotateY animation in 2D transform will move so weird like demo
who can explain it, thanks
the demo code is
pug html
.ar
.ar2
css
body { background: black;}
#keyframes wing3{
0%{transform: rotateX(50deg)}
50%{transform: rotateX(70deg)}
100%{transform: rotateX(50deg)}
}
#keyframes wing4{
0%{transform: rotateY(50deg)}
50%{transform: rotateY(70deg)}
100%{transform: rotateY(50deg)}
}
.ar {
width: 40px; height: 5px; background: #fff;
animation: wing3 1.2s infinite;
}
.ar2 {
width: 40px; height: 5px; background: #fff;
animation: wing4 1.2s infinite;
}

It's not werid but logical. You are rotating on the X/Y axis so from our perspective your don't see any rotation but only a size changing.
Here is a classic rotation done the on Z axis:
.b {
width:100px;
height:10px;
background:red;
margin:50px;
animation:change 5s infinite linear;
}
#keyframes change{
to {
transform:rotate(90deg);
}
}
<div class="b">
</div>
Our element is rotating at the center going from 0 to 90deg. Now imagine your are looking to this rotation from the bottom. You will simply see a reduced width.
Here is the different frames:
.b {
width:100px;
height:10px;
display:inline-block;
background:red;
margin:50px 10px;;
}
body {
margin:0;
font-size:0;
}
<div class="b">
</div>
<div class="b" style="transform:rotate(40deg)">
</div>
<div class="b" style="transform:rotate(60deg)">
</div>
<div class="b" style="transform:rotate(80deg)">
</div>
<div class="b" style="transform:rotate(90deg)">
</div>
Now let's look at this from the bottom:
.b {
width:100px;
height:10px;
display:inline-block;
background:red;
margin:50px 5px;
}
.a {
width:100px;
height:10px;
display:inline-block;
background:blue;
margin:50px 10px;
}
body {
margin:0;
font-size:0;
}
<div class="b">
</div>
<div class="b" style="transform:rotate(40deg)">
</div>
<div class="b" style="transform:rotate(60deg)">
</div>
<div class="b" style="transform:rotate(80deg)">
</div>
<div class="b" style="transform:rotate(90deg)">
</div>
<br>
<div class="a">
</div>
<div class="a" style="transform:rotateY(40deg)">
</div>
<div class="a" style="transform:rotateY(60deg)">
</div>
<div class="a" style="transform:rotateY(80deg)">
</div>
<div class="a" style="transform:rotateY(90deg)">
</div>
So the blue part is our perception of the Z rotation if we look at it from another direction which is equivalent to an Y rotation. And you also have the same effect using a scale transformation since this one will do the same thing from our perception:
.b {
width:100px;
height:10px;
display:inline-block;
background:red;
margin:50px 5px;
animation:rotate 4s infinite linear;
}
.a {
width:100px;
height:10px;
display:inline-block;
background:blue;
margin:50px 10px;
animation:scale 5s infinite linear;
}
#keyframes rotate{
to {
transform:rotateY(90deg);
}
}
#keyframes scale{
to {
transform:scaleX(0);
}
}
body {
margin:0;
font-size:0;
}
<div class="b">
</div>
<br>
<div class="a">
</div>
In order to see this differently, you can add some perspective and you will make the rotation more close to what we see in a real world:
.b {
width:100px;
height:10px;
display:inline-block;
background:red;
margin:50px 5px;
animation:rotate-1 4s infinite linear;
}
.a {
width:100px;
height:10px;
display:inline-block;
background:blue;
margin:50px 10px;
animation:rotate-2 5s infinite linear;
}
#keyframes rotate-1{
to {
transform:perspective(45px) rotateY(180deg);
}
}
#keyframes rotate-2{
to {
transform:perspective(45px) rotateX(180deg);
}
}
body {
margin:0;
font-size:0;
}
<div class="b">
</div>
<br>
<div class="a">
</div>

Related

How can I make my looping background work without it glitching?

I've looked at other similar questions, but I can't find a solution.
I have an assignment where I need to make a mini game. I want to make a looping background with CSS, using an image with 1600px width and 500px height. My screen (div) has 800px width and 500px height. I tried so many things, but it keeps 'glitching'. So instead of being smooth, it jumps back.
This is the HTML:
<section class="center">
<div class="background disco"></div>
<div class="player"><img src="images/player-03.png"></div>
<div class="bier"><img src="images/bier.png"></div>
<div class="water"><img src="images/water.png"></div>
<p class="biertjes"></p>
<p class="watertjes"></p>
<p class="promille"></p>
<p class="gameover">Watje! Water maakt je nuchter!</p>
<p class="gameoverscore"></p>
<p class="winscreen">Proficiat! Door alle alcohol heb je een blackout!</p>
<p class="winscore"></p>
<div class="startscreen">
<h1>Welkom! Zo moet je spelen:</h1>
<p>↑ = stijgen<br>
↓ = dalen<br>
← = vertragen<br>
→ = versnellen</p>
<p class="start">SPEEL!!</p>
<div class="el"></div>
<div class="dance"></div>
<div class="dance2"></div>
</div>
</section>
This is my CSS:
.center {
width:800px;
height:500px;
position:absolute;
z-index: 0;
left:50%;
top:50%;
margin:-250px 0 0 -400px;
text-align:center;
border: 3px solid #ff23be;
overflow: hidden;
background: black;
}
.background {
width:800px;
height:500px;
position:absolute;
background-repeat: no-repeat;
}
.disco {
width: 2400px;
height: 500px;
z-index: 0;
background-image: url(/images/loop.jpg);
background-size: contain;
top: 0px;
animation-name: disco;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#keyframes disco {
from {transform: translateX(0px); }
to {transform: translateX(-1200px);}
}
Can anyone help? I really can't find anything!

Keep a div from moving when resized

I am trying to position a div in a corner of my screen so that I can resize it to cover the screen.
Problem is, when I resize it the div moves as you can see in the snippet below. I tried to apply the effect on an pseudo-element but it did not help. Any idea how I can resize an item without it moving ?
Thank you for your help.
$('button').click(function(){
$(this).closest('div').find('.cover').toggleClass('active');
console.log("test");
})
.main{
display:flex;
justify-content:space-around;
}
.item {
width:350px;
height:350px;
background-color:teal;
position:relative;
overflow:hidden;
}
.item .cover {
transition:all .5s linear;
width:20px;
height:20px;
background-color:orange;
position:absolute;
inset:-10px -10px auto auto;
border-radius:50%;
}
.item.no-pseudo .cover.active {
width:200%;
height:200%;
}
}
button{
margin-top:1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.6.2/sass.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<div class="container">
<div class="item no-pseudo">
<div class="cover"></div>
</div>
<button class="no-pseudo">Click to toggle effect on element</button>
</div>
</div>
You can use transform:scale(x) instead, by default, transform-origin is done from the center of the element.
$('button').click(function(){
$(this).closest('div').find('.cover').toggleClass('active');
console.log("test");
})
.main{
display:flex;
justify-content:space-around;
}
.item {
width:350px;
height:350px;
background-color:teal;
position:relative;
overflow:hidden;
}
.item .cover {
transition:all .5s linear;
width:20px;
height:20px;
background-color:orange;
position:absolute;
inset:-10px -10px auto auto;
border-radius:50%;
}
.item.no-pseudo .cover.active {
transform:scale(50);
}
}
button{
margin-top:1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.6.2/sass.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<div class="container">
<div class="item no-pseudo">
<div class="cover"></div>
</div>
<button class="no-pseudo">Click to toggle effect on element</button>
</div>
</div>
Use scale instead of width and height.
$('button').click(function(){
$(this).closest('div').find('.cover').toggleClass('active');
console.log("test");
})
.main{
display:flex;
justify-content:space-around;
}
.item {
width:350px;
height:350px;
background-color:teal;
position:relative;
overflow:hidden;
}
.item .cover {
transition:all .5s linear;
width:20px;
height:20px;
background-color:orange;
position:absolute;
border-radius:50%;
}
.item.no-pseudo .cover.active {
transform:scale(20);
}
}
button{
margin-top:1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.6.2/sass.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<div class="container">
<div class="item no-pseudo">
<div class="cover"></div>
</div>
<button class="no-pseudo">Click to toggle effect on element</button>
</div>
</div>

CSS Background Animation only in block

I have The following animated background, currently displayed on the entire screen, I need you to only visualize in a block (<div class="c"> </ div>)
body {
margin:0;
}
.bg {
animation:slide 3s ease-in-out infinite alternate;
background-image: linear-gradient(-60deg, #6c3 50%, #09f 50%);
bottom:0;
left:-50%;
opacity:.5;
position:fixed;
right:-50%;
top:0;
z-index:-1;
}
.bg2 {
animation-direction:alternate-reverse;
animation-duration:4s;
}
.bg3 {
animation-duration:5s;
}
#keyframes slide {
0% {
transform:translateX(-25%);
}
100% {
transform:translateX(25%);
}
}
.c {margin:0 auto;}
<div class="c">
<div class="bg"></div>
<div class="bg bg2"></div>
<div class="bg bg3"></div>
<div class="content">
<h1>Only here animation</h1>
</div>
</div> <!-- /end animation -->
<div class="footer">Here without animation</div>
I always see on the whole screen, some suggestion to be able to see the animation only in a block (div)
Add the following css:
.c { height: 80px; }
.bg { height: 80px; }
Note: Change the sizes according to your taste.(height)
example:
body {
margin:0;
}
.c {
height: 80px;
}
.bg {
animation:slide 3s ease-in-out infinite alternate;
background-image: linear-gradient(-60deg, #6c3 50%, #09f 50%);
bottom:0;
left:-50%;
opacity:.5;
position:fixed;
right:-50%;
top:0;
z-index:-1;
height: 80px;
}
.bg2 {
animation-direction:alternate-reverse;
animation-duration:4s;
}
.bg3 {
animation-duration:5s;
}
#keyframes slide {
0% {
transform:translateX(-25%);
}
100% {
transform:translateX(25%);
}
}
<div class="c">
<div class="bg"></div>
<div class="bg bg2"></div>
<div class="bg bg3"></div>
<div class="content">
<h1>Only here animation</h1>
</div>
</div> <!-- /end animation -->
<div class="footer">Here without animation</div>
Change '.bg' position to relative. Add a "container" div as the parent. The "container" should have the relative position. The footer is going to have the "absolute" position.
Take a look
body {
margin:0;
height: 100%;
position: relative;
}
.footer{
position:relative;
bottom:0;
height:50px;
background-color: #f7f7f7;
width: 100%;
}
.bg {
animation:slide 3s ease-in-out infinite alternate;
background-image: linear-gradient(-60deg, #6c3 50%, #09f 50%);
bottom:0;
left:-50%;
opacity:.5;
position:absolute;
right:-50%;
top:0;
z-index:-1;
}
.bg2 {
animation-direction:alternate-reverse;
animation-duration:4s;
}
.bg3 {
animation-duration:5s;
}
#keyframes slide {
0% {
transform:translateX(-25%);
}
100% {
transform:translateX(25%);
}
}
.c {margin:0 auto;}
<div class="container">
<div class="c">
<div class="bg"></div>
<div class="bg bg2"></div>
<div class="bg bg3"></div>
<div class="content">
<h1>Only here animation</h1>
</div>
</div> <!-- /end animation -->
<div class="footer">Here without animation</div>
</div>

CSS - stopping animation with :hover (no JS)

Is there any way of stopping animation with :hover and make it run again once hovered off?
This part is solved:
I thought of doing it with animation-state-paused, but as the animation runs on multiple elements with precised animation-delay, such solution desynchronizes elements.
What I would like to achieve 'at least' is to stop all of the animation once hovered.
Still looking for solution for this part:
And the Great Achievement would be (additionaly) to change z-index so the hovered picture goes in front of all the other ones... and come backs to its z-index from animation once hovered off + animation continues the cycle.
Important thing - NO JAVASCRIPT (I'd really like to use it, but I cannot because of some CMS settings).
Code without hover: CODEPEN and SOSnippet:
.cube2>div{
position:absolute;
left:50%;
transform: translateX(-50%);
width:450px;
}
.playground2 {
overflow: hidden;
}
.frame {
position: absolute;
top:-12px;
left:-1px;
z-index: 1;}
.one, .two, .three, .four, .five, .six, .seven, .eight{
animation: comedown 32s infinite ease-in-out
}
.eight {
animation-delay: 0s
}
.seven {
animation-delay: 4s
}
.six {
animation-delay: 8s
}
.five {
animation-delay: 12s
}
.four {
animation-delay: 16s
}
.three {
animation-delay: 20s
}
.two {
animation-delay: 24s
}
.one {
animation-delay: 28s;
}
.container {
background: darkkhaki;
height: 400px;
position: relative;
}
.cube2 {
top: 100px;
height: 300px;
position: relative;
left: 50%;
transform: translateX(-50%);
}
#-webkit-keyframes comedown {
0% {
top: 0%;
z-index: 1;
}
12.5% {
top: 120%;
z-index: 2;
left:50%;
transform:translateX(-50%);
}
13%{z-index:-15}
25%{
top:-50px;
transform: translateX(-32%)
}
35%{z-index:-10}
37.5%{
top:-42px;
transform: translateX(-35%);
}
50%{
top:-36px;
transform: translateX(-38%);
z-index:-6;
}
62.5%{
top:-28px;
transform: translateX(-41%);
z-index:-5;
}
75%{
top:-20px;
transform: translateX(-44%);
z-index:-4;
}
87.5%{
top:-12px;
transform: translateX(-47%);
z-index:-3;
}
100%{
top:0px;
left:50%;
transform:translateX(-50%);
z-index:-2;
}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="playground2 container">
<div class="cube2">
<div class="one">
<img class="face" src="https://s17.postimg.org/71iegzebj/img_little.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="two">
<img class="face" src="https://s17.postimg.org/duncqzuin/img_little3.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="three">
<img class="face" src="https://s17.postimg.org/o3b8j2t6n/img_little2.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="four">
<img class="face" src="https://s17.postimg.org/v97kz9rnj/img_little4.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="five">
<img class="face" src="https://s16.postimg.org/4reke4owl/image.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="six">
<img class="face" src="https://s16.postimg.org/3qebp07x1/image.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="seven">
<img class="face" src="https://s16.postimg.org/fgs96e0ph/image.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
<div class="eight">
<img class="face" src="https://s16.postimg.org/xxmnx7gnp/image.png">
<img class="frame" src="https://s16.postimg.org/5e6yfj8d1/frame.png">
</div>
</div>
</div>
The trick is to catch :hover on .cube2.
This will pause the animation:
.cube2:hover > div{
-webkit-animation-play-state: paused; /* Safari 4.0 - 8.0 */
animation-play-state: paused;
}
To bring image box to front using z-index, use this:
.cube2 > div:hover{
z-index: 99 !important;
}
.cube2:hover > div.one, .cube2:hover >.two, .cube2:hover >.three, .cube2:hover >.four, .cube2:hover >.five,.cube2:hover > .six, .cube2:hover >.seven, .cube2:hover >.eight{
animation-play-state: paused;
}
This way all animation is stopped since you call hover on .cube2
See:
https://jsfiddle.net/duuhr712/

Color overlay on image hover css

I'm trying to overlay a white circle on top of an image once it is hovered over, however this is trickier than I thought using just CSS. The solution doesn't need to be a strictly CSS one, it's just that I wouldn't like to use images.
HTML/ERB
<div class="item-container">
<div class="rollover-item">
<%= link_to image_tag(#featured_product_first.product.images.order(:placement).first.image.url(:medium)), #featured_product_first.product %>
</div>
<%= link_to #featured_product_first.product.name, #featured_product_first.product %>
<% end %>
</div>
CSS
.item-container {
width: 100%;
height: 100%;
}
.rollover-item {
position: relative;
z-index: 1;
}
.rollover-info img:hover:after {
content: ' ';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(255,255,255,.5);
border-radius: 50%;
z-index: 10;
}
Assuming this structure
JSFiddle Demo
HTML
<div class="item-container">
<div class="rollover-item">
<img class="product-img" src="http://lorempixel.com/output/technics-q-c-200-200-7.jpg" alt=""/>
<a class="description" href="#">Product Description</a>
</div>
</div>
Then this general CSS should work. Using overflow hidden, absolute positioning and transitioning.
.item.container {
display:inline-block;
}
.rollover-item {
position:relative;
overflow:hidden;
width:200px;
}
.description{
position:absolute;
top:100%;
left:0;
display:block;
width:200px; /* as image */
height:200px; /* as image */
line-height:200px; /* as image */
text-align:center;
text-decoration:none;
color:black;
font-weight:bold;
background:rgba(255,255,255,0.5);
border-radius:50%;
transition:top 0.5s ease;
}
.rollover-item:hover .description {
top:0;
}
look at this example:
html:
<div class="item_cont">
<img src="img_src.jpg" />
<div class="circ"></div>
</div>
css:
.item_cont{width:100px;height:100px;}
.item_cont img{width:100px;height:100px;}
.item_cont .circ{display:none;background:#fff;width:80px;height:80px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;}
.item_cont:hover .circ{display:block;}
no js needed.
hope that helps.
use this code:
jsFiddle is here
HTML:
<div class="item-container">
<div class="rollover-item">
</div>
</div>
CSS:
.item-container{
position:relative;
width:200px;
height:200px;
background:tomato; /* I love this color */
}
.rollover-item{
position:aboslute;
width:0%;
height:0%;
margin:0 auto;
background:#fff;
border-radius:50%;
opacity:0;
transition:all 0.5s ease;
}
.item-container:hover .rollover-item{
width:100%;
height:100%;
opacity:1;
}

Resources