Angular2 Height Animation - same state transition - css

I have the following animation code attached to my component
animations:[
trigger('slide', [
state('show', style({
height: '*'
})),
state('hide', style({
position: 'relative',
height: 0,
overflow: 'hidden'
})),
transition('show <=> hide',animate('130ms ease-out'))
])
]
This is quite hard to explain, (and I can't seem to get animations to work on plunker) but here goes.
The current functionality is as follows:
User clicks a button to display table.
Table smoothly slides into view from below a div.
User click button again.
Table smoothly slides out of the view up into the div.
The desired functionality is as follows:
User clicks a button to display table.
Table smoothly slides into view from below a div.
More rows are added to table (could be a large number of rows)
Animation handles the new table height and instead of just instantly being displayed there is a smoothing animation to gradually move to the new height.
User Clicks button.
Table slides back up under div again.
Edit: here is a plunker demo. You can see when you add/remove rows from the table the animation does not smoothly move to the new height.
The problem is caused because if you are in true state and rows are added.
The animation will not transition to true again, because it is already in true state.
So how will I trigger a transition to the "newHeight" state when items are added?

I made a quick, rough, animation example using angular animations API:
https://embed.plnkr.co/7qWuHmbFFie4p8Y9h53T/
I would play around with that plnkr until you get the animations right. You can hide the element behind something by either removing the table entirely after animating it down by toggling the animation with an *ngIf in your template, or do it the way I show in the plnkr, but toggle the visibility of the table after the animation is complete. I prefer the *ngIf way.
For individual rows being added or removed:
I would add an #animation to every row of the table and enable the up animation if the number of rows increases, or down if it decreases.

Related

Creating ripple effect in TailwindCSS, but not on click, rather on hover

There are a couple examples of how to create a ripple effect in TailwindCSS for click:
https://tailwind-elements.com/docs/standard/methods/ripple/#!
https://codepen.io/vituja1/pen/oNWzNwq
And basically it's about creating an element that grows inside the boundary of the parent button and vanishes.
targetElement.addEventListener('click', e => {
// create an element, append it to the target, let it grow, and then remove it
});
However, I want to create the ripple that acts on hover, not on click. As you can see here:
https://www.templatemonsterpreview.com/demo/187467.html
How can we achieve this effect in tailwind?

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

React loses CSS transition if element ordering changes

React keys are not working.
If I swap the position of two react elements (item0 and item1) positioned with transform transform: translate(); a css transition is triggered, only if the elements were rendered in the same order.
If I change the order of the render (position swap still the same but now item0 renders after item1), the css transition is not triggered.
It looks like react is deleting the DOM element and recreating it, even if they have React keys set.
Here is a simple JSfiddle with the problem.
https://jsfiddle.net/santiagopuentep/vvpezbp9/2/
Here is a written explanation:
Two React elements (item0 and item1) positioned with transform: translate(); in css and with a css transition active for that transform.
The app renders a list of items using a layout.
The first layout is:
item0 at translate(0px,0px); and item1 at translate(0px,50px);.
The second layout with the same items but with positions flipped:
item0 at translate(0px,50px); and item1 at translate(0px,0px);.
Clicking on any of the two items changed the layout back and forth from the two, swapping their positions and thus triggering the css transition for the position change.
This works just fine, the transitions trigger correctly.
The problem happens if the second layout makes the item1 render after item0 (only change in render order, css translate positions still swapped), the transition for the second element is lost.
This looks like React is deleting the element instead of just reordering it, even if I have keys set.
Please help!
Thank you very much! I confirm this issue, so workaround is:
lastOrder = []
render() {
let cards=this.props.cardList
// HERE I RESORT NEW LIST LIKE PREVIOUS IT
if (this.lastOrder.length) cards.sort((a, b) =>
(this.lastOrder.indexOf(a.id) - this.lastOrder.indexOf(b.id)))
// AND SAVE LAST ORDER
this.lastOrder = cards.map(card => card.id)
return <div className='board'>
{cards.map(card => <Card key={card.id} {...card} />)}
</div>
}

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

Resources