Skip to content

text

属性释义有效值
textAnchor文字方向middle、start、end
strokeWidth文本描边宽度2px
stroke文本描边颜色#fff
fill文字填充色#fff
strokeLinejoin定义两条线段在“拐角”处(连接点)的形状miter(默认尖角)、round(圆角)、bevel(切角)
tSpan(类似 span,支持像是 html 文档流自然排列)
jsx
<svg viewBox="0 0 150 72">
    <text
        x="50%"
        y="60"
        stroke="#fff"
        strokeWidth="2"
        fill="#FF3803"
        letterSpacing="-2px"
        textAnchor="middle"
    >
        <tspan fontSize="72px">24</tspan>
        <tspan
            fontSize="50px"
            fontWeight={400}
        >
            HR
        </tspan>
    </text>
</svg>
给文字加上描边颜色
jsx
<svg
    className="-z-1 pointer-events-none absolute left-0 top-0 h-full w-full"
    viewBox={`0 0 ${width} ${height}`}
>
    <defs>
        <linearGradient
            id="gradient-rule"
            x1="0%"
            y1="0%"
            x2="0%"
            y2="100%"
        >
            <stop
                offset="48%"
                stopColor="#8CBBCF"
            />
            <stop
                offset="100%"
                stopColor="#4578A5"
            />
        </linearGradient>
    </defs>
    <rect stroke="url(#gradient-rule)" />
</svg>
填充 rect
属性释义有效值
patternUnits定位关系userSpaceOnUse(类似 bg-no-repeat)
jsx
<svg
    className="-z-1 pointer-events-none absolute left-0 top-0 h-full w-full"
    viewBox={`0 0 ${width} ${height}`}
>
    <defs>
        <pattern
            id="pattern-rule"
            x="10"
            y="10"
            width="27"
            height="27"
            patternUnits="userSpaceOnUse"
        >
            <path
                d="M26 0V26H0"
                stroke="#D9D9D9"
                strokeWidth="2"
                opacity="0.07"
                fill="none"
            />
        </pattern>
    </defs>
    <rect
        strokeWidth={10}
        fill="url(#pattern-rule)"
        strokeLinejoin="round"
        rx={43}
    />
</svg>
文字添加阴影

关键字 in (系统自带输入源)

属性释义包含什么信息?
SourceAlpha原始透明度只有形状(不透明的地方是黑,透明的是白/无)。不包含颜色。
SourceGraphic原始图形形状 + 颜色 + 描边。就是物体原本长什么样。

流程总览 想象你在处理 Photoshop 图层:

  1. 提取轮廓:先把原图的轮廓提取出来,做成黑色的。
  2. 模糊:把这个轮廓弄模糊。
  3. 位移:把模糊的轮廓向下移一点。
  4. 上色:把这个黑乎乎的影子染成一种特殊的蓝紫色半透明颜色。
  5. 合并:把原图盖在这个蓝紫色的影子上面。

详解

  1. 高斯模糊 (feGaussianBlur)
    • in="SourceAlpha":这是关键。它不取原图的颜色,只取透明度通道。这意味着无论你的原图是什么颜色,这里得到的都是一个纯黑色的轮廓(不透明的地方是黑,透明的地方还是透明)。
    • stdDeviation="3":模糊程度。数值越大,影子越虚、越散。
    • result="blur":把这个处理结果命名为 blur,给下一步用。
  2. 偏移位置 (feOffset)
  3. 准备颜色 (feFlood)
    • 作用:这就好比拿着油漆桶,倒满整个画布。
    • floodColor:定义影子的颜色。这里是一个深蓝色,30% 透明度。
    • result="color":命名为“颜色层”。此时画布上全是这个颜色,还没有形状。
  4. 颜色合成/裁剪 (feComposite) —— 最重要的一步
    • 原理:这是为了解决“怎么把黑色影子变成蓝色”的问题。
    • in="color":输入源是刚才那个全屏的蓝色。
    • in2="offsetBlur":遮罩源是第 2 步那个移位后的模糊轮廓。
    • operator="in":取交集。意思是:只保留 in2 (模糊轮廓) 范围内的 in (蓝色)。
    • 结果:原本全屏的蓝色被剪裁成了影子的形状。现在你得到了一个完美的、模糊的、深蓝色的影子。
  5. 合并显示 (feMerge)
    • 作用:把影子和原图叠在一起输出。SVG 里的顺序是从下往上叠。
    • :先把刚才做好的蓝色影子放在最底层。
    • :把原始图像(SourceGraphic)盖在影子上面。
jsx
<svg
    className="h-full w-full"
    viewBox="0 0 100 100"
>
    <defs>
        <filter id="complexShadow">
            <feGaussianBlur
                in="SourceAlpha"
                stdDeviation="3"
                result="blur"
            />
            <feOffset
                in="blur"
                dx="0"
                dy="8"
                result="offsetBlur"
            />
            <feFlood
                floodColor="rgba(8, 7, 122, 0.30)"
                result="color"
            />
            <feComposite
                in="color"
                in2="offsetBlur"
                operator="in"
                result="shadow"
            />

            <feMerge>
                <feMergeNode in="shadow" />
                <feMergeNode in="SourceGraphic" />
            </feMerge>
        </filter>
    </defs>

    <text
        x="0"
        y="45"
        fill="#fff"
        filter="url(#complexShadow)"
    >
        {children}
    </text>
</svg>

animate

  • 加上 animate 可以控制动画
  • 可以添加多个 animate,同时生效
  • morph,针对 path 动态变化(比如图形 a 到图形 b)
  • 写法2:通过 href=“#myReact”,可以不需要内嵌 animate 标签
  • 动画行为控制
    • begin
      • =2s 延迟两秒后再执行
      • =click 点击元素后再执行(如果希望由其他元素触发,设置成 myReact.click
      • =mouseover
      • =animateA.end (动画衔接:存在一个另一个 animate id=animateA,当它的动画结束后,该动画开始)
      • =animateA.end - 1s (结束前 1s 开始)
      • =3s;click (复合条件,满足任一)
      • element.beginElement() 通过 JavaScript 控制
html
<svg
    viewBox="0 0 10 10"
    xmlns="http://www.w3.org/2000/svg"
>
    <rect
        width="10"
        height="10"
        id="myReact"
    >
        <animate
            attributeName="rx"
            values="0;5;0"
            dur="10s"
            repeatCount="indefinite"
        />
    </rect>
</svg>

关键帧(设置动画过渡效果)

html
<svg
    width="120"
    height="120"
    xmlns="http://www.w3.org/2000/svg"
>
    <circle
        cx="60"
        cy="10"
        r="10"
    >
        <animate
            attributeName="cx"
            attributeType="XML"
            dur="4s"
            values="60 ; 110 ; 60 ; 10 ; 60"
            keyTimes="0 ; 0.25 ; 0.5 ; 0.75 ; 1"
            repeatCount="indefinite"
        />

        <animate
            attributeName="cy"
            attributeType="XML"
            dur="4s"
            values="10 ; 60 ; 110 ; 60 ; 10 "
            keyTimes="0 ; 0.25 ; 0.5 ; 0.75 ; 1"
            repeatCount="indefinite"
        />
    </circle>
</svg>

Last updated: