因此,从我能告诉的所有内容来看,这应该是有效的……但事实并非如此……
我试图让父级(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;
}
答案 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