如何以角度为父母和孩子制作动画?

时间:2018-09-11 18:15:14

标签: javascript angular typescript animation

因此,从我能告诉的所有内容来看,这应该是有效的……但事实并非如此……

我试图让父级(ui-switch-groove)在颜色之间过渡,而子级(ui-switch-dongle)移动。

按原样使用此代码,可为父级和子级动画化“ false => true”,但仅在执行“ true => false”时动画化子级

有没有一种方法,而无需显式编写父级和子级的关键帧?我以为我可以定义状态样式和时间安排,而其余部分则可以处理(几乎做到了)。如果我注释掉 query(':self'),则加密狗将在两种状态下均正常工作。如果我注释掉 query('@ dongleState'),则凹槽对于两种状态均能正常工作。

我也可以用它来动画化两个部分,一个接一个,但这不是我想要的。

app.component.html

<app-ui-switch name="trueSet" checked="true" text="OFF" alt="ON"></app-ui-switch>

ui-switch.component.ts

@Component({
    inputs: ['checked','text','alt','height','width'],
    outputs: ['checked','state'],
    selector: 'app-ui-switch',
    templateUrl: './ui-switch.component.html',
    styleUrls: ['./ui-switch.component.css'],
    animations: [
        trigger('grooveState', [
            state('inactive',
                style({
                    backgroundColor: 'var(--negative-primary-color)',
                })
            ),
            state('active',
                style({
                    backgroundColor: 'var(--positive-primary-color)',
                })
            ),
            transition('inactive <=> active',[
                group([
                    query(':self', [
                        animate('500ms'),
                    ]),
                    query('@dongleState', [
                        animateChild(),
                    ])
                ])
            ]),
        ]),
        trigger('dongleState', [
            state('inactive',
                style({
                    transform: 'translateX(155px)',
                })
            ),
            state('active',
                style({
                    transform: 'translateX(5px)',
                })
            ),
            transition('inactive <=> active',
                animate('500ms')
            ),

        ]),
    ]
})
export class UiSwitchComponent implements OnInit {
    state : boolean;
    stateString : string;

    @Input() 
    set checked(val){
        this.state = Boolean(val);
        if(val === false || val.toString()==="false" || typeof(val) === "undefined"){
            this.state = false;
        }else{
            this.state = true;
        }
        this.stateString = (this.state===true?"active":"inactive");
        console.log("set value",val,typeof(val),this.state);
    }
    get checked(){
        console.log("get value");
        return this.state;  
    }

    constructor() {
        if (typeof(this.state)==="undefined"){
            this.checked = false;
        }
    }
    ngOnInit() {
    }
    slide(e : Event){
        e.stopPropagation();
        this.checked = !this.state;
        this.onStateChange.emit(this.state);
    }
}

ui-switch.component.html

<div class="ui-switch-wrapper">
    <div class="ui-switch-groove test" (click)="slide($event)" [@grooveState]="stateString">
        <div class="ui-switch-label" (click)="slide($event)">{{ state === true ? text : alt }}</div>
        <div class="ui-switch-dongle" (click)="slide($event)" [@dongleState]="stateString" ></div>
        <input class="ui-switch-input" type="checkbox" [(ngModel)]="state" hidden>
    </div>
</div>

ui-switch.component.css

.ui-switch-wrapper {
  display: inline;
  --positive-primary-color: #5cb85c;
  --positive-secondary-color:#33cc66;
  --negative-primary-color: #FD0011;
  --negative-secondary-color: #f64437;
  --tertiary-color: #DDDDDD;
  --quartenary-color: #FFFFFF;
  --switch-height: 50px;
  --switch-width: 200px;
  --switch-padding: 5px;
}

.ui-switch-groove {
  background-color: var(--positive-primary-color);
  position: relative;
  display: flex;
  height: var(--switch-height);
  width: var(--switch-width);
  vertical-align: middle;
  align-items: center;
  cursor: pointer;
  border-radius: calc( var(--switch-height) / 2);
}

.ui-switch-dongle {
  position: absolute;
  transform: translateX(5px);
  height: 40px;
  width: 40px;
  border-radius: 100%;
  background-color: var(--tertiary-color);
  content: "";
}

.ui-switch-label {
  display: inline;
  position: relative;
  font-size: 28px;
  color: var(--quartenary-color);
  padding-left: calc(var(--switch-height) / 2);
  user-select: none;
  vertical-align: middle;
  margin-left: 5px;
}

1 个答案:

答案 0 :(得分:0)

看起来过渡动画组中的顺序确实很重要。我将其分为两个过渡

        transition('inactive => active',[
            group([
                query(':self', [ animate('500ms') ]),
                query('@dongleState', [ animateChild() ])
            ])
        ]),
        transition('active => inactive',[
            group([
                query('@dongleState', [ animateChild() ]),
                query(':self', [ animate('500ms') ]),
            ])
        ]),

现在它正在按预期工作 https://stackblitz.com/edit/angular-4mzwy8