Framer motion: move down element with animation after triggering other animation - css

I am wondering how to do the following scenario with Framer motion: I have a list that appears when I click on a button. The list comes in with a fade-in animation. However, the box of content below will immediately move down without an animation. What I would like to achieve is that the 'box with content' moves downwards smoothly to its new place while the list animation is going on. How can I achieve this? I have made a code sandbox to replicate the situation:
https://codesandbox.io/s/stupefied-shockley-pwxg9e?file=/src/App.js

Couple of things:
Framer Motion lets you animate height from 0 to auto
Animate Presence requires you to add a key to the items. In your case I used index
I updated your sandbox to work. 1 fixes the content reflow. 2 fixes the exit animation not working
https://codesandbox.io/s/broken-http-n8i2hk?file=/src/App.js
I did a writeup on this feature in Framer Motion, because I think it is rather undocumented. Check it out if you like: https://www.joshuawootonn.com/how-to-animate-width-and-height-with-framer-motion

Related

How can I make `react-beautiful-dnd` not trigger a `react-transition-group` animation?

Video demonstrating my issue: https://i.imgur.com/L3laZLc.mp4
I have a simple app where you can add Cards to 2 different Rows. When a card is added to a row, I'm using react-transition-group to trigger an "enter" animation.
However, I also have react-beautiful-dnd installed to enable dragging Cards between the Rows, and also to re-order the Rows themselves. But when a Card is moved to a new Row, or when the Rows are re-ordered, some of the cards have their "enter" animation fire, which looks very weird and should not be happening.
When dragging, the unwanted animation will fire when
A Card is dragged to a different Row.
A Row is re-ordered and the 2 Rows have different numbers of
Cards.
Oddly, the unwanted animations will not happen when
A Card is dragged to a new position within its original Row.
The Rows are re-ordered and the Rows have the same number of Cards.
I would like to know how I can have it so the react-transition-group animations will not fire when the state is modified by using react-beautiful-dnd.
Sandbox of my issue (More information in comments in the App.js file):
https://codesandbox.io/s/get-beautiful-drag-to-not-trigger-transition-group-tc40w?fontsize=14&hidenavigation=1&theme=dark
I have modified solution by RaviNila to remove afforementioned blink when you drag between rows, by intoducing additional collection of styles. That blink was caused by this css property:
transition: all 200ms ease-out;
When item was rendered as a part of TransitionGroup even though it was set to timeout 0 and "" as a class, the transition still happend, propbably because newCardItem was changes in setTimeout. But removing setTimeout completely kills the animation. So repeating the styles without that transition property fully fixes your issue, afaics.
https://codesandbox.io/s/get-beautiful-drag-to-not-trigger-transition-group-share-bpc43
In App.js you have mentioned the following comment which is your requirement:
What I want:
I would like the react-transition-group animations to fire only when new state is added
and not when state is modified by dragging and dropping (with the onDragEnd function);
This issue can be fixed just by introducing a new flag hasNewCard. This flag will be true only when a new card is created, not when state is modified by onDragEnd.
So here react-transition-group animation should fire only when hasNewCard is true.
CodeSandbox version:
https://codesandbox.io/s/get-beautiful-drag-to-not-trigger-transition-group-share-o25ej

How to control which attribute selector changes trigger a css animation?

With the following rules:
.container[data-direction="reverse"] .pane[style*="display: none"]{
animation:SlideOutToRight 1s ease;
}
.container[data-direction="forward"] .pane[style*="display: none"]{
animation:SlideOutToLeft 1s ease;
}
The animation runs whenever (a) the data-direction attribute changes and (b) whenever the style becomes display:none. How can I change this code so that the animation only runs when the style becomes display:none but not when the data-direction attribute changes?
Right now, when the direction changes, all of the containers go flying across the screen to the other side because the animation gets applied to all of them when the data attribute changes value.
The data-direction attribute should only control which animation plays, but changes to it's value should not trigger the animation. Is this possible?
Update:
Here is a fiddle of the problem: https://jsfiddle.net/j6ytzbh6/
Expected behavior: The forward button should cause the next sequential box to enter from the right hand side while the current box exists left. The backward button should cause the previous sequential box to enter from the left while the current box exits right. No other box should move or cross the view-port when its not it's turn to move.
Reminder: This is a CSS question, so doing the animation in javascript is cheating. The idea is that Javascript controls functionality (ie a box should be shown or hidden) while css controls presentation (ie. do we make it disappear, fade out or fly to the side). You shouldn't have to re-write your plugin to change the visual way things get shown or hidden.

