Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Angular LAB:动画列表并使用 AnimationBuilder 实现命令式动画_创想鸟

Angular LAB:动画列表并使用 AnimationBuilder 实现命令式动画

angular lab:动画列表并使用 animationbuilder 实现命令式动画

您知道 angular 包含一个复杂的动画系统吗?当我想要在元素进入屏幕或被破坏时为其设置动画时,我发现它特别有用!

此外,您还可以使用 animationbuilder 来强制播放、暂停或停止一些自定义动画!让我们看看它是如何完成的。

创建列表

在本练习中,我们首先创建一个列表,如下所示:

@component({  selector: 'app-root',  standalone: true,  template: `        
    @for (user of users(); track user.id) {
  • {{ user.name }}
  • }
`,})export class appcomponent { users = signal([ { id: math.random(), name: 'michele' } ]); adduser() { this.users.update(users => [...users, { id: math.random(), name: 'new user' }]); }}

请注意,我们添加了一个将用户添加到列表中的按钮!

动画列表

现在,如果我们想要为要添加的新用户设置动画该怎么办?首先,我们想通过在主配置中提供它来告诉 angular 我们想要使用它的动画系统:

import { provideanimationsasync } from '@angular/platform-browser/animations/async';bootstrapapplication(appcomponent, {  providers: [    provideanimationsasync(),  ]});

然后,我们可以创建我们的动画:

import { trigger, transition, style, animate } from '@angular/animations';const fadeinanimation = trigger('fadein', [  transition(':enter', [    style({ transform: 'scale(0.5)', opacity: 0 }),    animate(      '.3s cubic-bezier(.8, -0.6, 0.2, 1.5)',       style({ transform: 'scale(1)', opacity: 1 })    )  ])])

有了这些帮助者,我们:

创建了一个名为 fadein 的动画触发器添加了元素进入屏幕时的过渡应用了初始样式立即开始动画,这将导致新的样式应用于元素

更多关于如何编写动画的信息,可以参考官方指南,非常棒!

现在让我们将此动画应用到列表中的每个元素:

