I created a tab-based Ionic 2 project and I'm using the following lifecycle hooks to define a trigger property for animations to occur when a given page loads:
ionViewDidEnter() {
this.state = 'active';
console.log(this.state);
}
ionViewWillLeave() {
this.state = 'inactive';
console.log(this.state);
}
This is what the animations looks like in the component decorator:
animations: [
trigger('focusPanel', [
state('inactive', style({
opacity: '0'
})),
state('active', style({
transform: 'translateY(-80px)',
opacity: '1'
})),
transition('* <=> active', animate('.5s ease-out'))
]),
]
This works when the app loads. I can click on a different tab and go back, and the animation works as expected.
However, if I go back a third time, while the console.log is accurate and consistent, the animations no longer play. It doesn't fade from 0 opacity, and it does not animate up based on translateY.
Any idea of what's going on? I've tried different lifecycle hooks, as well as different transition() properties in the animations above.
Related
I have an Animation class given below:
import { trigger, state, style, transition, animate } from '#angular/animations';
export class Animations {
constructor() {}
animate = animate('.5s cubic-bezier(0.68, -0.55, 0.265, 1.55)');
side() {
return trigger(`visibilityAnimation`, [
state('false', style({
transform: '{{ side }}',
display: 'none'
}), { params: { side: 'translateX(100%)' } }),
state('true', style({
transform: 'translateX(0)',
display: 'block'
})),
transition('false <=> true', this.animate),
]);
}
top() {.....}
chooseAnimation() {....}
background() {....}
}
In one of my components I'm using as follows:
import { Animations } from './animations';
const animations = new Animations();
#Component({
selector: 'app-nav-user',
templateUrl: './nav-user.component.html',
styleUrls: ['./nav-user.component.scss'],
animations: [
animations.chooseAnimation(),
animations.background()
]
})
When I use ng build --prod --aot --output-hashing=all, I get the above error.
Note: I'm using angular cli v7.
I had a similar situation happen to me while trying to code parameterized animations. Writing a function that returns the animation object is the intuitive thing to do, and after the error you would think storing the return in a constant and passing that to the decorator would work, but it doesn't with AOT. The reason has to do with the ordem of the compilation, so to speak. The AOT compiler will resolve metadata first, and it wont deal with function calls at all, so even if you try to resolve it outside of the decorator, it's all the same.
So what you should do is export the trigger(...) object as a constant and use the animation option params to do all necessary configurations, like you did with the side parameter in your example.
I can't really help you with much more, as you didn't share the part of the code actually triggering the error, the chooseAnimation method, but you should be able to get the idea behind it, as you already know how to use the options.
I had the same problem, so I'm just expanding on the answer by #Henrique Erzinger, which helped me solve it.
All you need to do is make sure there are no user-defined parameters in an animation function - in other words, all the parameters are (so to say) hardcoded.
Your function fadeIn, for example, can be called from the decorator by using animations: [fadeIn()] in the decorator, but the function definition itself cannot take any parameters.
// this WILL work
export function fadeIn(): AnimationTriggerMetadata {
return trigger('fadeIn', [
transition(':enter', [
// only static code, no variables allowed ...
])
]);
}
// this will NOT work
export function fadeIn(time = 300): AnimationTriggerMetadata {
return trigger('fadeIn', [
transition(':enter', [
group([
animate(time + 'ms' .... // NOT allowed
])
]);
}
I am trying to do a simple transition using angular 5. The transition itself is working but when I try to adjust the ease-in / ease out period of the transition. My setup is based off of the angular documentation, so I am really at loss as to why the transition time isn't changing.
component.ts
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
animations: [
trigger('homeState', [
state('hide', style({
backgroundColor: '#eee',
transform: 'translateX(0%)'
})),
state('show', style({
backgroundColor: '#cfd8dc',
transform: 'translateX(100%)'
})),
transition('show => hide', animate('6000ms ease-out')),
transition('hide => show', animate('1000ms ease-in'))
])
]
})
component.html
<h1 [#homeState]="stateName">{{title}}</h1>
<button (click)="toggle()"></button>
The toggle function changes between the show and hide states. Can someone please point me in the right direction? thanks.
UPDATE:
Okay, so I have done some more digging. I downloaded the source code of the animations. The source code has the easing effect working. So i copied that code over to my project and still the ease effect is not working. But when I copied my original code over to the animations project everything works.
Your global Angular CLI version (1.7.4) is greater than your local
version (1.6.5). The local Angular CLI version is used.
Okay, I finally figured it out. I had the noop testing module as well as the regular angular animations in my file (this is my fault, I copied someone else's setup without fully understanding what I was doing). The noop is a no operation module used solely for testing.
more info:
What's the difference between BrowserAnimationsModule and NoopAnimationsModule?
Once I removed this from my app.module.ts all was good:
import { NoopAnimationsModule } from '#angular/platform-browser/animations';
I hope this helps someone down the road.
I'm trying to trigger an animation on an hidden element of a child component. To be simple, the animation should occur when the element appears, and then each time a user click on a button from the parent component.
Here is simple code :
(tried to plunkr it, but impossible to import trigger component from angular core)
app.ts
import {ChildComponent} from './child';
#Component({
selector: 'my-app',
template: `
<button id="showChildButton" (click)="setShowChild()">Show Child</button>
<button id="triggerAnimation">Trigger animation</button>
<child-component *ngIf="showChild"></child-component>
`
.....
})
export class App {
showChild: boolean = false;
setShowChild() {
this.showChild = true;
}
}
child.ts
import {
Component,
trigger,
state,
style,
transition,
animate
} from '#angular/core'
#Component({
selector: 'child-component',
template: `<h1 [#inflateIn]>Hello</h1>`,
animations: [
trigger('inflateIn', [
transition('void => *', [
animate(100, style({ transform: 'scale(1.1)'}))
]),
transition('* => *', [
animate(100, style({ transform: 'scale(1.1)'}))
])
])
]
})
export class ChildComponent {
}
I am able to animate the , the first time it appears, but I can't figure out how to trigger this animation again, when clicking on button #triggerAnimation of the parent component.
I searched for examples but I didn't find anything that solve my case.
Thanks for your help
You have to toggle the showChild variable. You can change your setShowChild() method as follows
setShowChild() {
this.showChild === false ? true : false;
}
It checks if this.showChild is false so make it true otherwise false to hide it again.
I hope this is what you wanted to get the desired result?
I'm still new to Angular 2 and was wondering if there is a way to let a component 'fly in' and let another component 'fly out' when switching routes. Let's say I have 2 components: Test1Component and Test2Component and 2 routes pointing to each of them. What would be the best way to do it?
https://github.com/angular/angular/issues/9845#issuecomment-235799008
RC5 will hopefully be out this week, if not then next week.
For now (with RC5) you will need to do this for every component that
is routed to and you want to add animations to:
#Component({
host: {
'[#routeAnimation]': 'true'
},
animations: [
trigger('routeAnimation', [
transition('* => void', animate(...)),
transition('void => *', animate(...))
])
]
})
class Cmp { }
Once we get query() and $variables into animations then you can use
<router-outlet> with the URL API that I wrote above.
I've been trying to use the arbor layout. I've tried
layout: {
name:"arbor"
}
and
layout: {
name:"arbor",
liveUpdate: true,
ready: undefined,
maxSimulationTime: 4000,
fit: true,
padding: [ 50, 50, 50, 50 ],
ungrabifyWhileSimulating: true,
repulsion: undefined,
stiffness: undefined,
friction: undefined,
gravity: true,
fps: undefined,
precision: undefined,
nodeMass: undefined,
edgeLength: undefined,
stepSize: 1,
stableEnergy: function( energy ){
var e = energy;
return (e.max <= 7) || (e.mean <= 5);
}
}
In both cases the firebug console reports
arbor is not defined
http://localhost/WS/BioJS/biojs/src/main/resources/dependencies/cytoscape/jquery.cytoscapeweb.layout.arbor.js
Line 76
I'm I missing something?
is there a working example of the arbor layout usage?
You need to include arbor.js in a script tag in your HTML. The file jquery.cytoscapeweb.layout.arbor.js just interfaces arbor with Cytoscape Web. Make sure you use the version of arbor.js bundled in the Cytoscape Web ZIP if you need IE support -- arbor doesn't provide this out of the box.
The reason why arbor.js isn't embedded in jquery.cytoscapeweb.layout.arbor.js is because arbor.js needs to be in its own script tag in order for web workers to work properly. If you concatenate and minify arbor.js with your app's other scripts, arbor's path finding can break or arbor's webworkers could conflict with other webworkers in your app.