如何制作带渐变与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
相关产品推荐
相关产品推荐