@component({  ...,  template: `        
    @for (user of users(); track user.id) {
  • {{ user.name }}
  • }
`, // also, add the animation to the metadata of the component animations: [fadeinanimation]})

现在,当添加新项目时,它会变得动画!我们的第一步已经完成。

请注意,为了让我们的动画正常工作,angular 必须跟踪 for 中的每个元素,因为否则它最终可能会在更新模板时重新创建相同的元素,从而导致不必要的结果动画。这是免费的新控制流语法,因为 track 属性是强制性的,但如果您使用旧版本的 angular 和 *ngfor 指令,则必须使用 trackby 选项,如下所示:

  • {{ user.name }}
  • // a class method in your component:trackbyuserid(index, user: user) {  return user.id;}

    现在,让我们向列表中添加另一种类型的动画。

    动画生成器

    让我们为列表的每个元素添加一个按钮:

  • {{ user.name }}
  • 想象一下:我们想让元素在按下按钮时闪烁。那就太酷了!这就是 animationbuilder 服务的用武之地。

    首先,让我们创建一个将应用于每个元素的指令。在此指令中,我们将注入 elementref 和 a​​nimationbuilder:

    import { animationbuilder, style, animate } from '@angular/animations';@directive({  selector: '[blink]',  exportas: 'blink', // <--- notice  standalone: true})export class blinkdirective {  private animationbuilder = inject(animationbuilder);  private el = inject(elementref);}

    请注意,我们导出了指令:我们将在几秒钟内找到原因。

    然后,我们可以创建一个像这样的自定义动画:

    export class blinkdirective {  ...  private animation = this.animationbuilder.build([    style({ transform: 'scale(1)', opacity: 1 }),    animate(150, style({ transform: 'scale(1.1)', opacity: .5 })),    animate(150, style({ transform: 'scale(1)', opacity: 1 }))  ]);}

    我们使用的函数与之前的动画中使用的函数相同,只是样式不同。

    现在我们要创建一个播放器,它将在我们的元素上执行动画:

    export class blinkdirective {  ...  private player = this.animation.create(this.el.nativeelement);}

    现在让我们公开一个真正启动动画的方法!

    export class blinkdirective {  ...  start() {    this.player.play();  }}

    只剩下一步了:我们必须导入指令,将其应用到我们的元素,使用模板变量获取它,并在按下按钮时调用该方法!

    @component({  selector: 'app-root',  standalone: true,  template: `        
      @for (user of users(); track user.id) {
    • {{ user.name }}
    • }
    `, imports: [blinkdirective], animations: [ fadeinanimation ]})

    我们可以获取指令的实例并将其放入局部变量中,因为我们之前使用exportas导出了指令。这就是关键部分!

    现在,尝试单击按钮:该元素将正确设置动画!

    练习已经完成,但这只是冰山一角! animationplayer 有很多命令可用于停止、暂停和恢复动画。非常酷!

    interface animationplayer {  ondone(fn: () => void): void;  onstart(fn: () => void): void;  ondestroy(fn: () => void): void;  init(): void;  hasstarted(): boolean;  play(): void;  pause(): void;  restart(): void;  finish(): void;  destroy(): void;  reset(): void;  setposition(position: number): void;  getposition(): number;  parentplayer: animationplayer;  readonly totaltime: number;  beforedestroy?: () => any;}

    如果您想使用它,这是我们的完整示例:只需将其放入 main.ts 文件中并查看它的实际效果!

    import { Component, signal, Directive, ElementRef, inject } from '@angular/core';import { bootstrapApplication } from '@angular/platform-browser';import { trigger, transition, style, animate, AnimationBuilder } from '@angular/animations';import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';interface User {  id: number;  name: string;}@Directive({  selector: '[blink]',  exportAs: 'blink',  standalone: true})export class BlinkDirective {  private animationBuilder = inject(AnimationBuilder);  private el = inject(ElementRef);  private animation = this.animationBuilder.build([    style({ transform: 'scale(1)', opacity: 1 }),    animate(150, style({ transform: 'scale(1.1)', opacity: .5 })),    animate(150, style({ transform: 'scale(1)', opacity: 1 }))  ]);  private player = this.animation.create(this.el.nativeElement);  start() {    this.player.play();  }}const fadeInAnimation = trigger('fadeIn', [  transition(':enter', [    style({ transform: 'scale(0.5)', opacity: 0 }),    animate(      '.3s cubic-bezier(.8, -0.6, 0.2, 1.5)',       style({ transform: 'scale(1)', opacity: 1 })    )  ])])@Component({  selector: 'app-root',  standalone: true,  template: `        
      @for (user of users(); track user.id) {
    • {{ user.name }}
    • }
    `, imports: [BlinkDirective], animations: [ fadeInAnimation ]})export class App { users = signal([ { id: Math.random(), name: 'Michele' } ]); addUser() { this.users.update(users => [...users, { id: Math.random(), name: 'New user' }]); }}bootstrapApplication(App, { providers: [ provideAnimationsAsync() ]});

    以上就是Angular LAB:动画列表并使用 AnimationBuilder 实现命令式动画的详细内容,更多请关注创想鸟其它相关文章!

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
    发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1493125.html

    赞 (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    React Native 入门 (EXPO):初学者指南
    上一篇 2025年12月19日 15:25:32
    了解如何建立实时聊天
    下一篇 2025年12月19日 15:25:40

    相关推荐

    • 编译CEGUI「建议收藏」

      大家好,很高兴再次与你们见面,我是你们的老朋友全栈君。 平台: Windows 7 / 64位 / VS2005 CEGUI下载 地址:https://www.php.cn/link/9a2327a2fcc570914ce9c9e61581cbf8 源码选择: CEGUI 0.7.9 库源码下载 这…

      2026年9月21日
      000
    • 大数据量下的批量导入/导出优化

      在大数据环境下优化批量导入/导出的方法包括:1. 使用批处理技术分批导入/导出数据,减少系统资源压力;2. 采用数据流技术如apache kafka进行实时处理,降低内存占用;3. 利用并行处理技术分配任务到多个处理器或节点,提高处理速度;4. 通过性能监控和调优识别并解决瓶颈点,以提升整体效率。 …

      2026年9月21日
      300
    • Yii调试面板(Debug Toolbar)的高级用法

      yii框架的调试面板除了基本功能外,还能提供性能分析、数据库查询分析、邮件发送记录等高级用法。1.性能分析功能可识别代码瓶颈,优化应用速度。2.数据库查询分析工具显示sql查询及执行时间,优化数据库操作。3.邮件发送记录功能帮助排查邮件发送问题。合理使用这些功能能大幅提升应用性能和用户体验。 让我们…

      2026年9月20日
      000
    • 如何在Laravel中管理环境变量

      在laravel中管理环境变量的核心在于利用.env文件和config配置系统。具体来说,1. 使用.env文件存储环境变量,如数据库连接信息、api密钥等;2. 通过laravel的配置文件(如config/database.php)读取.env中的值,并使用config()函数获取配置;3. 在…

      2026年9月20日
      000
    • 如何在Laravel中使用宏指令

      宏指令在laravel中是一种运行时动态扩展类功能的机制。1. 它通过调用类的macro静态方法,传入名称和闭包来实现;2. 常用于给str、request、response、builder等核心类添加便捷方法;3. 与继承和特性不同,宏指令是非侵入性的运行时扩展,适合轻量级工具方法或链式调用场景;…

      2026年9月20日
      000
    • 如何在Laravel中配置路由缓存

      laravel路由缓存通过将路由定义编译为单个php文件来提升性能。1. 它减少了每次请求时解析多个路由文件的开销,适用于生产环境;2. 启用时需先清除旧缓存(php artisan route:clear),再生成新缓存(php artisan route:cache);3. 路由缓存后,修改路由…

      2026年9月13日
      000
    • 如何在Laravel中使用门面模式

      门面模式在laravel中通过静态代理简化了类的访问。其核心实现步骤包括:1. 创建服务提供者并绑定服务到容器;2. 创建继承facade基类并重写getfacadeaccessor方法的门面类;3. 在config/app.php中注册门面别名;4. 通过静态方式调用服务方法。为避免门面导致代码耦…

      2026年9月13日
      100
    • ThinkPHP的分页功能怎么做?ThinkPHP如何实现数据分页?

      ThinkPHP的分页功能怎么做?ThinkPHP如何实现数据分页?ThinkPHP的分页功能怎么做?ThinkPHP如何实现数据分页?ThinkPHP的分页功能怎么做?ThinkPHP如何实现数据分页?ThinkPHP的分页功能怎么做?ThinkPHP如何实现数据分页?

      thinkphp实现分页功能的核心是使用内置的paginate()方法。具体步骤如下:1. 在控制器中通过db门面或模型调用paginate()方法执行分页查询,可结合where、order等链式操作设置查询条件;2. 将分页结果传递到视图层,使用$list->render()渲染分页链接;3…

      2026年9月12日 • 用户投稿
      100
    • YII框架的主题是什么?YII框架如何切换主题?

      yii框架的主题是一种视图层面的分离策略,通过配置view组件的theme属性实现主题切换,需在config/web.php中设置basepath和baseurl;2. 主题目录结构包含views、layouts、assets或web文件夹,用于组织视图、布局和静态资源,形成独立的ui皮肤;3. 常…

      2026年9月12日
      100
    • YII框架的覆盖率测试是什么?YII框架如何检查测试覆盖率?

      代码覆盖率是衡量测试对代码触达程度的指标,在YII框架中通过PHPUnit结合Xdebug或PCOV生成报告,合理配置phpunit.xml可聚焦业务逻辑覆盖,但追求100%覆盖率不现实且易陷入测试误区,应关注核心逻辑的高质量覆盖而非绝对数值。 代码覆盖率测试,简单说,就是衡量你的自动化测试(主要是…

      2026年9月12日
      100
    • YII框架的多租户是什么?YII框架如何支持SaaS?

      答案:Yii框架通过共享数据库加租户ID隔离、独立数据库或Schema等策略实现多租户,结合自定义BaseActiveRecord、查询作用域、行为和事件系统确保数据隔离,利用子域名或路径路由识别租户,并通过RBAC、模块化设计和缓存优化支持SaaS应用的可扩展性与安全性。 YII框架的多租户,简单…

      2026年9月12日
      100
    • VSCode怎么做弹窗_VSCode开发Web弹窗与插件交互功能教程

      答案:VSCode插件通过Webview实现弹窗,需创建WebviewPanel并设置HTML内容,利用onDidReceiveMessage和postMessage实现双向通信,结合CSS框架与图标提升美观性,通过Configuration API或文件系统实现数据持久化,并使用开发者工具调试。 …

      2026年9月11日
      100
    • Laravel模型多态映射?多态映射如何配置?

      Laravel多态映射通过commentable_id和commentable_type字段实现一个模型属于多种父模型,如评论可同时关联文章和视频;在Comment模型中使用morphTo(),在Post和Video模型中使用morphMany(),并通过morphs()方法创建迁移字段;相比传统关…

      2026年9月10日
      100
    • Laravel路由是什么?路由如何定义使用?

      Laravel路由是应用的交通指挥中心,定义URL与代码的映射关系。它通过routes目录下的web.php和api.php文件,使用Route门面将HTTP动词与URL模式关联到控制器或闭包。路由支持参数、中间件、分组、资源路由等特性,贯穿请求生命周期,与中间件、服务容器协作完成请求处理。为管理复…

      2026年9月10日
      100
    • Laravel观察者模式?模型观察者如何使用?

      Laravel模型观察者用于解耦模型生命周期事件处理,通过创建观察者类、定义事件方法(如created、updating)并在AppServiceProvider中注册,实现对模型操作的响应。选择观察者适合处理与模型紧密相关的逻辑,而事件监听器更适合跨模块的解耦场景。saving在保存前执行,可修改…

      2026年9月10日
      100
    • Laravel事件广播?广播事件怎样配置?

      Laravel事件广播的核心优势在于实现服务器端事件的实时推送,提升用户体验。它通过WebSocket等技术将传统请求-响应模式转变为实时流式交互,确保客户端几乎即时接收更新,如聊天消息、订单状态等,避免轮询带来的延迟与资源浪费。该机制增强应用的响应性与互动性,降低服务器负载,同时通过频道授权(如私…

      2026年9月10日
      000
    • Laravel路由缓存?路由缓存如何生成?

      Laravel路由缓存通过将所有路由编译为单一PHP文件,显著提升生产环境性能。执行php artisan route:cache可生成缓存,使每次请求无需重复解析路由文件,大幅减少启动开销。开发环境中应禁用缓存以避免更新延迟,生产部署时则应在发布流程中自动清除旧缓存并生成新缓存,确保路由更新生效。…

      2026年9月10日
      100
    • Laravel门面是什么?门面如何调用方法?

      Laravel门面通过静态语法提供对服务容器中实例的便捷访问,其核心是利用__callStatic()魔术方法将静态调用转发给容器解析出的底层实例。每个门面继承自IlluminateSupportFacadesFacade,并实现getFacadeAccessor()返回服务绑定键名,从而实现服务的…

      2026年9月10日
      100
    • Laravel如何创建和注册服务提供者_框架核心扩展机制

      Laravel服务提供者通过register()绑定服务、boot()引导应用,实现依赖注入与模块化,提升代码可维护性。 Laravel中创建和注册服务提供者,是扩展框架核心功能、实现依赖注入和模块化应用的关键机制。它允许我们将服务的绑定、配置和引导逻辑集中管理,从而让代码更整洁、可维护性更高。 解…

      2026年9月10日
      200
    • Laravel如何实现用户注册和登录_用户身份认证系统实现

      Laravel通过内置认证系统实现用户注册登录,使用Laravel UI或Jetstream生成基础功能,支持自定义逻辑、邮箱验证、第三方登录及路由保护。 直接说吧,Laravel 实现用户注册和登录,核心就在于它内置的身份认证系统。这套系统帮你处理了大部分底层逻辑,让你能更专注于业务层面。 注册和…

      2026年9月10日
      500

    发表回复

    登录后才能评论
    关注微信