跳到主要内容

渐变

渐变是从一种颜色平滑过渡到另一种颜色的效果。SVG 支持两种渐变类型:线性渐变和径向渐变。渐变可以为图形添加深度感和视觉吸引力。

渐变基础

渐变定义在 <defs> 元素内部,然后通过 ID 引用。<defs> 元素用于定义可重用的元素,这些元素不会直接显示,只有被引用时才会渲染。

<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="myGradient">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="180" height="80" fill="url(#myGradient)"/>
</svg>

线性渐变 - linearGradient

线性渐变沿着直线方向改变颜色。

基本语法

<linearGradient id="gradient-id" x1="x1" y1="y1" x2="x2" y2="y2">
<stop offset="offset" stop-color="color" stop-opacity="opacity"/>
...
</linearGradient>

渐变方向

x1y1 定义渐变起点,x2y2 定义渐变终点。默认值是水平从左到右(x1="0%" y1="0%" x2="100%" y2="0%")。

<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="horizontal" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
<linearGradient id="vertical" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
<linearGradient id="diagonal" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="80" height="80" fill="url(#horizontal)"/>
<rect x="110" y="10" width="80" height="80" fill="url(#vertical)"/>
<rect x="210" y="10" width="80" height="80" fill="url(#diagonal)"/>
</svg>

多色渐变

可以添加多个 <stop> 元素创建多色渐变:

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="rainbow">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="25%" stop-color="#f39c12"/>
<stop offset="50%" stop-color="#f1c40f"/>
<stop offset="75%" stop-color="#2ecc71"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="280" height="80" fill="url(#rainbow)"/>
</svg>

透明度渐变

使用 stop-opacity 属性创建透明度渐变:

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="fade">
<stop offset="0%" stop-color="#3498db" stop-opacity="1"/>
<stop offset="100%" stop-color="#3498db" stop-opacity="0"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="280" height="80" fill="url(#fade)"/>
</svg>

径向渐变 - radialGradient

径向渐变从一个中心点向外辐射,颜色呈圆形或椭圆形扩散。

基本语法

<radialGradient id="gradient-id" cx="cx" cy="cy" r="r" fx="fx" fy="fy">
<stop offset="offset" stop-color="color" stop-opacity="opacity"/>
...
</radialGradient>

中心点和半径

  • cxcy:渐变中心点坐标(默认 50%, 50%)
  • r:渐变半径(默认 50%)
  • fxfy:焦点坐标,渐变颜色的起始点(默认等于 cx, cy)
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="radial1">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#3498db"/>
</radialGradient>
<radialGradient id="radial2" cx="30%" cy="30%">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#e74c3c"/>
</radialGradient>
</defs>
<circle cx="75" cy="75" r="60" fill="url(#radial1)"/>
<circle cx="225" cy="75" r="60" fill="url(#radial2)"/>
</svg>

焦点偏移

通过设置 fxfy 可以偏移焦点,创建类似光照效果:

<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="spotlight" cx="50%" cy="50%" r="50%" fx="25%" fy="25%">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#2c3e50"/>
</radialGradient>
</defs>
<circle cx="150" cy="75" r="70" fill="url(#spotlight)"/>
</svg>

椭圆渐变

通过设置不同的 rxry(使用 gradientTransform 变换)可以创建椭圆渐变:

<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="ellipse" cx="50%" cy="50%" r="50%"
gradientTransform="scale(1, 0.5)">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#9b59b6"/>
</radialGradient>
</defs>
<ellipse cx="150" cy="75" rx="120" ry="60" fill="url(#ellipse)"/>
</svg>

渐变扩展模式

spreadMethod 属性定义当渐变没有填满整个图形时的处理方式。

