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
Related
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
I'm creating a dashboard page which is full of CSS animations. From Bootstrap stuff (animated progress bars) to custom animations.
When you click some of the elements, a near full-screen modal is triggered, which overlaps all the animations, so I want to temporarily pause them all (because of possible performance issues) by adding/removing a class to one of the top elements, and using CSS to pause all animations when that class is set.
This solution would use only a single line of js, just to toggle the class on opening the modal.
My template looks somewhat like this:
<body>
<div class="modal">
<!-- Modal code -->
</div>
<div class="app">
<!-- Template -->
</div>
</div>
Is it possible to add a class to .app which pauses every CSS animation in every child element?
Note 1:
I know you can use the exact opposite of what I request: namely, have a default .animation-play class to one of the top elements, and prefix every child element with an animation with this class, and then remove this class to pause every animation. Just like:
app.animation-play .somediv .somediv .element {
// animation code
}
app.animation-play .somediv .element {
// animation code
}
app.animation-play .somediv .somediv .somediv .somediv .element {
// animation code
}
But then I have to edit a lot of CSS code, and it doesn't look very nice either.
Note 2:
I'm also open for a JS solution, but I would heavily prefer a pure CSS way of achieving this.
You can use a universal selector to target everything when a class of 'paused' is added to your app wrapper, however many CSS linters still warn against using these due to performance impacts.
To be honest the impact is probably minimal these days and many CSS resets for example use them.
You could use something like:
.app.paused * {
animation: none;
}
EDIT:
Looking through the comments above it seems as though the above selector doesn't have enough precedence to overwrite the animations so '!important' has been added.
.app.paused * {
animation: none !important;
transition: none !important;
}
However this is generally not a great idea, I always try to avoid using '!important' at all costs due to the difficulty in maintaining the stylesheet with these selectors in place. If you can overwrite the animations with a greater precedence then it would be better to do so rather than using '!important'.
EDIT 2:
As you mentioned you were open to JS solutions, here is some JS that should clear all the animations within a given selector. I'm not sure what the performance impact of doing it this way is but I added it here just in case someone else prefers to do it only using JS:
let stopAnimationsWrap = document.querySelector('.app');
let stoppedAnims = [];
// Stop animations
document.querySelector('.stop').addEventListener('click', () => {
let appAllEls = stopAnimationsWrap.querySelectorAll('*');
let allElsAr = Array.prototype.slice.call(appAllEls);
allElsAr.forEach((thisEl) => {
let elClass = thisEl.classList[0];
let cs = getComputedStyle(thisEl, null);
let thisAnimation = cs.getPropertyValue('animation-name');
if (thisAnimation !== 'none') {
stoppedAnims.push([elClass, {
'animationName': thisAnimation
}]);
thisEl.style.animationName = 'none';
}
});
});
// Start animations
document.querySelector('.start').addEventListener('click', () => {
stoppedAnims.forEach((thisEl) => {
let domEl = '.' + thisEl[0];
stopAnimationsWrap.querySelector(domEl).style.animationName = thisEl[1].animationName;
});
});
Fiddle:
https://jsfiddle.net/vu6javb2/14/
.app {
-webkit-animation-play-state: paused; /* Safari 4.0 - 8.0 */
animation-play-state: paused;
}
on hover:
.app:hover {
-webkit-animation-play-state: paused; /* Safari 4.0 - 8.0 */
animation-play-state: paused;
}
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.
The site where I want my animation to work adds #user-space before any of my tags. So, my animation looks like this:
#user-space #-webkit-keyframes animation-name {
from {
style definition ["Before"-state]
}
to {
style definition ["After"-state]
}
And that #user-space declaration is breaking the css statement and animation is not working. Is there any way, to do that otherwise? For exaple put my keyframes insine -webkit-animation: animation-name 1.1s ease infinite; like
webkit-animation: from {
style definition ["Before"-state]
}
to {
style definition ["After"-state]
} 1.1s ease infinite; like
The solution I see is to get around your problem and do it with javascript.
Simply add a new style in your html file (in the header) and add the #-webkit-keyframes animation inside.
There is a thread which explains it well (see accepted solution): Set the webkit-keyframes from/to parameter with JavaScript
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.