How to make a CSS3 animation reusable? - css

Without JQuery.
I have the following code but it will only work on one click. It will not be able to be used twice:
#-moz-keyframes lulse {
0%{
-moz-transform:scale(1);
}
20%{
-moz-transform:scale(1.5);
}
100% {
-moz-transform:scale(1);
}
}
.pinto {
-moz-animation-name: lulse;
-moz-animation-duration: .2s;
-moz-animation-iteration-count: 1;
-moz-animation-timing-function: linear;
-moz-animation-direction: normal;
}
Javascript:
onclick="changeClass(this.id);
function changeClass(a)
{
document.getElementById(a).className += "pinto";
}

Hmm, on the surface it looks like you should be able to remove the class at the beginning of your click handler if it exists. Specifically:
function changeClass(a) {
var elementA = document.getElementById(a);
var regEx = new RegExp('(\\s|^)pinto(\\s|$)');
elementA.className = elementA.className.replace(regEx,' ');
elementA.className += " pinto";
}
This will remove the class and reapply it, which should restart the effect.

Related

How I can make animation for background?

I have a menu form. To add and remove items from this menu, I use React Transition Group
ReactJS:
<TransitionGroup>
{
menu.map(meal =>
<CSSTransition
key={meal.id}
timeout={500}
classNames="meMeals"
>
<Meal meal={meal} deleteFromMenu={deleteMealFromMenu}/>
</CSSTransition>
)
}
</TransitionGroup>
CSS:
.meMeals-enter {
opacity: 0;
transform: translateY(-30px);
}
.meMeals-enter-active {
opacity: 1;
transform: translateY(0);
transition: all 500ms ease-in;
}
.meMeals-exit {
opacity: 1;
transform: translateY(0);
}
.meMeals-exit-active {
opacity: 0;
transform: translateY(-30px);
transition: all 500ms ease-in;
}
and I am completely satisfied with the behavior of the menu items.
Now I want the background element (grey) as well as the add button to move smoothly as the menu item appears or disappears. How can i do this?
I solved the problem by writing a method that is not directly related to the TransitionGroup, but works in parallel. I also set my window:
transition: 0.5s;
whatever the animation
Now I call this method every time the list changes....
function replaceMenuSize(value) {
const menuSize = menuEditorRef.current.getBoundingClientRect().height
if (value > 0) {
menuEditorRef.current.setAttribute("style", "height: " + (menuSize + 41) + "px")
} else {
menuEditorRef.current.setAttribute("style", "height: " + (menuSize - 41) + "px")
}
}

Random image slideshow, image transition fade in/out?

I am using this script for a random image slideshow, trying to display sponsor images. The script works fine, I'm trying to create a fade in and/or fade out effect to it.
The script:
<script>
var delay=4000
var curindex=0
var randomimages=new Array()
randomimages[0]="https://cdn4.sportngin.com/attachments/photo/5aed-137970385/cambria_large.jpg"
randomimages[1]="https://cdn1.sportngin.com/attachments/photo/acab-137970605/9Round_large.png"
randomimages[2]="https://cdn2.sportngin.com/attachments/photo/a12b-137971067/qdoba_large.jpg"
randomimages[3]="https://cdn1.sportngin.com/attachments/photo/fcf5-137974579/chipotle_large.jpg"
randomimages[4]="https://cdn3.sportngin.com/attachments/photo/3397-137974001/countryinn_large.jpg"
var preload=new Array()
for (n=0;n<randomimages.length;n++)
{
preload[n]=new Image()
preload[n].src=randomimages[n]
}
document.write('<img class="fade-in" name="defaultimage" height="294" width="294" style="display:block; margin-left:auto; margin-right:auto;" src="'+randomimages[Math.floor(Math.random()*(randomimages.length))]+'">')
function rotateimage()
{
if (curindex==(tempindex=Math.floor(Math.random()*(randomimages.length)))){
curindex=curindex==0? 1 : curindex-1
}
else
curindex=tempindex
document.images.defaultimage.src=randomimages[curindex]
}
setInterval("rotateimage()",delay)
</script>
The script itself works fine.
This is the CSS I've tried for the image transition:
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 4s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
When the page loads the fade in works on the first image, but none of the subsequent ones JSFiddle. I'm hoping someone could steer me in the right direction.
Here a solution, add notes inside:
var delay=4000
var curindex=0
var randomimages=new Array()
randomimages[0]="https://cdn4.sportngin.com/attachments/photo/5aed-137970385/cambria_large.jpg"
randomimages[1]="https://cdn1.sportngin.com/attachments/photo/acab-137970605/9Round_large.png"
randomimages[2]="https://cdn2.sportngin.com/attachments/photo/a12b-137971067/qdoba_large.jpg"
randomimages[3]="https://cdn1.sportngin.com/attachments/photo/fcf5-137974579/chipotle_large.jpg"
randomimages[4]="https://cdn3.sportngin.com/attachments/photo/3397-137974001/countryinn_large.jpg"
var preload=new Array()
for (n=0;n<randomimages.length;n++)
{
preload[n]=new Image()
preload[n].src=randomimages[n]
}
//document.write('<img class="fade-in" name="defaultimage" height="294" width="294" style="display:block; margin-left:auto; margin-right:auto;" src="'+randomimages[Math.floor(Math.random()*(randomimages.length))]+'">')
// place the image on container:
document.querySelector('figure').innerHTML = '<img class="fade-in" name="defaultimage" height="294" width="294" style="display:block; margin-left:auto; margin-right:auto;" src="'+randomimages[Math.floor(Math.random()*(randomimages.length))]+'">';
function rotateimage()
{
document.querySelector('figure').innerHTML = ''; // clear image from container
if (curindex==(tempindex=Math.floor(Math.random()*(randomimages.length)))){
curindex=curindex==0? 1 : curindex-1
}
else
curindex=tempindex
// document.images.defaultimage.src=randomimages[curindex]
// place image with different source on the container
document.querySelector('figure').innerHTML = '<img class="fade-in" name="defaultimage" height="294" width="294" style="display:block; margin-left:auto; margin-right:auto;" src="'+randomimages[curindex]+'">';
}
setInterval("rotateimage()",delay)
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 4s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<figure></figure>
Additional important notes:
The key here is to create the element so the class will work. Now you are just changing src attribute so the class doesn't change (you can inspect that on browser dev tools).
On your code you use document.write. I change it to .innerHTML - both consider to be BAD practices on production. You should create and append nodes instead. I use it here cause it fast.

