ReactCSSTransitionGroup troubles - trying to get smooth slide in/out animation - css

I'm writing a questionnaire system in react and want to get the questions smoothly transitioning in and out.
Here's the render method for my component that displays the questions within.
render () {
const { loadingQuestion, question, userId, actions } = this.props;
const q = this.renderQuestion(question, (...args) => actions.answerQuestion(userId, ...args), (...args) => actions.skipQuestion(userId, ...args));
return (
<ul className="questions">
<ReactCSSTransitionGroup
transitionName="question"
transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}
>
{q}
</ReactCSSTransitionGroup>
</ul>
);
}
And also the css I'm using at the moment to achieve the vertical transition:
.question-enter {
transform: translateY(100%);
}
.question-enter.question-enter-active {
transform: translateY(0%);
transition: transform 1000ms ease-in-out;
}
.question-leave {
transform: translateY(0%);
}
.question-leave.question-leave-active {
transform: translateY(-100%);
transition: transform 1000ms ease-in-out;
}
Here's a link to a page showing the current behaviour:
http://price-it.co:8080/frame
Does anyone know why this css doesn't cause the question to slide out and instead just causes it to disappear?
Thanks!

Your example is not working in my browser (I got app.js:12Redux DevTools could not render. Did you forget to include DevTools.instrument() in your store enhancer chain before using createStore()? error).
But I could say I have the same kind of experience with CSSTransitionGroup, so I decided to use <TransitionGroup> with Velocity instead - sure it's a little bit more jQuery-style, but it obviosely works better then css animation.

Related

vue v-bind style - smooth changes, not instantly

I use "vuex-module-decorators" and dynamically determine the style in this getter:
<div class="viewport":style="viewportStyleVars">...</div>
get viewportStyleVars() {
const tx = -this.viewportRect.x;
const ty = -this.viewportRect.y;
return {
'--translate-x': `${tx}px`,
'--translate-y': `${ty}px`,
}
}
How to make change happen smoothly, not instantly?
I would be grateful for the hints, I am not familiar with the animation.
You just need to add transition in CSS to the div with class .viewport something like:
.viewport{
transition: all 1s linear;
}
The 1s in the transition, is the time, that the action will take, you can tweak this value to something smaller, like 0.1s, if that suits you better.

Angular Universal SSR CSS animation transform Error

I have added Angular universal to my app and followed the guide on https://angular.io/guide/universal
It was realy simple, I'm just struggling with this Error:
ERROR Error: Unable to build the animation due to the following errors: The provided animation property "transform" is not a supported CSS property for animations
The provided animation property "transform" is not a supported CSS property for animations
The reason for this is a simple Button with a keyframe animation which uses transform: rotate(0deg);
The button is round and rolls from the right to the left side after loading.
Is there any workaround to solve this issue? I'm sure that transform is quite a valid CSS property for animations.
Edit:
I use the transform Property inside of a components scss file. The content is static and the component shows a whole site. The css code is this:
.roll-in { animation: 2s linear 0s 1 animation;
animation-fill-mode: both;
}
#keyframes animation {
0% {
left: 110%;
}
10% {
transform: rotate(0deg);
left: 110%;
}
100% {
transform: rotate(-720deg);
left: 0px;
}
}
After running the app with serve:ssr the element has no animation attribute.
I think, it happens when the animation starts on server side rendering itself. Since this is SSR, there is no meaning of loading the animations on server version.
Load the animations only in Browser platform version. So, animations will start only after the page rendered in browser view. For example,
component.ts
import { Component, Inject } from '#angular/core';
import { PLATFORM_ID } from '#angular/core';
import { isPlatformBrowser } from '#angular/common';
#Component({
selector: 'my-animated-component',
templateUrl: './my-animated-component.html'
})
export class MyAnimatedComponent{
isBrowser: boolean;
constructor( #Inject(PLATFORM_ID) platformId: Object) {
this.isBrowser = isPlatformBrowser(platformId);
}
}
In markup
<div *ngIf="isBrowser">
<my-animated-component></my-animated-component>
</div>
It's recommended to use Angular native animations rather than CSS animations. A working example is here: https://stackblitz.com/edit/angular-animate-keyframes

