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

如何制作带渐变与JS可控焦点的非完整圆形描边?

实现Apple Watch风格的渐变弧形进度环

需求说明

要制作下图所示的Apple Watch空气质量小组件样式元素:
带渐变描边的非完整圆形
核心需求:

  • 非完整圆形(底部留缺口,**禁止使用transform: rotate**实现)
  • 描边带有完整渐变效果
  • 可通过JavaScript动态设置焦点标记,对应实际数值

之前尝试用dasharray+dashoffset处理整圆,但渐变无法覆盖整条描边,且不想依赖旋转实现缺口。


解决方案:用<path>绘制弧形替代整圆

直接通过SVG的<path>椭圆弧命令绘制指定角度的弧形,天然保留底部缺口,同时渐变可以完整覆盖描边,再配合JS动态控制焦点和进度。

完整代码示例

<svg width="500px" height="500px" viewBox="0 0 120 120">
  <!-- 渐变定义 -->
  <defs>
    <linearGradient id="arcGradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="#05a" />
      <stop offset="50%" stop-color="#a55" />
      <stop offset="100%" stop-color="#0a5" />
    </linearGradient>
    <radialGradient id="focusGradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" stop-color="#fff" />
      <stop offset="100%" stop-color="#0a5" />
    </radialGradient>
  </defs>

  <!-- 270度渐变弧形(底部留90度缺口) -->
  <path 
    id="progressArc"
    fill="none" 
    stroke="url(#arcGradient)" 
    stroke-width="10" 
    stroke-linecap="round"
    d="M 60,10 
       A 50,50 0 1,1 60,110" />

  <!-- 动态焦点标记 -->
  <circle id="focusDot" cx="60" cy="10" r="5" fill="url(#focusGradient)" />
</svg>
/* 基础样式,可按需调整 */
svg {
  display: block;
  margin: 0 auto;
}

JavaScript控制逻辑

1. 动态设置焦点位置

根据数值计算对应弧形上的坐标,更新焦点标记:

// value: 当前数值, min/max: 数值范围
function setFocus(value, min = 0, max = 100) {
  const percentage = (value - min) / (max - min);
  const totalArcAngle = 270; // 弧形总角度(对应底部90度缺口)
  const targetAngle = percentage * totalArcAngle;
  // 转换为弧度,初始位置为顶部(-90度)
  const radians = (targetAngle - 90) * Math.PI / 180;
  
  const centerX = 60;
  const centerY = 60;
  const radius = 50;
  
  const dotX = centerX + radius * Math.cos(radians);
  const dotY = centerY + radius * Math.sin(radians);
  
  const focusDot = document.getElementById('focusDot');
  focusDot.setAttribute('cx', dotX);
  focusDot.setAttribute('cy', dotY);
}

// 示例:设置数值为75时的焦点
setFocus(75);
2. 动态调整弧形进度(可选)

如果需要实现部分填充的弧形进度,结合stroke-dasharray控制:

function setProgress(value, min = 0, max = 100) {
  const percentage = (value - min) / (max - min);
  const arcLength = 2 * Math.PI * 50 * (270 / 360); // 270度弧形的周长
  const dashArray = `${percentage * arcLength}, ${arcLength}`;
  
  const arc = document.getElementById('progressArc');
  arc.setAttribute('stroke-dasharray', dashArray);
}

// 示例:设置进度为50%
setProgress(50);

关键优势

  • 无需旋转操作,弧形缺口天然存在,避免布局偏移问题
  • 渐变完整覆盖整条弧形描边,不会因为dasharray导致渐变截断
  • 焦点和进度的计算逻辑直观,便于JS动态控制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:40:28