Animation delays generation with LESS

I am trying to generate animation delays with LESS. The final result should be similar to:
[data-animation-delay="1"] {
animation-delay: .5s;
}
[data-animation-delay="2"] {
animation-delay: 1s;
}
My code looks like:
#animation-delays: 10;
#animation-delay-step: .5; // delay in seconds
.animation-delays-loop (#i) when (#i > 0) {
[data-animation-step="#{i}"] {
#animation-delay = #animation-delay-step * #{i};
animation-delay: #animation-delay~"s";
}
.animation-delays-loop(#i - 1);
}
.animation-delays-loop (#animation-delays);
However, it doesn't work. The problem seems to be in animation-delay: #animation-delay~"s";. Any ideas how to correct it?
OK, I ended up with doing this:
#animation-delays: 10;
#animation-delay-step: .5; // delay in seconds
.animation-delays-loop (#i) when (#i > 0) {
[data-animation-step="#{i}"] {
#animation-delay: #i * #animation-delay-step;
animation-delay: ~"#{animation-delay}s";
}
.animation-delays-loop(#i - 1);
}
.animation-delays-loop (#animation-delays);
worked like a charm.

CSSTransitionGroup doesn't fade in

I am quite new to react and I am trying to build a react app. I want a login box to fade in on the page when the login in the navbar is clicked. In my App.js I set up the CSSTransitionGroup like this:
<CSSTransitionGroup
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
transitionAppear={true}
transitionAppearTimeout={500}
transitionName="fade">
{loginPopup}
</CSSTransitionGroup>
The login popup is shown based on state:
let loginPopup;
if (display_login) {
loginPopup = (<LoginPopup key={1} />)
}
Now the css I use for the transition looks like this:
//fade
.fade-appear {
opacity: 0.01;
}
.fade-appear-active {
opacity: 1;
transition: opacity 300ms ease-in;
}
.fade-leave {
opacity: 1;
}
.fade-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}
My problem is...that the fadeout works as intended, but the fadein does not work. It just pops up (no transition).
I also tried using .fade-enter - But I figured that enter was wrong as the LoginPopup component is spawned based on state.
Any ideas why the fade in don't work?
Edit:
This is the gist of the code: https://gist.github.com/xenoxsis/6345eb6897aedf228662ffaf64f65053

What is wrong with ReactCSSTransitionGroup?

I have this code inside render() function in my component:
..
<ReactCSSTransitionGroup
transitionName="testing"
transitionEnterTimeout={600}
transitionLeaveTimeout={600}>
<div>testing animations!</div>
</ReactCSSTransitionGroup>
..
And i have this code in my CSS file:
.testing-enter {
animation: slideIn 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.testing-leave {
animation: slideOut 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
}
#keyframes slideIn {
0% {
opacity 0
transform translate3d(-50px, 0, 0)
}
100% {
opacity 1
transform translate3d(0, 0, 0)
}
}
#keyframes slideOut {
0% {
opacity: 1
transform: translate3d(0, 0, 0)
}
100% {
opacity: 0
transform: translate3d(50px, 0, 0)
}
}
I just want my div block to slideIn from the right, but nothing happens! Could not find the wrong piece of code, it looks like everything is ok.
You have static content inside the <ReactCSSTransitionGroup/> tag. You need to have dynamic content. Let's say you need to render <div>testing animations!</div> upon mouse click. You need to assign the children to a variable and modify the variable upon mouse click.
let myDiv = buttonClicked ? <div>testing animations!</div> : <div></div>
<ReactCSSTransitionGroup
transitionName="testing"
transitionEnterTimeout={600}
transitionLeaveTimeout={600}>
{myDiv}
</ReactCSSTransitionGroup>
If no actions are performed and you simply need to animate it on initial mount, use transition-appear instead.
ReactCSSTransitionGroup provides the optional prop transitionAppear,
to add an extra transition phase at the initial mount of the
component. There is generally no transition phase at the initial mount
as the default value of transitionAppear is false. The following is an
example which passes the prop transitionAppear with the value true.
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500}>
<div>testing animations!</div>
</ReactCSSTransitionGroup>
.example-appear {
opacity: 0.01;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}

Resources