

SVG 绘制自适应的菱形
source link: https://segmentfault.com/a/1190000041618406
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

欢迎关注我的公众号:前端侦探
最近在某思看到这样一个问题:需要绘制一个自适应尺寸的菱形,并且还有边框,一般在流程图中很常见,效果如下
如果没有边框的话,用 CSS clip-path 也能很方便的裁剪出一个菱形,但是边框不太好处理(通常用嵌套一层的方式或者投影来模拟,但是效果不太好),这里介绍一个 SVG 方式,充分利用缩放特性来实现这样一个效果
一、SVG 从何而来
SVG 通常都不需要手写代码(除少量基本形状以外),一般都可以用设计软件生成(SVG 在设计之初就是给机器看的,非常不利于人工阅读)。比如,我这里是用 Figma 绘制的(一个多边形就搞定),随便什么尺寸都行
然后就得到了这样一段 SVG
<svg width="167" height="90" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/> </svg>
在浏览器中效果如下
二、SVG 的缩放特性
现在 SVG 有一个默认尺寸,如果手动改变 SVG 的默认尺寸,如下
是不是有点类似于object-fit:contain
的效果?如果想整个铺满,强制拉伸该怎么做呢?这里需要用到 SVG 的缩放属性preserveAspectRatio,表示当 SVG 的实际尺寸和viewBox
尺寸不一致时的缩放规则,有点类似于 object-fit
和 object-position
组合。这里的取值非常多,默认值是xMidYMid,表示强制等比缩放,并且居中对齐。
有兴趣的可以参考这篇文章:理解SVG viewport,viewBox,preserveAspectRatio缩放,案例非常详细
这里我们不需要等比缩放,可以直接设置为none
<svg preserveAspectRatio="none"> ... </svg>
三、SVG 的描边缩放
在设置不等比缩放后,其实描边还有一点小问题,不同尺寸下,描边的粗细不同,如下
有没有办法让描边不会跟随 SVG 尺寸缩放呢?当然也是有的!SVG 中有一个属性 vector-effect可以控制描边不缩放,永远保持默认设置的尺寸,有兴趣的可以参考这篇文章 CSS vector-effect与SVG stroke描边缩放,这里只需要在 path
添加属性vector-effect="non-scaling-stroke"
就行了,表示描边不跟随缩放,如下
<svg preserveAspectRatio="none"> <path vector-effect="non-scaling-stroke">...</path> </svg>
这样就实现了一个自适应尺寸的菱形了,描边也不会缩放,完整 SVG 代码如下
<svg width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg"> <path vector-effect="non-scaling-stroke" d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/> </svg>
四、SVG 内联 base64
通常情况下,这样一个图形用作背景图更为合适(SVG代码放在页面上不太美观)。让人惊讶的是,将 SVG 转换成 base64 后,以上特性仍然是存在的。这里使用张鑫旭老师的 SVG在线压缩合并工具,如下
转换后,将这段 base64 直接用作背景就行
div{ background: url('data:image/svg+xml;base64,PHN2ZyBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIiB2aWV3Qm94PSIwIDAgMTY3IDkwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIHZlY3Rvci1lZmZlY3Q9Im5vbi1zY2FsaW5nLXN0cm9rZSIgZD0iTTIuMTA4IDQ1TDgzLjUgMS4xMzYgMTY0Ljg5MiA0NSA4My41IDg4Ljg2NCAyLjEwOCA0NXoiIGZpbGw9IiNGRkVDQzciIGZpbGwtb3BhY2l0eT0iLjYiIHN0cm9rZT0iI0ZGQjIwMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+') }
这样就得到了一个自适应的菱形背景了
当然,转换成 base64 后就不能实时修改颜色了,需要整体替换
完整代码可以访问 SVG diamond
五、总结一下
从这个例子就可以看出 SVG 的天然优势了,特别是描边的缩放特性,如果用 CSS 来绘制估计要遇到不少麻烦。这里总结一下实现要点:
- SVG 一般通过设计软件绘制导出就行,不需要手写
- SVG 默认是保持原比例缩放的,可以通过 preserveAspectRatio 修改缩放规则
- SVG 描边的粗细默认会跟随整体尺寸缩放,可以通过 vector-effect 设置保持原始大小
- SVG 在转成 base64 后仍然具备以上特性,更适合用作背景图片
SVG 一直在图形绘制上更具优势,特别是这类几何图形,缩放、自适应更加灵活,如果 CSS 实现有困难,不妨考虑一下 SVG。最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤
欢迎关注我的公众号:前端侦探
Recommend
-
116
36氪首发 |「无学网络」完成数百万元天使轮融资,相比教学管理系统更想输出管理方法与自适应学习韩旭·2017-11-07 23:41系统沉淀的数据将会随着时间推移慢慢...
-
100
在各大平台几乎都能用到而十分受欢迎的 Google Maps,一直以来都持续有在进化。这次,Google 理解到了其实根据使用者的不同旅程方式,是可以给予他们更专注需求的图资,让人更容易在复杂的路线资料中快速找到需要的信息。例如,假若你正在搭乘大众交通工具,那么加...
-
170
Web自适应布局你需要知道的所有事儿 2017年12月05日 02:40 · 阅读 20762
-
138
website upgrading… 京ICP备110065...
-
71
rem——更好的适配移动端。这个单位我一直想弄个究竟,今天终于看了个差不多。看了很多的博客。心中总算有自己的想法。(还有vh,vw这里我这个小白还没有弄明白就先不写了。) 1.rem可以在html,body下设置font-size的大小,然后根据 根元素的大小
-
97
404 | 百度EUX 页面搬家啦,点...
-
27
我在GitChat上最新开通了一个Chat,主题为:限界上下文的菱形对称架构。为有利于搜索,更名为:领域驱动设计的菱形对称架构,但主要针对的是领域驱动设计...
-
15
英菲尼迪QX60 5月28日 11:57 采...
-
6
领域驱动架构篇—菱形对称架构领域驱动设计中,对于架构风格有一个指导思想:不同的限界上下文,根据其领域模型和业务特征,可以选用不同的架构风格。在传统的分层架构与领域驱动理念相结合的过程中,产生了多种架构风格:六边型架构、整洁架构、...
-
7
4个SVG绘制工具推荐,设计师都在用! 更新时间:2023-08-22 17:53:29 设计大佬都在用的 SVG 绘制工具推荐:即时设计、Sketch、Justinmind、Inkpad,让我看看到底...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK