如何借助SVG linearGradient的repeat spreadMethod实现砖墙图案?
用SVG linearGradient实现砖墙图案的正确方式
理解spreadMethod="repeat"
spreadMethod="repeat"的作用是:在你定义的渐变区间(x1,y1到x2,y2)之外,重复整个渐变的颜色序列。要实现无缝重复,必须保证渐变的起始颜色(offset=0处)和结束颜色(offset=100%处)完全一致,否则重复时会出现明显的颜色断层。你之前的渐变定义没有完成完整循环,导致repeat无法正常工作。
修正后的linearGradient方案
下面是调整后的代码,通过两个linearGradient叠加实现砖墙的垂直重复和水平错缝:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <defs> <!-- 垂直方向砖墙+灰缝循环,每个循环占10%高度 --> <linearGradient spreadMethod="repeat" id="brickVertical" x1="0%" y1="0%" x2="0%" y2="10%"> <stop class="mortar" offset="0%"/> <stop class="mortar" offset="1%"/> <stop class="brick" offset="1%"/> <stop class="brick" offset="9%"/> <stop class="mortar" offset="9%"/> <stop class="mortar" offset="10%"/> </linearGradient> <!-- 水平方向错缝灰缝,每个循环占11%宽度,实现每行偏移 --> <linearGradient spreadMethod="repeat" id="brickHorizontal" x1="0%" y1="0%" x2="11%" y2="0%"> <stop offset="0%" stop-color="transparent"/> <stop offset="5%" stop-color="transparent"/> <stop class="mortar" offset="5%"/> <stop class="mortar" offset="6%"/> <stop offset="6%" stop-color="transparent"/> <stop offset="11%" stop-color="transparent"/> </linearGradient> <style> .ground { fill: #073605; } .fence { fill: #480d0d; } .front { fill: url(#brickVertical); } .front-offset { fill: url(#brickHorizontal); /* 让错缝只作用在奇数行,通过渐变变换实现垂直偏移 */ mask: url(#rowMask); } .brick { stop-color: #b00; } .mortar { stop-color: #bbb; } .side { fill: darkred; } .back-roof { fill: #901900; } .front-roof { fill: #a62f20; } .path { fill: brown; } .front-window { fill: white; } .grass { fill: green; } </style> <!-- 遮罩:只显示奇数行,实现错缝效果 --> <mask id="rowMask"> <linearGradient spreadMethod="repeat" id="maskGrad" x1="0%" y1="0%" x2="0%" y2="20%"> <stop offset="0%" stop-color="white"/> <stop offset="10%" stop-color="white"/> <stop offset="10%" stop-color="black"/> <stop offset="20%" stop-color="black"/> </linearGradient> <rect width="100%" height="100%" fill="url(#maskGrad)"/> </mask> </defs> <title>Talihouse</title> <rect class="ground" height="500" width="1000" y="500" /> <rect class="fence" height="20" y="480" width="1000" /> <!-- 基础砖墙 --> <rect class="front" width="500" height="300" x="100" y="450" /> <!-- 叠加错缝灰缝 --> <rect class="front-offset" width="500" height="300" x="100" y="450" /> <rect class="door" width="50" height="100" fill="black" x="330" y="650" /> <polygon class="back-roof" points="600,450 550,350 650,250 700,300" /> <polygon class="front-roof" points="600,450 550,350 150,350 100,450" /> <polygon class="side" points="600,750 600,450 700,300 700,500" /> <polygon class="grass" points="100,750 50,900 600,900 740,500 700,500 600,750 " /> <polygon class="path" points="320,750 300,800 83,800 66,850 350,850 390,750" /> <g class="front-windows"> <rect class="front-window" x="150" y="650" width="100" height="50" /> <rect class="front-window" x="150" y="500" width="100" height="50" /> <rect class="front-window" x="450" y="500" width="100" height="50" /> <rect class="front-window" x="450" y="650" width="100" height="50" /> </g> </svg>
代码说明
- brickVertical:定义了垂直方向的基本单元(1%灰缝+8%砖+1%灰缝),设置
y2="10%"让每个循环占10%高度,spreadMethod="repeat"会自动重复这个单元填充整个rect。 - brickHorizontal:定义水平方向的错缝灰缝,每个循环占11%宽度,通过遮罩
rowMask只让这个渐变作用在奇数行,实现砖墙的交错效果。 - rowMask:用线性渐变做遮罩,交替显示/隐藏行,确保错缝只出现在奇数行。
更简洁的方案:用SVG Pattern
如果追求更直观、易维护的砖墙效果,推荐使用SVG的<pattern>,它专门用于创建重复图案,比linearGradient更适合二维重复场景:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <defs> <!-- 砖墙图案单元:宽110,高100(对应实际尺寸的比例) --> <pattern id="brickPattern" width="110" height="100" patternUnits="userSpaceOnUse"> <!-- 第一行砖 --> <rect class="brick" x="0" y="0" width="100" height="80"/> <rect class="brick" x="110" y="0" width="100" height="80"/> <!-- 灰缝 --> <rect class="mortar" x="0" y="80" width="210" height="20"/> <rect class="mortar" x="100" y="0" width="10" height="80"/> <!-- 第二行错缝砖 --> <rect class="brick" x="55" y="100" width="100" height="80"/> <rect class="brick" x="165" y="100" width="100" height="80"/> <rect class="mortar" x="0" y="180" width="210" height="20"/> <rect class="mortar" x="155" y="100" width="10" height="80"/> </pattern> <style> .ground { fill: #073605; } .fence { fill: #480d0d; } .front { fill: url(#brickPattern); } .brick { fill: #b00; } .mortar { fill: #bbb; } .side { fill: darkred; } .back-roof { fill: #901900; } .front-roof { fill: #a62f20; } .path { fill: brown; } .front-window { fill: white; } .grass { fill: green; } </style> </defs> <title>Talihouse</title> <rect class="ground" height="500" width="1000" y="500" /> <rect class="fence" height="20" y="480" width="1000" /> <rect class="front" width="500" height="300" x="100" y="450" /> <rect class="door" width="50" height="100" fill="black" x="330" y="650" /> <polygon class="back-roof" points="600,450 550,350 650,250 700,300" /> <polygon class="front-roof" points="600,450 550,350 150,350 100,450" /> <polygon class="side" points="600,750 600,450 700,300 700,500" /> <polygon class="grass" points="100,750 50,900 600,900 740,500 700,500 600,750 " /> <polygon class="path" points="320,750 300,800 83,800 66,850 350,850 390,750" /> <g class="front-windows"> <rect class="front-window" x="150" y="650" width="100" height="50" /> <rect class="front-window" x="150" y="500" width="100" height="50" /> <rect class="front-window" x="450" y="500" width="100" height="50" /> <rect class="front-window" x="450" y="650" width="100" height="50" /> </g> </svg>
Pattern方案优势
- 直观:直接绘制砖墙的基本重复单元,修改砖的大小、颜色、灰缝宽度都非常方便。
- 高效:不需要叠加多个渐变,单个pattern就能实现完整的砖墙效果。
内容的提问来源于stack exchange,提问作者alasdair009
相关产品推荐
相关产品推荐

