Ocillate function between two values javascript - javascript

I need to have a growing and decreasing circle in made in javascript.
My idea is to use a div with
border-radius : 50%
To get a circle. I need to make it scale from 0.2 to 1 every [x] seconds .
Like It grows from 0.2 to 1 in 5 seconds, then it decreases from 1 to 0.2 in5 seconds too. THen the movement starts again.
I think i have to use sin or cos functions but i don't know how to get this interval depending on time.
I need it to be coupled with a javascript timing function, so that when i satr a timer, the animation begins, and when I pause it it pauses the animation.
Thanks for advice !

One more example of CSS animation which probably better option then javascript:
.circle {
background: coral;
height: 100px;
width: 100px;
border-radius: 50%;
-webkit-animation: pulse 1s ease infinite alternate;
animation: pulse 1s ease infinite alternate;
}
#-webkit-keyframes pulse {
from {
-webkit-transform: scale(1);
}
to {
-webkit-transform: scale(.2);
}
}
<div class="circle"></div>
For Firefox you will need to add prefixless rule
#keyframes pulse {
from { transform: scale(1); }
to { transform: scale(.2); }
}

You could do this with CSS3 animations. Look at this example and change it until it does exactly how you want it.
#circle {
-webkit-animation: oscillate 10s infinite;
animation: oscillate 10s infinite;
border: 1px solid black;
height: 100px;
width: 100px;
}
#-webkit-keyframes oscillate {
0% { border-radius: 20%; }
50% { border-radius: 100%; }
100% { border-radius: 20%; }
}
#keyframes oscillate {
0% { border-radius: 20%; }
50% { border-radius: 100%; }
100% { border-radius: 20%; }
}
<div id="circle">Hi</div>

Use a CSS3 animation set on infinite. Check this fiddle.
#-webkit-keyframes mymove {
0%, 100% { -webkit-transform: scale(1); }
50% { -webkit-transform: scale(0.2); }
}
#keyframes mymove {
0%, 100% { transform: scale(1); }
50% { transform: scale(0.2); }
}
div {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: mymove 5s infinite; /* Chrome, Safari, Opera */
animation: mymove 5s infinite;
border-radius:60px;
}

Related

how make another transform animation after fade-in and existing transform?

hello I have a text which has fade-in and transform(translate) animation so after the fade-in and transform animation I want a moving text like up and down a lite, not too much in an infinite loop like you are waiting for loading of something
.imgContaner {
width: 100%;
height: 86.6vh;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/8/85/Sky-3.jpg");
background-size: cover;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
}
.imgContaner p {
color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 3em;
text-align: center;
text-shadow: -1px 0 #000000, 1px 0 #000000, 0 1px #000000, 0 -1px #000000;
animation: 4s ease-in-out test ;
opacity: 1;
}
#keyframes test {
from {
transform: translate(-50% , 400%);
opacity: 0;
}
to {
transform: translate(-50%, -50%);
opacity: 1;
}
}
<div className={classes.imgContaner}>
<p>Make Your Dreams Come True</p>
</div>
You can do this in two ways with css.
First way: Add more frames in your #keyframes definition. Instead of using from and to properties, use percentages. For example:
#keyframes test {
0% {
transform: translate(-50% , 400%);
opacity: 0;
}
50% {
transform: translate(-50%, -50%);
opacity: 1;
}
75% {
Do other stuff...
}
100% {
Do other stuff...
}
}
Second way: Chain animations to play after the other one. By adding delay to the second animation equal to the duration of first animation. Like:
animation: test 4s ease-in-out, otherAnim 2s ease-in-out 4s;
Note that you can't do it this way:
animation: test 4s ease-in-out;
animation: otherAnim 2s ease-in-out 4s;
This way first one will be overwriten by second one. Which is not what you want.

Getting Top/Right values ​from a css-animated element