How to custom transition for each component?

I have 3 components which I want to show a transition effect when they enter/leave.
There's 1 "main" component and the 2 others show up when you press the associated button. My current sample code is here: https://jsfiddle.net/5aq1k05L/
<transition :name="'step_' + currentView" mode="out-in">
<component :is="currentView"></component>
</transition>
CSS:
.step_componentA-enter-active {
transition: transform 0.4s;
}
.step_componentA-leave-active {
transition: transform 0s;
}
.step_componentA-enter {
transform: translateX(-100%);
}
.step_mainComponent-leave-active {
transition: transform 0.3s;
}
.step_mainComponent-leave-to {
transform: translateX(-100%);
}
.step_componentB-enter-active {
transition: transform 0.4s;
}
.step_componentB-leave-active {
transition: transform 0s;
}
.step_componentB-enter {
transform: translateX(100%);
}
What I am trying to do:
When I click on the "componentA" button, I want that component to slide from the left while "mainComponent" is still visible in the background (not stripped out of elements like now) during the transition.
Same thing for "componentB", except it will slide from the right, and will back to the right when clicking back.
What am I missing? https://jsfiddle.net/5aq1k05L/
Edit 2:
Here a working example with the componentA and componentB that are sliding over the mainComponent -> https://jsfiddle.net/5aq1k05L/8/
I changed the transition to mode:in-out, I added a z-index for each component, and put the components in position:absolute and the app in position:relative
Edit:
Here a working example for your case -> https://jsfiddle.net/5aq1k05L/4/
When you analyse the script step by step, you see that the class when the componentB is leaving is step_mainComponent-leave-active step_mainComponent-leave-to that it makes a classic toggle relative to the mainComponent style.
If you want to use different animations, you should use enter-active-class and leave-active-class etc (see more here) - or put two vars in name, i guess, with a dynamic value relative to the previous view, in the store like currentView is.
It could be like this :
<transition
:name="'step_' + currentView + '_from_' + prevView"
mode="out-in"
>
In the store (you ll need to update the states, mapState, etc.. as well too) :
SET_CURRENT_VIEW(state, new_currentView) {
state.prevView = state.currentView;
state.currentView = new_currentView;
}
Hope it ll help you

Animating div content populated by AngularJS without jQuery

I have a div like this:
<div class="row">
<alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
</div>
I create the alerts in angularjs (and I'm using bootstrap), and while this works great, the visual effect is kind of uncool. As alerts are added to the div, all page content is shoved ungracefully down to make room for the new alert.
I would like to animate the movement so that it is at least smooth. But I don't want to use jQuery. I've played with the CSS3 transitions, but can't seem to get them to work smoothly.
Can I do this where the trigger is a change in div height? How?
you can do it with directives in their link function. i think you wont mind about so small piece on jquery code
myModule.directive('animateRight', function () {
var linker = function (scope, element, attrs) {
var right = function() {
$(this).animate({
{"height": "800px"},
"fast");
})
}
element.on('click', right);
};
return {
restrict:'A',
link:linker
}
})
<div animate-right class="box"></div>
Ok, so I don't like to answer my own question, but this seems like the way to do it...
I used AngularJS 1.2, along with the new ngAnimate module. You need to add angular-animate.js, and reference the animate module, so at the end here's what my modules looked like:
var app = angular.module('tracker', ['$strap.directives', 'ui.bootstrap', 'ngRoute', 'ngAnimate']);
After that, its super simple, and very much CSS3 animations. My alert line ended up with a class repeat-item:
<alert class="repeat-item" type="alert.type" data-ng-repeat="alert in alerts" close="closeAlert($index)">{{alert.msg}}</alert>
And I added some CSS to target that class with the angularjs triggers:
.repeat-item.ng-enter,
.repeat-item.ng-leave {
-webkit-transition: 0.2s linear all;
-moz-transition: 0.2s linear all;
-o-transition: 0.2s linear all;
transition: 0.2s linear all;
}
.repeat-item.ng-enter,
.repeat-item.ng-leave.ng-leave-active {
opacity: 0;
}
.repeat-item.ng-leave,
.repeat-item.ng-enter.ng-enter-active {
opacity: 1;
}
And voila a nice fade in and out animation.
This page really explains very well how to do it. Cheers to Michael Benford for the great link.

