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

在SwiftUI中复刻Apple Pay环形波纹效果

环形波纹效果实现方案

一、环形排列圆环

核心思路是围绕中心点,按固定角度间隔排布每个圆环,下面提供两种适合新手的实现方式:

方法1:CSS实现(上手简单)

  1. 搭建父容器作为定位基准,尺寸设为最大圆环的直径,开启相对定位。
  2. 每个圆环用绝对定位,先平移到父容器右侧边缘,再绕父容器中心旋转对应角度。
  3. 角度计算:若有N个圆环,每个圆环的旋转角度为 360°/N × 序号。

示例代码:

<div class="ripple-container">
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="ring"></div>
  <div class="center-icon">🔔</div>
</div>

<style>
.ripple-container {
  position: relative;
  width: 200px;
  height: 200px;
  margin: 50px auto;
}

.ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  transform-origin: center left; /* 旋转基点设为父容器中心左侧 */
}

/* 给每个圆环分配旋转角度 */
.ring:nth-child(1) { transform: rotate(0deg); }
.ring:nth-child(2) { transform: rotate(45deg); }
.ring:nth-child(3) { transform: rotate(90deg); }
.ring:nth-child(4) { transform: rotate(135deg); }
.ring:nth-child(5) { transform: rotate(180deg); }
.ring:nth-child(6) { transform: rotate(225deg); }
.ring:nth-child(7) { transform: rotate(270deg); }
.ring:nth-child(8) { transform: rotate(315deg); }

.center-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 40px;
}
</style>

方法2:Canvas实现(支持动态效果)

通过三角函数计算每个圆环的圆心坐标,实现环形排列:

  1. 确定画布中心坐标(cx, cy),以及中心到圆环圆心的距离ringRadius。
  2. 每个圆环的圆心坐标公式:
    • x = cx + ringRadius × cos(弧度角度)
    • y = cy + ringRadius × sin(弧度角度)
  3. 弧度角度计算:若有N个圆环,每个圆环的角度为 2π/N × 序号。

示例代码:

const canvas = document.getElementById('ripple-canvas');
const ctx = canvas.getContext('2d');
canvas.width = 300;
canvas.height = 300;

const cx = canvas.width / 2;
const cy = canvas.height / 2;
const ringCount = 8; // 圆环总数
const ringRadius = 60; // 中心到圆环圆心的距离
const singleRingSize = 40; // 单个圆环的半径
const ringWidth = 2; // 圆环线条宽度

// 批量绘制环形排列的圆环
for(let i = 0; i < ringCount; i++) {
  const angle = (Math.PI * 2 / ringCount) * i;
  const x = cx + ringRadius * Math.cos(angle);
  const y = cy + ringRadius * Math.sin(angle);
  
  ctx.beginPath();
  ctx.arc(x, y, singleRingSize, 0, Math.PI * 2);
  ctx.lineWidth = ringWidth;
  ctx.strokeStyle = '#000';
  ctx.stroke();
}

// 绘制中间图标(用文字替代)
ctx.font = '40px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('🔔', cx, cy);

二、实现整体渐变效果

要让所有圆环呈现统一渐变,核心是让所有元素共享同一个渐变源,而非单独设置:

CSS方案:背景裁剪+路径裁剪

  1. 给父容器设置线性/径向渐变背景。
  2. 每个圆环用clip-path剪出圆环形状,同时继承父容器的渐变背景。

修改CSS中.ring的样式:

.ring {
  /* 保留原有定位、旋转样式 */
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  background-clip: text;
  -webkit-background-clip: text;
  /* 用两个圆形路径相减,得到圆环形状 */
  clip-path: circle(50% at 50% 50%) circle(45% at 50% 50%);
}

调整两个圆形的百分比,可以控制圆环的宽度。

Canvas方案:统一渐变笔触

创建一个全局渐变对象,所有圆环都使用这个渐变描边:

// 在绘制圆环前创建渐变
const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
gradient.addColorStop(0, '#4facfe');
gradient.addColorStop(1, '#00f2fe');

// 绘制圆环时替换描边样式
ctx.strokeStyle = gradient;

额外优化:波纹扩散动画

给每个圆环添加延迟动画,模拟波纹扩散效果:

.ring {
  /* 保留原有样式 */
  animation: ripple 2s infinite;
  --rotate: 0deg;
  transform: rotate(var(--rotate));
}

/* 给每个圆环设置动画延迟 */
.ring:nth-child(1) { --rotate: 0deg; animation-delay: 0s; }
.ring:nth-child(2) { --rotate: 45deg; animation-delay: 0.25s; }
.ring:nth-child(3) { --rotate: 90deg; animation-delay: 0.5s; }
.ring:nth-child(4) { --rotate: 135deg; animation-delay: 0.75s; }
.ring:nth-child(5) { --rotate: 180deg; animation-delay: 1s; }
.ring:nth-child(6) { --rotate: 225deg; animation-delay: 1.25s; }
.ring:nth-child(7) { --rotate: 270deg; animation-delay: 1.5s; }
.ring:nth-child(8) { --rotate: 315deg; animation-delay: 1.75s; }

@keyframes ripple {
  0% {
    transform: rotate(var(--rotate)) scale(1);
    opacity: 1;
  }
  100% {
    transform: rotate(var(--rotate)) scale(1.5);
    opacity: 0;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:47:46