Apply scale on ongoing CSS animated bitmap? - css

I have a bitmap with an applied animation style that spins it ad nausaum. I would like it to move to the left and resize about 50% when an event is triggered (hover in this case). I've been able to apply smoothly the movement towards the left, but i get no response with the transform: scale command. See jsfiddle here.
.wheel:hover {
margin-left: -228px;
transform: scale(0.5);
}
What I'm doing wrong?

it doesn't work because you have transform:rotate() on the image from the animation. and adding another transform on the same image, in the same time the animation is working, it's not possible
instead of transform:scale(0.5) you can use height:50%;width:auto . see snippet below or fiddle > jsFiddle
let me know if it helps
#keyframes spin {
from {transform:rotate(0deg);}
to {transform:rotate(360deg);}
}
.wheel {
position: fixed;
top: 30px;
left: 140px;
animation: spin 15s infinite linear;
transition: all 0.5s linear;
}
.wheel:hover {
margin-left: -228px;
width:auto;
height:50%;
}
<body>
<img src="https://pbs.twimg.com/profile_images/616542814319415296/McCTpH_E.jpg" class="wheel">
</body>

Related

I need to have two animations in css, one at start and one at hover, but it isn't working

I have a div element, which has an animation to play when starting the page. I want to make it have another animation to play when I'm hovering over it. It works just fine, but when I get my mouse out of the div element, it plays the starting animation again (fades in from out of the screen).
#keyframes div{
0%{
opacity: 0;
}
}
#keyframes divHover{
50%{
top: 200px;
}
100%{
top: 0px;
}
}
#div{
opacity: 1;
animation: div 1s;
position: absolute;
left: 0px;
top: 0px;
}
#div:hover{
animation: divHover 1s linear 0s infinite;
}
<div id="div"> abc </div>
Expected:
Div starts invisible and fades in. When hovering div, it goes up and down, and keeps doing it while hovering. After stopping the hover, div stops the animation and keeps its full opacity
Actual:
After stopping the hover, div stops the animation but returns to 0 opacity, then takes one second to display the starting animation again.
https://jsfiddle.net/odq125Lu/6/
The issue is due to the fact that you are overriding the first opacity animation with the up & down one then when you unhover you active the first one again.
You can use multiple animations and consider animation-play-state to activate the second one:
#keyframes div {
0% {
opacity: 0;
}
}
#keyframes divHover {
50% {
top: 200px;
}
100% {
top: 0px;
}
}
#div {
opacity: 1;
animation:
div 1s,
divHover 1s linear 0s infinite;
animation-play-state:running,paused;
position: absolute;
left: 0px;
top: 0px;
background:red;
padding:20px;
}
#div:hover {
animation-play-state:running,running;
}
<div id="div"> abc </div>
I'm no expert, but it may have something to do with the fact that you haven't set a 100% value for the animation "divHover"?
#keyframes div{
0%{
opacity: 0;
}
100% {
opacity: 1;
}
}

Why is CSS position attribute affecting a rotation animation?

I'm working on a website (that I didn't design, someone else gave me the HTML/CSS) as a developer and We've got a nice spinner animation for async loading components. It's forever-spinning animation is defined by this CSS rule:
animation: spinning 1s infinite linear; (it has also vendor prefix versions but it's irrelevant).
The spinning animation is defined as:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
Our designer has put a position: absolute !important attribute to the spinning element. I was trying to position it inside some other element and I've thought that attribute was irrelevant. As soon as I removed position: absolute, the spinner stopped spinning. When I added it again, spinner started spinning again.
I've tried other position values too, it seems that absolute and fixed are working okay (in regards to spinning animation) while relative and static cause the animation to stop.
Why would CSS position attribute affect a spinner animation?
Here is a snippet reproducing the problem:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
#first{
position: absolute;
}
#second{
position: relative; /* or don't specify it at all */
}
<div style='background:yellow;width:400px;height:100px;'>
<span id='first' style='animation:spinning 1s infinite linear'>hello</span>
</div>
<div style='background:lime;width:400px;height:100px;'>
<span id='second' style='animation:spinning 1s infinite linear'>hello</span>
</div>
It's because a span is an inline-element by default and so is not affected by transforms.
Setting the position to absolute imparts a block formatting to the span.
Just add display:inline-block:
#keyframes spinning {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
div.one {
background: yellow;
width: 400px;
height: 100px;
}
div.two {
background: lime;
width: 400px;
height: 100px;
}
#first {
position: absolute;
animation: spinning 1s infinite linear
}
#second {
position: relative;
/* or don't specify it at all */
animation: spinning 1s infinite linear;
display: inline-block;
}
<div class="one">
<span id='first'>hello</span>
</div>
<div class="two">
<span id='second'>hello</span>
</div>

Animating scale using CSS - with multiple backgrounds

