[园冶图式] 用SVG绘制《园冶注释》图式——束腰式
读《园冶注释》时,觉得书中图式甚为精巧,想着将其整理收藏。正好博客园又能在文章中放上SVG图案,便有了此系列随笔,权当学习H5的SVG绘图知识与自娱自乐。
每个图式下都附上了对应的SVG代码并默认折叠,方便阅读。
束腰式
如长槅欲齐短槅并装,亦宜上下用。
图一 - 五十七
图一 - 五十七:SVG代码
<style>
line {
stroke: black;
stroke-width: 4px;
}
.line-1 {
stroke-linecap: square;
}
polyline {
fill: transparent;
stroke: black;
stroke-width: 4px;
}
</style>
<svg width="320px" height="120px" style="border: 4px solid black">
<rect width="320" height="120" x="0" y="0"></rect>
<line class="line-1" x1="-1" y1="41" x2="61.5" y2="-1"></line>
<line class="line-1" x1="321" y1="41" x2="258.5" y2="-1"></line>
<polyline points="110 40, 160 6.67, 210 40"></polyline>
<line x1="30" y1="20" x2="56" y2="37.33"></line>
<line x1="290" y1="20" x2="264" y2="37.33"></line>
<polyline points="140 60, 80 100, 20 60, 80 20, 140 60"></polyline>
<polyline points="180 60, 240 20, 300 60, 240 100, 180 60"></polyline>
<line x1="140" y1="60" x2="180" y2="60"></line>
<line class="line-1" x1="-1" y1="79" x2="61.5" y2="121"></line>
<line class="line-1" x1="258.5" y1="121" x2="321" y2="79"></line>
<polyline points="110 80, 160 113.33, 210 80"></polyline>
<line x1="30" y1="100" x2="56" y2="82.67"></line>
<line x1="290" y1="100" x2="264" y2="82.67"></line>
</svg>
图一 - 五十八
图一 - 五十八:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<!-- 中间矩形 -->
<rect x="26.67" y="20" height="80" width="266.67"></rect>
<!-- 内部矩形 -->
<rect x="80" y="40" height="40" width="160"></rect>
<!-- 垂直中线 -->
<line x1="160" y1="0" x2="160" y2="120"></line>
<!-- 水平中线 -->
<line x1="26.67" y1="60" x2="293.34" y2="60"></line>
<!-- 四角 -->
<polyline points="53.33 0, 53.33 40, 0 40"></polyline>
<polyline points="266.67 0, 266.67 40, 320 40"></polyline>
<polyline points="0 80, 53.33 80, 53.33 120"></polyline>
<polyline points="266.67 120, 266.67 80, 320 80"></polyline>
<!-- 连接柱 -->
<line x1="106.67" y1="20" x2="106.67" y2="40"></line>
<line x1="213.33" y1="20" x2="213.33" y2="40"></line>
<line x1="106.67" y1="80" x2="106.67" y2="100"></line>
<line x1="213.33" y1="80" x2="213.33" y2="100"></line>
</svg>
图一 - 五十九
图一 - 五十九:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<!-- 中间矩形 -->
<rect width="106.67" height="72" x="106.67" y="24"></rect>
<!-- 两侧半矩形 -->
<polyline points="0 24, 71.11 24, 71.11 96, 0 96"></polyline>
<polyline points="320 24, 248.89 24, 248.89 96, 320 96"></polyline>
<!-- 上侧半矩形 -->
<polyline points="35.56 0, 35.56 48, 142.22 48, 142.22 0"></polyline>
<polyline points="177.78 0, 177.78 48, 284.44 48, 284.44 0"></polyline>
<!-- 下侧半矩形 -->
<polyline points="35.56 120, 35.56 72, 142.22 72, 142.22 120"></polyline>
<polyline points="177.78 120, 177.78 72, 284.44 72, 284.44 120"></polyline>
</svg>
图一 - 六十
图一 - 六十:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<!-- 内部高矩形 -->
<rect width="213.33" height="80" x="53.33" y="20"></rect>
<!-- 内部宽矩形 -->
<rect width="266.67" height="40" x="26.67" y="40"></rect>
<!-- 水平贯穿线 -->
<line x1="0" y1="60" x2="320" y2="60"></line>
<!-- 四角小矩形 -->
<polyline points="0 20, 26.67 20, 26.67 0"></polyline>
<polyline points="320 20, 293.33 20, 293.33 0"></polyline>
<polyline points="0 100, 26.67 100, 26.67 120"></polyline>
<polyline points="320 100, 293.33 100, 293.33 120"></polyline>
<!-- 中部垂直连接柱 -->
<line x1="160" y1="40" x2="160" y2="80"></line>
<!-- 垂直连接柱 -->
<line x1="106.67" y1="0" x2="106.67" y2="40"></line>
<line x1="213.33" y1="0" x2="213.33" y2="40"></line>
<line x1="106.67" y1="80" x2="106.67" y2="120"></line>
<line x1="213.33" y1="80" x2="213.33" y2="120"></line>
</svg>
可以发现图式均具有较强的对称性,基本上可以分为左上、右上、左下、右下四个部分,绘制其一,通过翻转即可得到图式的其余部分。
这种做法需要用到SVG中的<defs>
或<symbol>
标签定义基本元素,并使用<use>
标签引用相应元素。
图一 - 六十一
图一 - 六十一:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<!-- 定义基本元素(左上角1/4图) -->
<defs>
<g id="g61Comp">
<polyline points="0 48, 128 48, 128 0"></polyline>
<polyline points="32 60, 32 24, 160 24"></polyline>
<line x1="64" y1="0" x2="64" y2="24"></line>
<line x1="128" y1="48" x2="160" y2="60"></line>
</g>
</defs>
<!-- 旋转、位移补全 -->
<use xlink:href="#g61Comp"/>
<use xlink:href="#g61Comp" style="transform: translate(320px) matrix(-1, 0, 0, 1, 0, 0);"/>
<use xlink:href="#g61Comp" style="transform: translate(320px,120px) matrix(-1, 0, 0, -1, 0, 0);"/>
<use xlink:href="#g61Comp" style="transform: translate(0,120px) matrix(1, 0, 0, -1, 0, 0);"/>
</svg>
当完整图案的构成元素存在较多重复时,SVG元素的复用可以有效减少重复代码。但是需要注意,定义的基础元素被复用时只会显示SVG图中可见的部分,不展示超出SVG画框的线条。所以,在绘制基础元素时,要保证元素的所有线条在SVG画面中可见。
图一 - 六十二
图一 - 六十二:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<symbol id="g62Comp-basic">
<polygon points="80 60, 60 80, 60 100, 100 100, 100 80"></polygon>
</symbol>
<symbol id="g62Comp">
<use xlink:href="#g62Comp-basic"/>
<use xlink:href="#g62Comp-basic" style="transform: rotate(90deg);transform-origin: 80px 60px;"/>
<use xlink:href="#g62Comp-basic" style="transform: rotate(180deg);transform-origin: 80px 60px;"/>
<use xlink:href="#g62Comp-basic" style="transform: rotate(270deg);transform-origin: 80px 60px;"/>
</symbol>
<use xlink:href="#g62Comp" style="transform: translate(-40px, -60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(40px, -60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(120px, -60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(200px, -60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(-80px);"/>
<use xlink:href="#g62Comp"/>
<use xlink:href="#g62Comp" style="transform: translate(80px);"/>
<use xlink:href="#g62Comp" style="transform: translate(160px);"/>
<use xlink:href="#g62Comp" style="transform: translate(240px);"/>
<use xlink:href="#g62Comp" style="transform: translate(-40px, 60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(40px, 60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(120px, 60px);"/>
<use xlink:href="#g62Comp" style="transform: translate(200px, 60px);"/>
</svg>
图一 - 六十三
图一 - 六十三:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<symbol id="g63Comp">
<polyline points="0 24, 64 24, 64 0"/>
<polyline points="0 60, 32 60, 32 48, 128 48, 128 0"/>
<polyline points="96 60, 96 24, 160 24, 160 60"/>
</symbol>
<!-- 旋转、位移补全 -->
<use xlink:href="#g63Comp"/>
<use xlink:href="#g63Comp" style="transform: translate(320px) matrix(-1, 0, 0, 1, 0, 0);"/>
<use xlink:href="#g63Comp" style="transform: translate(320px,120px) matrix(-1, 0, 0, -1, 0, 0);"/>
<use xlink:href="#g63Comp" style="transform: translate(0,120px) matrix(1, 0, 0, -1, 0, 0);"/>
</svg>
图一 - 六十四
图一 - 六十四:SVG代码
<svg class="svg-box" width="320px" height="120px">
<rect width="320" height="120" x="0" y="0"></rect>
<symbol id="g64Comp">
<polyline points="0 30, 128 30, 128 0"/>
<polyline points="64 30, 64 0"/>
<polyline points="32 30, 32 60, 160 60, 160 0"/>
</symbol>
<!-- 旋转、位移补全 -->
<use xlink:href="#g64Comp"/>
<use xlink:href="#g64Comp" style="transform: translate(320px) matrix(-1, 0, 0, 1, 0, 0);"/>
<use xlink:href="#g64Comp" style="transform: translate(320px,120px) matrix(-1, 0, 0, -1, 0, 0);"/>
<use xlink:href="#g64Comp" style="transform: translate(0,120px) matrix(1, 0, 0, -1, 0, 0);"/>
</svg>
参考资料
计成 原著,陈植 注释,“园冶注释”,中国建筑工业出版社,2017.