效果
pad(默认)用最后一个颜色填充剩余区域
reflect反向重复渐变
repeat从头重复渐变
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="pad" cx="50%" cy="50%" r="30%" spreadMethod="pad">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#3498db"/>
</radialGradient>
<radialGradient id="reflect" cx="50%" cy="50%" r="30%" spreadMethod="reflect">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#e74c3c"/>
</radialGradient>
<radialGradient id="repeat" cx="50%" cy="50%" r="30%" spreadMethod="repeat">
<stop offset="0%" stop-color="#fff"/>
<stop offset="100%" stop-color="#2ecc71"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="80" height="80" fill="url(#pad)"/>
<rect x="110" y="10" width="80" height="80" fill="url(#reflect)"/>
<rect x="210" y="10" width="80" height="80" fill="url(#repeat)"/>
</svg>

渐变单位系统

gradientUnits 属性定义渐变坐标的参考系统。

效果
objectBoundingBox(默认)使用图形的边界框作为坐标系统,坐标范围 0-1
userSpaceOnUse使用 SVG 画布的坐标系统
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bbox" x1="0%" y1="0%" x2="100%" y2="100%"
gradientUnits="objectBoundingBox">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
<linearGradient id="user" x1="0" y1="0" x2="300" y2="150"
gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="100%" stop-color="#3498db"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="80" height="80" fill="url(#bbox)"/>
<rect x="110" y="10" width="80" height="80" fill="url(#user)"/>
</svg>

使用 objectBoundingBox 时,渐变会自动适应图形大小。使用 userSpaceOnUse 时,渐变位置固定,不同图形可能显示渐变的不同部分。

渐变继承

使用 href 属性可以让一个渐变继承另一个渐变的属性:

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="base">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="50%" stop-color="#f39c12"/>
<stop offset="100%" stop-color="#2ecc71"/>
</linearGradient>
<linearGradient id="derived" href="#base" x1="0%" y1="0%" x2="0%" y2="100%"/>
</defs>
<rect x="10" y="10" width="130" height="80" fill="url(#base)"/>
<rect x="160" y="10" width="130" height="80" fill="url(#derived)"/>
</svg>

derived 渐变继承了 base 的颜色定义,但改变了渐变方向。

实用示例

金属质感按钮

<svg width="200" height="60" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="metal" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#f5f6f6"/>
<stop offset="50%" stop-color="#dbdce0"/>
<stop offset="51%" stop-color="#b8bac0"/>
<stop offset="100%" stop-color="#dddfe3"/>
</linearGradient>
</defs>
<rect x="10" y="10" width="180" height="40" rx="8" fill="url(#metal)" stroke="#a0a0a0" stroke-width="1"/>
<text x="100" y="36" text-anchor="middle" font-family="Arial" font-size="16" fill="#333">Metal Button</text>
</svg>

球体效果

<svg width="150" height="150" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="sphere" cx="35%" cy="35%" r="60%" fx="25%" fy="25%">
<stop offset="0%" stop-color="#fff"/>
<stop offset="30%" stop-color="#3498db"/>
<stop offset="100%" stop-color="#1a5276"/>
</radialGradient>
</defs>
<circle cx="75" cy="75" r="60" fill="url(#sphere)"/>
</svg>

霓虹效果

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="neon" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#ff00ff"/>
<stop offset="50%" stop-color="#00ffff"/>
<stop offset="100%" stop-color="#ff00ff"/>
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<text x="150" y="60" text-anchor="middle" font-family="Arial" font-size="40"
fill="url(#neon)" filter="url(#glow)">NEON</text>
</svg>

渐变描边

渐变也可以应用于描边:

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="strokeGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#e74c3c"/>
<stop offset="50%" stop-color="#f39c12"/>
<stop offset="100%" stop-color="#2ecc71"/>
</linearGradient>
</defs>
<text x="150" y="60" text-anchor="middle" font-family="Arial" font-size="50"
fill="none" stroke="url(#strokeGradient)" stroke-width="2">GRADIENT</text>
</svg>

小结

渐变是 SVG 中创建丰富视觉效果的重要工具。线性渐变沿直线方向过渡颜色,径向渐变从中心向外辐射。通过控制渐变方向、颜色停止点、透明度和扩展模式,可以创建各种视觉效果,如金属质感、球体效果和霓虹效果。