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

基于CSS实现特定形状的自定义光标(Angular应用场景)

实现Angular中跟随数值移动的自定义圆弧光标

核心思路

通过SVG的getPointAtLength()方法获取圆弧上对应数值比例的坐标点,动态更新白色光标的位置,实现数值与光标位置的精准绑定。

步骤1:修正SVG旋转中心(避免定位偏移)

原SVG的transform="rotate(138)"默认绕左上角旋转,需改为绕SVG中心(50,50)旋转,确保圆弧位置正确:

<svg width="200" height="200" viewBox="0 0 100 100" transform="rotate(138, 50, 50)">

步骤2:添加白色光标元素

在SVG内部添加白色圆形作为光标(推荐SVG方式,避免定位偏差):

<div class="main">
    <svg width="200" height="200" viewBox="0 0 100 100" transform="rotate(138, 50, 50)">
        <linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stop-color="#2ed8a7" />
            <stop offset="100%" stop-color="#a6ceff" />
        </linearGradient>
        <circle #progressCircle stroke-linecap="round" cx="50" cy="50" r="38" stroke="url(#linear)" stroke-width="8" fill="none"
            stroke-dasharray="275" stroke-dashoffset="100" stroke-miterlimit="0" />
        <!-- 白色光标 -->
        <circle #cursor cx="0" cy="0" r="6" fill="#fff" stroke="#333" stroke-width="1" />
    </svg>

    <div class="main-current">{{ currentValue }}</div>
    <div class="main-minmax">
        <div>{{ minValue }}</div>
        <div>{{ maxValue }}</div>
    </div>
</div>

步骤3:Angular组件逻辑实现

通过ViewChild获取DOM元素,计算数值对应的圆弧坐标并更新光标位置:

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

@Component({
  selector: 'app-custom-cursor',
  templateUrl: './custom-cursor.component.html',
  styleUrls: ['./custom-cursor.component.scss']
})
export class CustomCursorComponent implements OnInit {
  @ViewChild('progressCircle') progressCircle!: ElementRef<SVGCircleElement>;
  @ViewChild('cursor') cursor!: ElementRef<SVGCircleElement>;
  
  // 可根据业务需求动态修改这些参数
  currentValue = 70;
  minValue = 10;
  maxValue = 100;
  strokeDashoffset = 100; // 与SVG中的stroke-dashoffset保持一致

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

  // 更新光标位置的核心方法
  updateCursorPosition(): void {
    const circle = this.progressCircle.nativeElement;
    const totalArcLength = circle.getTotalLength(); // 获取圆形总周长
    // 计算当前数值在区间内的比例
    const progressRatio = (this.currentValue - this.minValue) / (this.maxValue - this.minValue);
    // 计算光标在圆弧上的长度位置:从偏移量开始,到显示弧长的对应比例点
    const cursorPositionLength = this.strokeDashoffset + progressRatio * (totalArcLength - this.strokeDashoffset);
    // 获取该长度对应的坐标点
    const targetPoint = circle.getPointAtLength(cursorPositionLength);
    // 设置光标坐标
    this.cursor.nativeElement.setAttribute('cx', targetPoint.x.toString());
    this.cursor.nativeElement.setAttribute('cy', targetPoint.y.toString());
  }

  // 示例:动态修改数值的方法(可根据业务场景调整)
  setValue(newValue: number): void {
    // 限制数值在min-max区间内
    this.currentValue = Math.max(this.minValue, Math.min(this.maxValue, newValue));
    this.updateCursorPosition();
  }
}

步骤4:动态数值测试(可选)

如果需要验证数值变化效果,可在模板中添加测试按钮:

<div style="margin-top: 20px;">
    <button (click)="setValue(20)">设置为20</button>
    <button (click)="setValue(70)">设置为70</button>
    <button (click)="setValue(100)">设置为100</button>
</div>

关键说明

  • getTotalLength():返回SVG圆形的总周长,作为计算的基准。
  • getPointAtLength(length):根据传入的长度值,返回圆弧上对应点的精确坐标。
  • 数值比例计算:确保10-100的数值范围与圆弧的起始/结束位置完全对应,可通过调整minValue和maxValue适配其他区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:25:14