I've been trying for days to emulate a video editing effect using CSS3 with no luck. I have two background images (one on top of the other) and want to create an animation where I scale up or zoom the image on top while leaving the background image intact.
I have been able to successfully change the position of the top image while leaving the background intact, and I can also do an animation which scales both foreground and background images at the same time.
Here's some code to make this all a bit more clear:
My HTML:
<section id="about-photo" class = "light-bg img-bg" style = "background-image: url({% static "assets/images/art/cocuy-foreground.png" %}), url({% static "assets/images/art/cocuy-background.jpg" %});">
<div class="container inner">
<div class="row">
</div><!-- /.row -->
</div><!-- /.container -->
</section>
My CSS (only including webkit for sake of brevity)
#-webkit-keyframes hide {
from { background-position: 0px 0px, 0px 0px; }
to { background-position: 0px 300px, 0px 0px; }
}
#-webkit-keyframes zoom {
from {-webkit-transform: scale(1,1), scale(1,1) ;}
to {-webkit-transform: scale(2,2), scale(1,1) ;}
}
#about-photo {
background-repeat: no-repeat;
-webkit-animation-name: zoom;
-webkit-animation-duration: 4s;
-webkit-animation-delay: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
}
When I apply the animation called "hide" things work fine, but when I use "zoom" nothing happens.
Any ideas/tips would be greatly appreciated!
Dennis
Not sure if you actually need to use keyframes for this. You can simply use transition and transform to achieve this. I made a jsFiddle showing how you can do that. Also be aware that you want to include other vendor prefixes so your code works in all browsers.
#about-photo {
position: relative;
}
.light-bg {
width: 1000px;
height: 1000px;
background: url('http://www.broomehovercraft.com.au/graphics/bht/popups/gallery-sunset-6.jpg');
background-repeat: no-repeat;
}
.smiley {
position: absolute;
top: 10%;
left: 20%;
width: 100px;
height: 100px;
z-index: 2;
background: url('http://www.wpclipart.com/smiley/assorted_smiley/assorted_3/smiley_a_bit_angry_T.png');
background-size: 100px 100px;
-webkit-transition: 1s ease-in-out;
-moz-transition: 1s ease-in-out;
-o-transition: 1s ease-in-out;
transition: 1s ease-in-out;
}
.smiley:hover {
-webkit-transform: scale(2);
-moz-transform: scale(2);
-o-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
}
<section id="about-photo" class="light-bg img-bg">
<div class="smiley"></div>
<!-- /.container -->
</section>
http://jsfiddle.net/augburto/44sbrooy/
The main thing to note is that on the element you wish to have a "zoom effect", you want to apply a transition so it knows that when a transform is applied to it, it will do it smoothly (if you don't have this, then it will do the action immediately.
Right now I have it so when you hover over the smiley, it will scale with a transform. However, you can easily change this to a class that you can apply. As long as your element has a transition, it will create that nice "zoom-in" effect. Then the actual scaling of the image can be applied to a separate class which you can apply whenever.
For more documentation on transitions, check out MDN.
If you really want to use keyframes, then update your question, but in my eyes it isn't necessary in this situation.

CSS animation: Difference between left:100% and translate(100%)

I have read about how using translate has better performance, but it seems they behave slightly differently: using left:100% moves the animated object all the way to the end of the screen, whereas translate(100%) only moves the animated object as far as its length. That is, it moves 100% of the screen versus 100% of the object.
Can explain why this is, and what can be done to reproduce the same behavior when using translate?
You can see a demo here: http://jsfiddle.net/32VJV/1/
.slide_1 {
top: 0px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_1 {
-webkit-animation: slide 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
.slide_2 {
top: 25px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_2 {
-webkit-animation: slide2 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
#-webkit-keyframes slide {
0% {
-webkit-transform: translate(0%);
}
50% {
-webkit-transform: translate(100%);
}
100% {
-webkit-transform: translate(0%);
}
}
#-webkit-keyframes slide2 {
0% {
left 0%;
}
50% {
left:100%;
}
100% {
left:0%;
}
}
<div style="font-size:18px;">
<div class=""> <span class="slide_1" id="dimensions">ABC</span> <span class="slide_2" id="dimensions">ABC</span>
</div>
</div>
The difference between the two is that animating a property like left will keep the element in the flow of the document whereas translate does not.
For more information on why you might use one or the other, Paul Irish has an excellent write up (with links to more information): Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
There's also a lot of great information on browser performance at jankfree.org
Solution for the translate animation: make the element as wide as the window:
Example
slide_1 {
top: 0px;
left:0%;
right: 0;
position: absolute;
overflow: hidden;
font-size: 30px;
}
An interesting exercise: Open your devtools and what what happens when you activate one animation at a time.
In Chrome:
The translate animation has basically nothing going on except a periodic GC
The Left animation you will see repeatedly:
Recalculate Style
Layout
Pain Setup
Paint
Composite Layers
In this case, the overhead it pretty small, but that can change quickly depending on what is being moved around the screen.

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;
}

Resources