Repeat Error on Slick Carousel

I'm trying to use CSS transforms to make the center object in a carousel have more focus/attention. (Carousel is Slick.js)
Everything works great, except when I go from the last item back to the first item, there is a pause and a jump before the change appears.
What is causing this? How do I fix it?
https://jsfiddle.net/6d91cqoq/1/
//pseudo code
EDIT: It also happens going from the first to the last.
EDIT 2:
It's worth noting I took the idea from the Slick.js website: http://kenwheeler.github.io/slick/
On the page with the 'Center Mode' example, it is using transforms to do this exact thing. I cannot for the life of me figure out what is different, other than the target element.
EDIT 3: I did attempt to change my elements to H3 elements, as is in the sample. No change.
The cause for this is that Slick changes the DOM order of the slide elements when switching from "first to last". The transition doesn't kick in when dom elements are removed and added back... You can work around this by playing around with javascript and Slicks beforeChange and afterChange events instead of a pure CSS solution. I have made an example, although the example I made also slightly changes the effect (the center slide won't widen until it is in the center, e.g. afterChange). Maybe with Slicks, next and previous slide parameters you can make it work like your example, didn't have time to investigate it more.
https://jsfiddle.net/6d91cqoq/2/
Changes made to your example:
//Added my own "active" class, so it does not to interfere with slicks active class
.slick-slide.active {
opacity: 1;
transform: scale(1.50);
}
JS
//make current center active after initialization
$('.slick-center').addClass('active');
//before slide change, make all "inactive"
$('.center').on('beforeChange', function(event, slick, index){
$('.slick-slide').removeClass('active');
});
//after change make the center one "active"
$('.center').on('afterChange', function(event, slick, index){
$(slick.$slides[index]).addClass('active');
});

Layers disappear after a while?

So I'm using Revolution Slider with 1 slide only and the layers on my slide keep disappearing after X minutes even though:
my slide is set to 9 seconds
the slide is set to end on this slide (General Settings -> Pause Slider -> Stop Slider Progress)
all the layers are set to fade after the slide ends so I have no clue what is with this glitch of layers disappearing after a few minutes.
Has anyone experienced something similar?
I reckon your problem will be fixed by following the instructions at https://www.themepunch.com/faq/prevent-layers-from-disappearing/.
To paraphrase those instructions, in the layers timeline section of the slide editor, set the layer to snap to the end of the timeline. The alternative is to set the layer to disappear beforehand which you don't want. This is a simple toggle button under the 'Fade' Column header.

CSS3: Base state, animation and back

Basically, I have an element with a given width and height. When I add the "zoomed" class to it, I want it to change its size and position. I got it working with a proper webkit-animation (keyframed).
The problem is that when I remove the "zoomed" class, it suddenly reverts to the original size and position, and I'd love to do it with an animation.
Note that this is an example that could probably be solved with the use of the transition property, but in my real world case, it can't because I have a fairly complex keyframed animation.
So, how to have a basic state, animate to a new state when a class is added and reverse the animation to the basic state when the class is removed? Thanks.
The problem that you have wouldn't be solved with a transition.
What makes a transition work in both ways is that usually you set it in a class, and change properties in an state. This way, you have the transition set all the time, and only change the properties.
If you set the transition in the changed state only, once you remove it, the transition is no longer in the element, and so the change is immediate.
If adding the class is really the procedure that you want (for some other reason), the you have 3 posibilities
As suggested in the comment, in the change to the basic state you should add another class that has as only property the animation playing in reverse.
In the base element set the animation in reverse, in the added class set the animation.
Go to an elaborate system where you really remove the class in the animation end event, and what you do triggers that (way too complicated I think)
There is no way that the element is animated - transitioned - whatever once you remove that from the element

Resources