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

将魔法光标效果的jQuery代码重构为Angular代码

如何在Angular中复刻魔法光标效果

原jQuery实现代码

JavaScript

$(document).ready(function(){
    var coordinateX=0;
    var coordinateY=0;
    var bottomCursor=document.querySelector('.circle-cursor-bottom');
    var topCursor=document.querySelector('.circle-cursor-top');

    function displayCursor(e){
        document.addEventListener('mousemove',e=>{
            coordinateX=e.clientX;
            coordinateY=e.clientY
        });

        function animCursor(){
            topCursor.style.transform=`translate(${coordinateX}px, ${coordinateY}px)`;
            bottomCursor.style.transform=`translate(${coordinateX}px, ${coordinateY}px)`;
            requestAnimationFrame(animCursor)
        };
        requestAnimationFrame(animCursor)
    };
    displayCursor();
});

CSS

.circle-cursor {
  position:fixed;
  pointer-events:none;
  width:1.4376rem;
  height:1.4376rem;
  margin:-0.630rem 0 0 -0.630px;
  top:0;
  left:0;
  border-radius:50%;   
}
.circle-cursor-inner {
   width:100%;
   height:100%;
   border-radius:50%;
   display:block;
}
.circle-cursor-top {
   background-color:#22d4b5;
   transition:transform 0.06s cubic-bezier(.12,.12,.25,.92),opacity 1s ease;
   z-index:9999;
}
.circle-cursor-bottom {
  background:#6edddf;
  transition:transform 0.26s cubic-bezier(.12,.12,.25,.92),opacity 1s ease;
  z-index:9998;
}

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="custom-cursor-holder">
  <div class="circle-cursor   circle-cursor-top">
    <span class="circle-cursor-inner"></span>
  </div>
  <div class="circle-cursor circle-cursor-bottom"></div>
</div>

我的Angular尝试代码

模板代码

<div class="custom-cursor-holder">
  <div #top class="circle-cursor   circle-cursor-top">
    <span class="circle-cursor-inner"></span>
  </div>
  <div #bottom class="circle-cursor circle-cursor-bottom"></div>
</div>

组件代码

export class AppComponent{
  coordinateX = 0;
  coordinateY = 0;

  @ViewChild('top') top!: ElementRef;
  @ViewChild('bottom') bottom!: ElementRef;

  constructor(private renderer: Renderer2) {

  }

  @HostListener('mouseover', ['$event'])
  onOver(event: MouseEvent): void {
      this.coordinateX = event.clientX;
      this.coordinateY = event.clientY;
      this.renderer.setStyle(this.top.nativeElement, 'transform', 'translate('+ this.coordinateX +'px, '+ this.coordinateY +'px)');
  }
}

最佳Angular实现方案

组件代码优化

import { Component, ElementRef, ViewChild, HostListener, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  coordinateX = 0;
  coordinateY = 0;
  animationId?: number;

  @ViewChild('top') top!: ElementRef<HTMLDivElement>;
  @ViewChild('bottom') bottom!: ElementRef<HTMLDivElement>;

  ngOnInit(): void {
    this.startCursorAnimation();
  }

  ngOnDestroy(): void {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId);
    }
  }

  @HostListener('document:mousemove', ['$event'])
  onMouseMove(event: MouseEvent): void {
    this.coordinateX = event.clientX;
    this.coordinateY = event.clientY;
  }

  private startCursorAnimation(): void {
    const animCursor = () => {
      this.top.nativeElement.style.transform = `translate(${this.coordinateX}px, ${this.coordinateY}px)`;
      this.bottom.nativeElement.style.transform = `translate(${this.coordinateX}px, ${this.coordinateY}px)`;
      this.animationId = requestAnimationFrame(animCursor);
    };
    animCursor();
  }
}

模板代码(保持不变)

<div class="custom-cursor-holder">
  <div #top class="circle-cursor circle-cursor-top">
    <span class="circle-cursor-inner"></span>
  </div>
  <div #bottom class="circle-cursor circle-cursor-bottom"></div>
</div>

CSS代码(直接复用原代码)

将原jQuery实现中的CSS代码复制到组件的app.component.css文件中即可。

关键改进点

  • 改用document:mousemove监听全局鼠标移动,确保光标在整个页面范围内响应
  • 沿用requestAnimationFrame实现和原jQuery一致的流畅动画效果
  • 实现OnDestroy接口,组件销毁时清除动画帧,避免内存泄漏
  • 同时更新顶部和底部光标的位置,修复原尝试代码只处理顶部光标的问题
  • 为ElementRef添加类型标注,提升代码健壮性

内容的提问来源于stack exchange,提问作者Ranjith Varatharajan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:05:17