简体   繁体   中英

Random animations in Angular

Consider the following code:

<div class="red-square" 
     *ngIf="someCondition"
     [@showHideAnimation]
></div>

Is there a way to cause aforementioned div to disappear with random animation ?

Random animation being, for example, rotation of the object by any number of degrees between, say, 30 and 150.

I have an idea, but it's not randomized per se .

given your animation

animations: [
  trigger('animationName', [
    state('void', style({
      // hidden case
    })),
    state('*', style({
      // visible case
    })),
    transition(':enter', animate('TIME [DELAY] EASING')),
    transition(':leave', animate('TIME [DELAY] EASING'))
  ])
]

What you could do is make a global function like so

function randomizeAnimation(propertiesNumber: number, state: number) {
  let properties = ['borderBottom', 'opacity', 'All of the properties you want to animate here'];
  let randomIndex = () => Math.random() * properties.length;

  let style = {};
  for (let i = 0; i < propertiesNumber; i++) {
    let index = randomIndex();
    let voidValue = '0';
    let showValue = '*';
    // Why it's not "randomized" : you need to make custom rules here. Example : colors
    if (properties[index].toLowerCase().includes('color')) { 
      let RdmOct = () => Math.random() * 256;
      let generateRandomColor = () => `rgb(${RdmOct()}, ${RdmOct()}, ${RdmOct()})`;
      voidValue = generateRandomColor();
      showValue = generateRandomColor();
    }
    style[properties[index]] = state ? voidValue : showValue;
  }
  return style;
}

What this function does is that it takes a number of properties to animate, and an animation state (boolean, or 0/1). It then choses random properties in its array, making it "random". If the properties have a special use case, such as colors (the wildcard '*' won't work), then you have to handle it. Once it has created the random style, it returns it to be used in the animate function. It's not "randomized" like a Math.random(), but it could do the trick !

In your component, you can now call this function in your animate :

animations: [
  trigger('animationName', [
    state('void', style(randomizeAnimation(1, 0))),
    state('void', style(randomizeAnimation(1, 1))),
    transition(':enter', animate('275ms ease-out')),
    transition(':leave', animate('275ms ease-in'))
  ])
]

I'm not sure it would work, but that's close enought for your need I guess !

EDIT you could even go further by setting an Interval in your animate, changing the animation every minute or so. But if this method doesn't even work ... I won't lose more time to write this one ahah

For animations with random values you will need to create animations that accept parameters. This will allow you to provide different values in the animation so that you can get random behavior. You will need to setup one or more animations depending on what you want to animate and set parameters on the values like so:

animations: [
    trigger('randomAnimation', [
        transition('* => colorFade', [
            animate("500ms ease-in", keyframes([
                style({'background-color': "{{color}}"}),
                style({'opacity': "{{opacity}}"}),
            ]))
        ], {params : { color: "yellow", opacity: "0" }}),
        transition('rotateFade', [
            animate("{{time}}ms ease-in", keyframes([
                style({'transform': 'rotate({{rotate}}deg);'}),
                style({'opacity': "{{opacity}}"}),
            ]))
        ], {params : { time: "500", rotate: "45", opacity: "0.6 }})
    ])
]

And then in the view you can bind the animation to an animation object that has the random values in it.

<div class="red-square" [@randomAnimation]="animationConfig"></div>

And in your component you can create the object that will make the animation random.

public setRandomAnimation() {
    this.animationConfig = {
        value: Math.random() > 0.5 ? 'colorFade' : 'rotateFade',
        params: {
            time: Math.floor(Math.random() * 5000) + 200,
            color: `#${(Math.floor(Math.random() * 255)).toString(16)}${(Math.floor(Math.random() * 255)).toString(16)}${(Math.floor(Math.random() * 255)).toString(16)}`,
            opacity: Math.random(),
            rotate: Math.floor(Math.random() * 360),
    };
}

The above method is just an example you could expand this much further and not cram it all into one method. The parameters that are not used by the animation will be ignored so it is okay to specify rotate even though it is not used in colorFade for example.

PREVIOUS ANSWER

You can define any number of animation states and then set up transitions so that when they go from any state to a specific state a certain animation will occur. Here is an example of what the animation states might look like:

animations: [
  trigger('randomAnimation', [
    transition('* => yellowDisappear', [
      animate(300, keyframes([
        style({'background-color': 'yellow'}),
        style({opacity: 0})
      ])),
    transition('* => rotateFade', [
      animate(300, keyframes([
        style({'transform': 'rotate(45deg);'}),
        style({opacity: 0.6})
      ]))
  ])
]

You can then specify the animation that you want to apply in the template.

<div class="red-square" [@randomAnimation]="'yellowDisappear'"></div>
<div class="red-square" [@randomAnimation]="'rotateFade'"></div>

If you want to have it occur randomly I would set up some kind of Observable that would change the animation randomly and if you want it to occur on certain conditions then I would make a method in the component to set the current state of the animation based on certain conditions.

Animations in Angular are a little tricky but there is good information in the tutorial and Matias Niemelä (one of the lead developers of the Angular animation module) wrote a good article on it as well. I would recommend checking these out if your project is going to make use of animations

I'm not sure if this will work, but you can add a state to the animated div like so:

<div class="red-square" 
     *ngIf="someCondition"
     [@showHideAnimation]="getRandomState()"
></div>

The getRandomState method can return a couple of predefined strings randomly.

Next you only need to create transitions for each of these strings to void , for example:

transition('yellowFirstState => void',[
  style({'background-color':'yellow'}),
  animate(100)
])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM