【问题标题】:Random animations in AngularAngular 中的随机动画
【发布时间】:2017-11-09 13:52:35
【问题描述】:

考虑以下代码:

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

有没有办法让上述 div 随随机动画消失

随机动画是,例如,对象旋转 任意度数,例如 30 到 150。

【问题讨论】:

    标签: javascript angular animation angular-animations angular5


    【解决方案1】:

    我有一个想法,但它不是随机的本身

    鉴于你的动画

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

    你可以做一个像这样的全局函数

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

    这个函数的作用是它需要一些属性来制作动画,以及一个动画状态(布尔值,或 0/1)。然后它在其数组中选择随机属性,使其“随机”。如果属性有特殊用例,例如颜色(通配符 '*' 不起作用),那么您必须处理它。一旦它创建了随机样式,它就会返回它以在动画函数中使用。它不像 Math.random() 那样“随机化”,但它可以解决问题!

    在你的组件中,你现在可以在你的动画中调用这个函数:

    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'))
      ])
    ]
    

    我不确定它会起作用,但我猜这已经足够满足您的需要了!

    编辑你甚至可以在你的动画中设置一个间隔,每分钟左右改变一次动画。但是如果这个方法甚至不起作用......我不会浪费更多时间来写这个啊啊啊

    【讨论】:

    • 好主意。我对其进行了测试,一旦为元素生成了特定的动画,它就会具有相同的动画,直到应用程序被刷新。不是我想要的,但非常接近。
    • 很高兴知道它有效!您是否尝试过超时?
    • 尝试使用 setInterval 每 500 毫秒更改一次动画,但没有成功
    • 你把间隔放在哪里了?进入函数,还是在函数调用处?另外,也许您应该先销毁组件,这意味着转到另一个页面并返回。但同样,这只是我的假设,我什至从未尝试过。
    • 我创建了一个变量,并每隔 500 毫秒为其分配新样式,同时将其提供给组件元数据中的动画部分。我希望这是有道理的。您的另一个想法,即销毁和重新创建组件可能实际上可行,但尚未测试。
    【解决方案2】:

    对于具有随机值的动画,您需要创建接受参数的动画。这将允许您在动画中提供不同的值,以便获得随机行为。您将需要根据要设置动画的内容设置一个或多个动画,并在值上设置参数,如下所示:

    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 }})
        ])
    ]
    

    然后在视图中,您可以将动画绑定到其中包含随机值的动画对象。

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

    在您的组件中,您可以创建使动画随机化的对象。

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

    上述方法只是一个示例,您可以进一步扩展它,而不是将其全部塞进一个方法中。动画未使用的参数将被忽略,因此可以指定rotate,即使它没有在colorFade 中使用。

    以前的答案

    您可以定义任意数量的动画状态,然后设置转换,以便当它们从任何状态转到特定状态时,会出现特定的动画。以下是动画状态的示例:

    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})
          ]))
      ])
    ]
    

    然后您可以指定要在模板中应用的动画。

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

    如果你想让它随机发生,我会设置某种 Observable 来随机改变动画,如果你想让它在某些条件下发生,那么我会在组件中创建一个方法来设置当前状态基于特定条件的动画。

    Angular 中的动画有点棘手,但 tutorial 中有很好的信息,而且 Matias Niemelä(Angular 动画模块的主要开发人员之一)也写了一篇很好的 article。如果您的项目要使用动画,我建议您查看这些

    【讨论】:

    • 这种方法的问题是动画状态的数量是有限。例如,我想要实现的是“将正方形随机旋转 30 到 150 度”。
    【解决方案3】:

    我不确定这是否可行,但您可以像这样向动画 div 添加状态:

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

    getRandomState 方法可以随机返回几个预定义的字符串。

    接下来您只需为这些字符串中的每一个创建到void 的转换,例如:

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

    【讨论】:

    • 可以手动定义的状态就这么多,有限
    • 是的,这是真的。可悲的是,我不知道如何让它变得无限和动态。 trichetriche 的解决方案可能是您将得到的最接近的解决方案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    相关资源
    最近更新 更多