jQuery Mobile: How do you simulate the iOS slide-out navigation pattern on jQuery Mobile?

EDIT 2/13: The Panels widget in jQuery Mobile 1.3 now exists! Please use this instead.
I'm trying to write a custom CSS-based transition in jQuery Mobile to simulate the slide-out navigation design pattern.
What I'm trying to accomplish is to have the navigation slide into view and take up 75% of the viewport space. The remaining 25% is filled with the remainder of the previous page.
Here's my CSS:
.slidenav.in { /*New page coming in*/
-webkit-transform: translateX(-75%);
-webkit-animation-name: slidenav-in;
}
#-webkit-keyframes slidenav-in {
from { -webkit-transform: translateX(-75%); }
to { -webkit-transform: translateX(0); }
}
.slidenav.out { /*Old page going out*/
-webkit-transform: translateX(0);
-webkit-animation-name: slidenav-content-out;
}
#-webkit-keyframes slidenav-content-out {
from { -webkit-transform: translateX(0); }
to { -webkit-transform: translateX(75%); }
}
.slidenav.in.reverse { /*Old page coming in*/
-webkit-transform: translateX(75%);
-webkit-animation-name: slidenav-content-in;
}
#-webkit-keyframes slidenav-content-in {
from { -webkit-transform: translateX(75%); }
to { -webkit-transform: translateX(0); }
}
.slidenav.out.reverse { /*New page going out*/
-webkit-transform: translateX(0);
-webkit-animation-name: slidenav-out;
}
#-webkit-keyframes slidenav-out {
from { -webkit-transform: translateX(0); }
to { -webkit-transform: translateX(-75%); }
}
I can't seem to get it to do what I want, though. It removes the old page entirely instead of leaving the remaining 25% of the page in view.
You can see what's happening here (Webkit browsers): http://jsbin.com/ukajeb/7
What am I doing wrong?
EDIT 2/13: The Panels widget in jQuery Mobile 1.3 now exists! Please use this instead.
So I worked some more on this and, with the help of Firebug, discovered that after the keyframe animation was occurring, the original page was being reset to its original position and display set to none.
Knowing this, I started going through the jQuery Mobile docs a bit more thoroughly and found that there are Page Transition Events that you can bind to. More specifically, the pageshow and pagehide events.
Then I set the CSS of the original page manually:
$('[data-role=page]').live('pagehide',function(event, ui){
$(this).css({
"display": "block",
"-webkit-transform": "translateX(75%)"
});
});
$('[data-role=page]').live('pageshow',function(event, ui){
$(this).css({
"display": "",
"-webkit-transform": ""
});
});
Check it out here (Webkit browsers): http://jsbin.com/ukajeb/3
Hope someone else finds this useful as well!
Note: This demo uses jQuery Mobile 1.0.1, which only supports jQuery 1.6.4. This is why .live() was used rather than .on(). However, the upcoming jQuery Mobile 1.1.0 will support jQuery 1.7.1, so moving forward .on() should be used in place of the deprecated .live().
I don't know if this will fully help, but I took a look at this inside of firebug a bit. What I think is happening is when you complete the transition (even the partial one) the active page becomes the menu you are transitioning to. This means the last page is being hidden as it is no longer active. And in fact you can see when the transition completes the other page with "content" disappears.
You might try this on your link that invokes the menu - try using a dialog. You would still need to apply your custom transition there. I think what you are trying to accomplish you may also look into a plugin called "sub page" it may get you to the look you are trying to achieve. Also there is splitview (http://asyraf9.github.com/jquery-mobile/) Alternately you could try messing around with the 1.2 branch of JQM and see if POPUP men may get you there as well. Essentially, it is a div that can sit on top of the existing active page.
Open dialog
I originally was using a dialog with a slide up / down effect - but it became too troublesome in Android so we removed it.
I don't think JQM was really designed by default to keep two pages active and visible at once.

Resources