Angular 2 "slide in animation" 个路由组件
Angular 2 "slide in animation" of a routed component
假设我在固定导航栏中有 2 个路由组件和两个 Routerlinks 来路由它们。我希望它们在我单击 Routerlinks 时从右侧滑入。
我不想用 css 偏移组件并使用超时函数更改 css class 让它滑入(例如使用 ngStyle 或 ngClass) .
在 Angular 2 中是否有更优雅的方法来实现这一点?
谢谢!
在滑动方面还是比较直接的
可以参考Official Angular 2 Animate docs.
您也可以查看这个 Plunker 我用新路由器 v3 做了一个简单的展示
请记住,当触发的元素即将从视图中销毁时,我正在努力弄清楚如何实际进行 leave/exit/void 转换。
我在 Angular 2 Animate - No visible effect of the '* => void' transition when changing routes/components 中打开了另一个线程,试图弄清楚如何让路由器注意到离开的 animation/transition 时间。
@Component({
selector: 'home',
directives: [ROUTER_DIRECTIVES],
template: `
<div @flyInOut="'active'" class="radibre">
</div>
`,
styles: ['.radibre { width: 200px; height: 100px; background: red; }'],
animations: [
trigger('flyInOut', [
state('in', style({transform: 'translateX(0)'})),
transition('void => *', [
style({transform: 'translateX(-100%)'}),
animate(100)
]),
transition('* => void', [
animate(100, style({transform: 'translateX(100%)'}))
])
])
]
})
export class Home {
constructor() { }
}
@Component({
selector: 'page',
template: `
<div @testingBottom="'active'" class="page"></div>`,
styles: ['.page { width: 300px; height: 50px; background: green; }'],
animations: [
trigger('testingBottom', [
state('active', style({transform: 'scale(1)'})),
transition('void => *', [
style({transform: 'scale(0)'}),
animate(100)
]),
transition('* => void', [
animate(100, style({transform: 'scale(0)'}))
])
])
]
})
使用 Angular 4.1 现在可以创建特定的路线动画。这与显示组件时触发动画不同,因为它可以让您同时为 entering/leaving 组件设置动画以实现平滑过渡,并让您根据哪个组件即将到来或即将离开来修改过渡。这意味着您可以执行复杂的转换,例如,如果您向下钻取内容,则从右侧滑入一个组件;如果您通过另一个组件的 'back' 按钮进入,则从左侧滑入。
首先,像这样注释您的路由器插座(例如app.component.html
):
<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)">
<router-outlet #outlet="outlet"></router-outlet>
</div>
在对应的组件定义中实现prepareRouteTransition(outlet)
函数(如app.component.js
)
prepareRouteTransition(outlet) {
const animation = outlet.activatedRouteData['animation'] || {};
return animation['value'] || null;
}
定义动画(例如 app.component.js
):
const slideLeft = [
query(':leave', style({ position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' }), {optional:true}),
query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' }), {optional:true}),
group([
query(':leave', group([
animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(100%,0,0)' })), // y: '-100%'
]), {optional:true}),
query(':enter', group([
animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })),
]), {optional:true})
])
]
const slideRight = [
query(':leave', style({ position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'}), {optional:true}),
query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'}), {optional:true}),
group([
query(':leave', group([
animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(-100%,0,0)' })), // y: '-100%'
]), {optional:true}),
query(':enter', group([
animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })),
]), {optional:true})
])
]
将动画元数据添加到您的路由定义中(例如 app.routing.ts
):
const routes: Routes = [
{
path: 'products',
component: ProductsComponent,
data: {
animation: {
value: 'products',
}
}
},
{
path: 'products/:id',
component: ProductDetailComponent,
data: {
animation: {
value: 'product-detail',
}
}
}
最后,使用您定义的动画和路由元数据(例如 app.component.js
)在您的组件上注册一个 'routerAnimations' 动画触发器:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('routerAnimations', [
transition('products => product-detail', slideRight),
transition('product-detail => products', slideLeft),
])
]
})
不要忘记填充 Web 动画 API 以针对旧浏览器
Matias Niemela 在 ng-conf 上详细讨论了路由动画(带演示):https://youtu.be/Oh9wj-1p2BM?t=12m21s
假设我在固定导航栏中有 2 个路由组件和两个 Routerlinks 来路由它们。我希望它们在我单击 Routerlinks 时从右侧滑入。
我不想用 css 偏移组件并使用超时函数更改 css class 让它滑入(例如使用 ngStyle 或 ngClass) .
在 Angular 2 中是否有更优雅的方法来实现这一点?
谢谢!
在滑动方面还是比较直接的
可以参考Official Angular 2 Animate docs.
您也可以查看这个 Plunker 我用新路由器 v3 做了一个简单的展示
请记住,当触发的元素即将从视图中销毁时,我正在努力弄清楚如何实际进行 leave/exit/void 转换。
我在 Angular 2 Animate - No visible effect of the '* => void' transition when changing routes/components 中打开了另一个线程,试图弄清楚如何让路由器注意到离开的 animation/transition 时间。
@Component({
selector: 'home',
directives: [ROUTER_DIRECTIVES],
template: `
<div @flyInOut="'active'" class="radibre">
</div>
`,
styles: ['.radibre { width: 200px; height: 100px; background: red; }'],
animations: [
trigger('flyInOut', [
state('in', style({transform: 'translateX(0)'})),
transition('void => *', [
style({transform: 'translateX(-100%)'}),
animate(100)
]),
transition('* => void', [
animate(100, style({transform: 'translateX(100%)'}))
])
])
]
})
export class Home {
constructor() { }
}
@Component({
selector: 'page',
template: `
<div @testingBottom="'active'" class="page"></div>`,
styles: ['.page { width: 300px; height: 50px; background: green; }'],
animations: [
trigger('testingBottom', [
state('active', style({transform: 'scale(1)'})),
transition('void => *', [
style({transform: 'scale(0)'}),
animate(100)
]),
transition('* => void', [
animate(100, style({transform: 'scale(0)'}))
])
])
]
})
使用 Angular 4.1 现在可以创建特定的路线动画。这与显示组件时触发动画不同,因为它可以让您同时为 entering/leaving 组件设置动画以实现平滑过渡,并让您根据哪个组件即将到来或即将离开来修改过渡。这意味着您可以执行复杂的转换,例如,如果您向下钻取内容,则从右侧滑入一个组件;如果您通过另一个组件的 'back' 按钮进入,则从左侧滑入。
首先,像这样注释您的路由器插座(例如
app.component.html
):<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)"> <router-outlet #outlet="outlet"></router-outlet> </div>
在对应的组件定义中实现
prepareRouteTransition(outlet)
函数(如app.component.js
)prepareRouteTransition(outlet) { const animation = outlet.activatedRouteData['animation'] || {}; return animation['value'] || null; }
定义动画(例如
app.component.js
):const slideLeft = [ query(':leave', style({ position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' }), {optional:true}), query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' }), {optional:true}), group([ query(':leave', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(100%,0,0)' })), // y: '-100%' ]), {optional:true}), query(':enter', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })), ]), {optional:true}) ]) ] const slideRight = [ query(':leave', style({ position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'}), {optional:true}), query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'}), {optional:true}), group([ query(':leave', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(-100%,0,0)' })), // y: '-100%' ]), {optional:true}), query(':enter', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })), ]), {optional:true}) ]) ]
将动画元数据添加到您的路由定义中(例如
app.routing.ts
):const routes: Routes = [ { path: 'products', component: ProductsComponent, data: { animation: { value: 'products', } } }, { path: 'products/:id', component: ProductDetailComponent, data: { animation: { value: 'product-detail', } } }
最后,使用您定义的动画和路由元数据(例如
app.component.js
)在您的组件上注册一个 'routerAnimations' 动画触发器:@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], animations: [ trigger('routerAnimations', [ transition('products => product-detail', slideRight), transition('product-detail => products', slideLeft), ]) ] })
不要忘记填充 Web 动画 API 以针对旧浏览器
Matias Niemela 在 ng-conf 上详细讨论了路由动画(带演示):https://youtu.be/Oh9wj-1p2BM?t=12m21s