You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何用Angular Animations实现Twitter风格点赞按钮

用Angular Animations实现Twitter风格点赞按钮

当然可以实现,我自己在项目里就用Angular Animations做过几乎一模一样的Twitter风格点赞按钮,完全不需要依赖任何外部包,核心实现思路和代码如下:

核心实现思路

  • 借助Angular的@angular/animations模块管理两种状态:未点赞(默认)和已点赞(激活)
  • 动画包含三个核心细节:
    • 爱心颜色的平滑过渡
    • 点赞瞬间的缩放脉冲效果
    • 可选的粒子扩散动画(还原Twitter原版的细节)

完整代码实现

组件TS代码

import { Component } from '@angular/core';
import { trigger, state, style, transition, animate, keyframes } from '@angular/animations';

@Component({
  selector: 'app-twitter-like',
  templateUrl: './twitter-like.component.html',
  styleUrls: ['./twitter-like.component.scss'],
  animations: [
    // 爱心状态动画
    trigger('likeState', [
      state('inactive', style({
        color: '#6e767d',
        transform: 'scale(1)'
      })),
      state('active', style({
        color: '#f91880',
        transform: 'scale(1)'
      })),
      // 点赞动画:缩小→放大→恢复
      transition('inactive => active', [
        animate('300ms ease-out', keyframes([
          style({ transform: 'scale(0.8)', offset: 0.1 }),
          style({ transform: 'scale(1.2)', offset: 0.5 }),
          style({ transform: 'scale(1)', offset: 1 })
        ]))
      ]),
      // 取消点赞:平滑变灰
      transition('active => inactive', [
        animate('200ms ease-in')
      ])
    ]),
    // 粒子扩散动画(可选,更贴近原版)
    trigger('particles', [
      state('hidden', style({ opacity: 0, transform: 'scale(0) translate(0,0)' })),
      state('visible', style({ opacity: 0, transform: 'scale(1.5) translate(var(--tx), var(--ty))' })),
      transition('hidden => visible', animate('600ms ease-out'))
    ])
  ]
})
export class TwitterLikeComponent {
  isLiked = false;
  particles = Array(8).fill(null); // 生成8个扩散粒子

  toggleLike() {
    this.isLiked = !this.isLiked;
    // 点赞时重置粒子数组,触发动画
    if (this.isLiked) {
      setTimeout(() => {
        this.particles = [...this.particles];
      }, 10);
    }
  }

  // 计算粒子的扩散偏移量
  getParticleOffset(index: number, axis: 'x' | 'y'): string {
    // 8个方向的角度
    const angles = [0, 45, 90, 135, 180, 225, 270, 315];
    const angle = angles[index] * Math.PI / 180;
    const distance = 12 + Math.random() * 8; // 随机扩散距离
    return axis === 'x' ? `${Math.cos(angle) * distance}px` : `${Math.sin(angle) * distance}px`;
  }
}

组件模板(HTML)

<button class="like-btn" (click)="toggleLike()" [@likeState]="isLiked ? 'active' : 'inactive'">
  <!-- 爱心SVG图标(也可以用Font Awesome等字体图标) -->
  <svg class="heart-icon" viewBox="0 0 24 24">
    <path d="M12 21.638h-.014C9.403 21.59 1.95 14.856 1.95 8.478c0-3.064 2.525-5.754 5.403-5.754 2.29 0 3.83 1.58 4.646 2.73.814-1.148 2.354-2.73 4.645-2.73 2.88 0 5.404 2.69 5.404 5.755 0 6.375-7.454 13.11-10.037 13.157Z" />
  </svg>
  <!-- 扩散粒子 -->
  <ng-container *ngFor="let _ of particles; let i = index">
    <span class="particle" 
          [@particles]="isLiked ? 'visible' : 'hidden'"
          [style.--tx]="getParticleOffset(i, 'x')"
          [style.--ty]="getParticleOffset(i, 'y')">
    </span>
  </ng-container>
</button>

组件样式(SCSS)

.like-btn {
  background: transparent;
  border: none;
  cursor: pointer;
  position: relative;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease;

  &:active {
    transform: scale(0.95);
  }

  .heart-icon {
    width: 24px;
    height: 24px;
    fill: currentColor;
    pointer-events: none;
  }

  .particle {
    position: absolute;
    width: 4px;
    height: 4px;
    background-color: #f91880;
    border-radius: 50%;
    opacity: 0;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
  }
}

效果说明

  • 点击按钮时,爱心会先快速缩小到0.8倍,再放大到1.2倍,最后恢复原大小,同时颜色从灰色平滑过渡到Twitter的粉红色
  • 开启粒子动画后,点赞瞬间会从爱心中心向8个随机方向飞出小粒子,完全复刻原版动效
  • 取消点赞时,爱心会平滑变回灰色,无额外动画,保持交互简洁

内容的提问来源于stack exchange,提问作者Ali Celebi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:25:09