阅读视图

发现新文章,点击刷新页面。

Apple同款SVG,怎么写出来?手写+编辑器,两张方法都能搞定!

编辑

有时候刷到那种很克制、很高级的轮播——没有夸张的左右整屏滑动,只是几张卡片在视野里轻轻错位一下,你大脑里就会自动补一句:

嗯,这味儿有点 Apple。

这类效果不一定要上 JS / CSS 大动干戈,很多公众号里的“高级轮播”,其实就是一段 纯 SVG + SMIL 动画。下面我们就拆一段实际在用的 4 图轮播代码,看它是怎么靠几行<animateTransform> 做出这种“款款而来”的感觉的。
*本文代码借鉴学习了一款现成的SVG编辑器 -  E2 编辑器做练习,只是做一下学习分享。

下文的核心结构来自这样一段代码(只保留和动效相关的部分):

<svg viewBox="0 0 0 0" width="100%">
  <g>
    <foreignObject x="0" y="0" width="0" height="0">
      <svg
        style='display:block; background-image:url(""); background-size:100% auto;'
        viewBox="0 0 0 0" width="100%">
      </svg>
    </foreignObject>
  </g>

  <g>
    <foreignObject ...> ... </foreignObject>
    <animateTransform
      attributeName="transform"
      type="translate"
      repeatCount="indefinite"
      values="0 0; 0 0; 0 0; 0 0; 0 0; 0 0; 0 0; -80 0; 0 0;"
      begin="0.3s"
      dur="4s"
      calcMode="spline"
      keySplines="0.42 0 0.58 1.0; ...">
    </animateTransform>
  </g>

  <!-- 另外 3 个 <g>,结构类似,只是 values 不同 -->
</svg>

一、整体结构:一个 <svg> + 多个 <g> = 多个 slide

这段代码的结构非常简单粗暴:

  • 最外层是一个 <svg>width="100%",跟着容器自动铺满;
  • 里面有 多个 <g> 分组,每个分组对应一张“幻灯片”;
  • 每个分组里都有一个 <foreignObject>,里面再包一段 <svg>,这段内嵌 svg 只干一件事:
    用 background-image 把真正的图片铺上去。

换句话说,这个轮播:

  • 没有 <image> 标签;
  • 没有 <img> 标签;
  • 就是把 图片当作 CSS 背景,挂在一个 svg 里。

这种写法在公众号场景里有个好处:

  • 版式层是 SVG 控制的(可以做动效);
  • 图像展示层直接走 CSS 背景(好替换、好裁剪)。

你要换自己的图,只需要改这一段的 URL:

<svg
  style='display:block; 
         background-image:url("https://你的图片地址.jpg");
         background-size:100% auto;
         background-repeat:no-repeat;'>
</svg>

二、轮播核心:用 SMIL 的 <animateTransform> 做平移

真正让这几个 slide “活起来”的,就是每个 <g> 下面那条 animateTransform

典型一条长这样:

<animateTransform
  attributeName="transform"
  type="translate"
  repeatCount="indefinite"
  values="0 0; 0 0; 0 0; 0 0; 0 0; 0 0; 0 0; -80 0; 0 0;"
  begin="0.3s"
  dur="4s"
  calcMode="spline"
  keySplines="
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0;
    0.42 0 0.58 1.0">
</animateTransform>

逐项看:

  • attributeName="transform"
    意味着这条动画会直接改 <g> 的 transform 属性;

  • type="translate"
    指定 transform 的类型是平移,相当于在做 translate(x, y)

  • repeatCount="indefinite"
    无限循环播放,保证轮播不停止;

  • dur="4s"
    一轮动画总时长 4 秒;

  • begin="0.3s"
    整体开始时间延迟了 0.3 秒,避免页面一加载上来就立刻抖动;

  • values="..."
    这是整段的关键帧列表,每一对数字代表一个平移坐标:

    • 0 0:停在初始位置;
    • -80 0:往左移动 80 个单位;
    • 接着再回到 0 0

values 里之所以有一长串 0 0,其实是在拉长“静止时间” ,让卡片绝大部分时间都稳稳地停在中间,只在时间轴尾巴那一段轻轻侧移一下再回来。

这就是“优雅”的第一层来源:
不是一直在明显地滑,而是大部分时间在静止、小部分时间在微动


三、动起来为什么看着“高级”?关键在于缓动 + 细小位移

1. 微小位移:只移动 80,而不是整屏 100%

可以对比一下常见轮播:

  • 普通“整屏轮播”:一张图从 0% 滑到 -100%,下一张从 100% 滑到 0
  • 这段 SVG 轮播:只平移 -80 或 +80 的距离。

也就是说,它并不是在做「换图」,而是在做「轻微错位」:

  • 用户视角里,一直是同一张图为主;
  • 偶尔轻轻滑动一点点,有一种“轻微呼吸”的感觉;
  • 视觉上更接近 Apple 官网那些“轻轻抖一抖”的动效,而不是 APP 里的 banner 跑马灯。