I'm trying to get the Top and Right values from an element being rotated by a CSS animation, for this I am using the following code:
HTML:
<div id="ball1"> </div>
CSS:
#keyframes spin {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
#ball1 {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10;
height: 10;
border-radius: 10px;
}
Javascript:
console.log(window.getComputedStyle(document.getElementById("ball1"), null).top);
console.log(window.getComputedStyle(document.getElementById("ball1"), null).right);
However it returns a value of 0px, I wanted to get the value from Right and Top as if I was manually setting them (and not by the transform animation).
If this is not possible, is there a way to simulate a "circle" rotation and return the right/top values without using the transform?
ie:
https://66.media.tumblr.com/fb22b61bcbca3785a515e86c2276451b/tumblr_inline_pmimnjEvbK1v6q8wn_1280.gif?fbclid=IwAR2zjgE0hfB8emWOg0f6TOcQb8DWGbEvu9IQOr92fMq4HmMKjiAQRQzLmI0
Use getBoundingClientRect():
const ball = document.getElementById("ball");
setInterval(() => {
const rect = ball.getBoundingClientRect();
console.log(rect.top, rect.right);
}, 300);
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#ball {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
<div id="ball"></div>
Here is an approximation using top/left. The trick is to animate each property individually alternating the ease function to simulate the circular path:
.box {
width:100px;
height:100px;
position:relative;
}
#ball1 {
animation:
Atop 2.5s infinite,
Aleft 2.5s infinite;
position: absolute;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
#keyframes Atop {
0%,50%,100% {
top:50%;
animation-timing-function: ease-out;
}
25% {
top:0%;
animation-timing-function: ease-in;
}
75% {
top:100%;
animation-timing-function: ease-in;
}
}
#keyframes Aleft {
0%,100% {
left:0;
animation-timing-function: ease-in;
}
25%,75% {
left:50%;
animation-timing-function: ease-out;
}
50% {
left:100%;
animation-timing-function: ease-in;
}
}
<div class="box">
<div id="ball1"> </div>
</div>

How to apply a hover effect on an element which has already been handled by an forward animation?