2. 贝塞尔缓动:keySplines="0.42 0 0.58 1.0"

calcMode="spline" + keySplines="0.42 0 0.58 1.0" 这对组合,其实就是 SVG 版本的 CSS cubic-bezier(0.42, 0, 0.58, 1),也就是非常经典的 ease-in-out

效果是:

  • 一开始慢慢起步(不是生硬地动);
  • 中间加速一点;
  • 结束前再慢慢刹车。

配合上前面说的“位移量不大”,就会得到一个很克制的动效——有存在感,但不抢内容风头

3. 多个 slide 共用同一时间轴

注意这 4 个 <g>

  • 都是 dur="4s" begin="0.3s" repeatCount="indefinite"
  • 唯一的区别是:每个 <g> 的 values 序列不一样。

换句话说:

  • 它们跑在同一条时间线上;
  • 但每一张图的“位移节奏”略有差异;
  • 最终呈现出来就是一个整体“呼吸”的卡片群,而不是单张 slide 独立乱飞。

这点非常像 Apple 官网那种「一组卡片跟着一个节奏,轮流被稍稍突出」的感觉。


四、想改成自己的轮播?几个实用的改法

如果你想在这个基础上做个自己的「苹果味轮播」,主要可以改 4 个方面:

1. 换成你自己的图片

找到每个 foreignObject 里的这段:

<svg
  style='display:block;
         background-image:url("https://你的图.jpg");
         background-size:100% auto;
         background-repeat:no-repeat;'>
</svg>

把 background-image 换成你的图地址就行。

想更“苹果一点”,可以准备几张同一系列、同一光感的产品图。

2. 调整位移幅度

所有轮播的空间错位,靠的就是 values 里的那几个 -80 0 / 80 0

  • 想动得更明显一点:可以改成 -160 0 / 160 0
  • 想更微妙一点:可以改成 -40 0 / 40 0

比如:

values="0 0; 0 0; 0 0; -40 0; 0 0; 0 0; 0 0; 0 0; 0 0"

3. 调整节奏和停留时间

几种常见玩法:

  • 整体放慢dur="4s" 改成 6s 或 8s

  • 让“静止”的比例更大:多复制几段 0 0

  • 只在最后 10% 时间里移动
    配合 keyTimes(如果你愿意加上一行):

    • 前 90% 的 keyTime 都是 0 0,最后 10% 才从 0 0 → -80 0 → 0 0

示意写法(扩展版):

<animateTransform
  attributeName="transform"
  type="translate"
  dur="8s"
  repeatCount="indefinite"
  values="0 0; 0 0; -80 0; 0 0"
  keyTimes="0;0.8;0.9;1"
  calcMode="spline"
  keySplines="
    0.42 0 0.58 1;
    0.42 0 0.58 1;
    0.42 0 0.58 1" />

4. 增加 / 减少图片数量

这个轮播没有“总数配置”,每张图就是一个 <g> ,所以:

  • 想多几张图:

    • 复制一份 <g> ... </g>
    • 按照原来的 pattern 写一条新的 values
  • 想只留 3 张图:

    • 删除其中一个 <g> 即可。

只要你保证:

  • 所有 <g> 的 dur 和 begin 一致;
  • values 之间有一点节奏差异(不要全部都一模一样);

整体看上去就还是那种「有秩序的小范围错位」。


五、小结

这个 4 图轮播本质上做了几件事:

  1. 用 SVG + foreignObject 搭了个“动效容器” ,图片当背景;
  2. 用 <animateTransform> + translate 做微位移,一次只挪几十个单位;
  3. 用 cubic-bezier 式的缓动曲线压住“廉价感” ,慢进慢出;
  4. 让所有 slide 套在同一时间轴上,做成整体的“呼吸”,而不是普通 banner 般机械的滑动。

看起来是“苹果味”的轮播,拆开就是一堆很朴素的 SVG 技巧。


最后一句:如果你懒得手写…

如果你不想自己去算这些 valueskeySplines 和 <g> 结构,也可以直接在 E2 编辑器里搜一下,组件名称叫「款款而来」,组件本身是免费使用的,用现成组件然后再对导出的 SVG 做二次改造,会轻松不少。

使用 E2 SVG 编辑器 — 基于 SVG 的“黑科技互动”可视化设计平台,上线1900+原创组件,支持积木式拖拽、组件复用与热区触发,已被 2 万+品牌应用于公众号、微博、活动专题制作,快速打造高互动图文、提升用户停留与完读率。

image.png 上传四张尺寸相同的图片,就可以直接预览效果,还可以点击获取代码后,在其他软件里进行二次编辑。还可以调整速度参数,如果购买了企业会员的话。

❌