I have a text and block in an animation of an SVG element.
Here in my example i simplified everything.
I want to have one initial animation and afterwards a hover animation on the block element. The initial animation is fine as it is. (use chrome to have equals measurements). But after the initial animation the user should be able to hover the block and the block itself should resize (which is also working already) and the text should get an opacity of 1. But this won't work since the opacity is already set by the keyframe animation.
Any suggestions on how to work around on this one?
I don't mind if i use JS or CSS or any frameworks. I don't rely on CSS animations. Just used them because i thought i'd be cleaner.
Important Edit: I forgot a simple but very important thing. Before the animation there are some other animations on different elements. So i have a delay of let's say 2 seconds. Before the animation starts, the opacity should be 0 so the text is not visible until the animation starts. Sorry, forgot about that!
.text{
font-weight: bold;
opacity: 0;
transition: all .8s;
animation: showText 3s ease-in-out forwards;
animation-delay: 2s;
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
animation-delay: 2s;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text'>
Foo Bar!
</div>
<div class='block'>
</div>
codepen.io link (same code as above): https://codepen.io/jdickel/pen/xJbQrY
Instead of a forwards animation, you can simply set the initial opacity to 0.3.
EDIT:
I'm fairly confident that forwards animation styles can't be easily overridden (though I'm unable to find it in documentation for some reason), so you could do similarly to what was originally suggested and just extend the time of the animation like so:
.text{
font-weight: bold;
/* Start out at 0.3 */
opacity: 0.3;
transition: all .8s;
/* 2s + 3s = 5s */
animation: showText 5s ease-in-out; /* no forwards */
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
/* Note the new animation keyframe locations */
70% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text'>
Foo Bar!
</div>
<div class='block'>
</div>
First, you need to remove forwards from the .text animation. You can use Javascript's mouseenter and mouseleave events to set the text's opacity when .block is hovered over.
.text{
font-weight: bold;
opacity: 0;
transition: all .8s;
animation: showText 3s ease-in-out;
animation-delay: 2s;
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
animation-delay: 2s;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text' id="text" onmouseenter="function1()" onmouseleave="function2()">
Foo Bar!
</div>
<div class='block' onmouseenter="function1()" onmouseleave="function2()">
</div>
<script>
setTimeout(function(){
document.getElementById("text").style.opacity = "0.3";
}, 3000)
function function1(){
document.getElementById("text").style.opacity = "1";
}
function function2(){
document.getElementById("text").style.opacity = "0.3";
}
</script>

I want to create a loader with still image in between the loader circle [duplicate]

This question already has answers here:
How to add a icon inside a spinner
(3 answers)
Closed 5 years ago.
I want to create a loader with still image in between the loader
circle. in this code the image is rotating along with loader i want
the image to be still not rotating.
<!DOCTYPE html>
<html>
<head>
<style>
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<h2>Loader with image</h2>
<p><strong>Note:</strong> The -webkit- and -ms- prefixes are for browsers that do not support animation and transform properties.</p>
<div class="loader">
<img id="drawerUserImage" class="img-circle" src="https://cdn2.iconfinder.com/data/icons/picol-vector/32/view-128.png"/>
</div>
</body>
</html>
You could change it something like this with using image in the wrapper elements background:
.wrapper {
width: 152px;
height: 152px;
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
.wrapper {
background: url('https://cdn2.iconfinder.com/data/icons/picol-vector/32/view-128.png') center no-repeat;
background-size:50%;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="wrapper">
<div class="loader"></div>
</div>
You could try countering the rotating effect by creating identical animation for the img, just in opposite direction. However, a better option would be to change your DOM so that the image is not a child of animated parent.
.loader img {
-webkit-animation: counter-spin 2s linear infinite;
animation: counter-spin 2s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(-360deg); }
}

How to capture css3 animation iteration if alternate

I'm developing a small application based on css3 animation with keyframes. I'm interested only in Chrome behavior. I can use jQuery or vanilla Javascript.
If I set an animation "infinite" along with "alternate" property on an element, the event animationiteration is fired two times before reaching the initial state of the element, since the iteration is counted even when the animation "reverses" itself.
The only solution I came up, to know when the initial state is reached, is to track the iteration with a variable:
CSS example:
.animate{
-webkit-animation: k-wide 0.6s ease-in infinite alternate;
animation: k-wide 0.6s ease-in infinite alternate;
}
#-webkit-keyframes k-wide{
from { transform: scale(1); }
to { transform: scale(1.2); }
}
#keyframes k-wide{
from { transform: scale(1); }
to { transform: scale(1.2); }
}
Javascript example:
var initialState = true;
elem = $('#myAnimatedElem')
//event listener
.on('webkitAnimationIteration animationiteration',function(){
initialState = !initialState ;
if (initialState) runMyCustomScript();
})
//start animation
.addClass('animate');
The question is: is there another method to catch the initial state? Is there a more efficient one? I was wondering if I missed some event handler.
As far as I know, no, you can't.
Alternatives:
1) Remove alternate from the animation. Make it alternate using more keyframes
#-webkit-keyframes k-wide {
from { transform: scale(1); }
50% { transform: scale(1.2); }
to { transform: scale(1); }
}
2) Use timeelapsed from the event and do some math.
Note that in the first alternative, the timing function is preserved.
from the standard
For a keyframed animation, the ‘animation-timing-function’ applies
between keyframes, not over the entire animation. For example, in the
case of an ‘ease-in-out’ timing function, an animation will ease in at
the start of the keyframe and ease out at the end of the keyframe. An
‘animation-timing-function’ defined within a keyframe block applies to
that keyframe, otherwise the timing function specified for the
animation is used.
In the following demo, an alternate animation moves the red box. An independent, single animation, move the shadow around it.
Notice that the second part of the animation needs to have an ease-out (because the original is reversed
.base {
width: 400px;
height: 800px;
border: solid 1px;
display: inline-block;
position: absolute;
left: 10px;
top: 10px;
}
.move {
position: absolute;
width: 100%;
height: 10px;
border: solid 1px lightgreen;
-webkit-animation: move 10s infinite linear;
animation: move 10s infinite linear;
}
#-webkit-keyframes move {
from {top: 0px;}
to {top: 100%;}
}
#keyframes move {
from {top: 0px;}
to {top: 100%;}
}
.test1, .test2 {
position: absolute;
width: 10px;
height: 10px;
top: 0px;
left: 100%;
}
.test1 {
background-color: red;
-webkit-animation: test1 5s infinite ease-in alternate;
animation: test1 5s infinite ease-in alternate;
}
.test2 {
box-shadow: 0px 0px 0px 5px blue;
-webkit-animation: test2 10s infinite ease-in;
animation: test2 10s infinite ease-in;
}
#-webkit-keyframes test1 {
from {left: 0px;}
to {left: 100%;}
}
#-webkit-keyframes test2 {
from {left: 0px;}
50% {left: 100%; -webkit-animation-timing-function: ease-out;}
to {left: 0px;}
}
#keyframes test1 {
from {left: 0px;}
to {left: 100%;}
}
#keyframes test2 {
from {left: 0px;}
50% {left: 100%; animation-timing-function: ease-out;}
to {left: 0px;}
}
<div class="base">
<div class="move">
<div class="test1"></div>
</div>
</div>
<div class="base" id="base2">
<div class="move">
<div class="test2"></div>
</div>
</div>

Categories