首页 > 其他分享 >深入解析SVG 标签的 viewBox属性(超详细)

深入解析SVG 标签的 viewBox属性(超详细)

时间:2024-08-15 11:54:11浏览次数:13  
标签:dom SVG 缩放 width 标签 svg 100 viewBox

解析SVG 标签的 viewBox属性

案情提要

相信小伙伴们在学习 svg标签viewBox属性 时候,无论是看w3cschool还是 MDN的官方文档,都是一头雾水。比如MDN给出的解释:viewBox 属性允许指定一个给定的一组图形伸展以适应特定的容器元素。viewBox 属性的值是一个包含 4 个参数的列表 min-x, min-y, width and height,以空格或者逗号分隔开,在用户空间中指定一个矩形区域映射到给定的元素。我当时也是尝尽了苦头,绕了很大的弯子才弄懂其中的奥秘。下面我将我的探究成果分享给大家。
先说结论
在这里插入图片描述

话不多说,直接开干

viewBox属性的值是一组相对的值,
我们首先创建一个svg标签,然后规定其宽高为300px*300px(下面我们都用这个大小的svg),绘制其边框,内部再绘制一个矩形,宽高为100px*100px(这个矩形的宽高也不变)。我们只对viewBox的值进行改变。

  1. 设置viewBox="0 0 300 300"
    <svg width="300px" height="300px" viewBox="0 0 300 300" style="border: 1px solid red;">
        <rect width="100" height="100" fill="green"></rect>
    </svg>
    

在这里插入图片描述
       这里的矩形dom为其设置的原始大小。

  1. 现在设置viewBox="0 0 100 100"
    <svg width="300px" height="300px" viewBox="0 0 100 100" style="border: 1px solid red;">
       <rect width="100" height="100" fill="green"></rect>
    </svg>
    

在这里插入图片描述

现在可以发现,第一次矩形渲染出的dom宽度 / 其原始大小 = 第一次svg的width / 第一次viewBox的width = 1;现在矩形放大到原来的3倍,此恰好svg的width / viewBox的width = 3,是不是可以猜想:svg内部的缩放比例就等同于 svg的width / viewBox的width(现在宽高都设置成比例一致的,后面再设置成不同的来探究)。下面进行验证。

  1. 设置viewBox="0 0 150 150"
    <svg width="300px" height="300px" viewBox="0 0 150 150" style="border: 1px solid red;">
    	<rect width="100" height="100" fill="green"></rect>
    </svg>
    
    在这里插入图片描述
    现在,svg的width / viewBox的width = 2,渲染出来的dom节点的宽高变为原来的2倍,遵循我们的假设。如果我们再放大一些呢(超出svg的大小)?
  2. 设置viewBox="0 0 50 50"
    <svg width="300px" height="300px" viewBox="0 0 50 50" style="border: 1px solid red;">
         <rect width="100" height="100" fill="green"></rect>
    </svg>
    
    在这里插入图片描述
    现在,svg的width / viewBox的width = 6,渲染出来的dom节点的宽高变为原来的6倍,遵循我们的假设。那如果我们将渲染出来的图形进行缩小呢?
  3. viewBox="0 0 600 600"
    <svg width="300px" height="300px" viewBox="0 0 600 600" style="border: 1px solid red;">
     	<rect width="100" height="100" fill="green"></rect>
    </svg>
    
    在这里插入图片描述
    同样的,svg的width / viewBox的width = 0.5,渲染出来的dom节点的宽高变为原来的0.5倍,遵循我们的假设。事实证明我们的假设是成立的。
    现在呢,我们想到,这个属性有四个参数,但是我们使用控制变量法,前面两个参数为0,只考虑了后面两个参数,那么前面两个参数的作用是什么呢?

追踪——前面两个参数的作用

前提:我们将原先元素的宽高设置保持不变,只改变viewBox的值。

  1. 设置viewBox="50 50 100 100"
    <svg width="300px" height="300px" viewBox="50 50 100 100" style="border: 1px solid red;">
      	<rect x="0" y="0" width="100" height="100" fill="green"></rect>
    </svg>
    

在这里插入图片描述
这时候我们会发现,渲染的dom大小好像跟之前 viewBox="0 0 100 100"时候的dom大小一致,而且在svg元素中的部分是整个dom的1/4,那么这种位置的变化规律是什么呢?我们多试几次再总结。

  1. 设置viewBox="50 50 150 150"
    <svg width="300px" height="300px" viewBox="50 50 150 150 style="border: 1px solid red;">
      	<rect x="0" y="0" width="100" height="100" fill="green"></rect>
    </svg>
    
    在这里插入图片描述
    这次我们同样看到,在svg元素中的部分是整个dom的1/4,而且渲染出的dom大小仍然遵循之前的规律。这是个巧合吗?那我们再试一组。
  2. viewBox="50 50 200 200"
        <svg width="300px" height="300px" viewBox="50 50 200 200" style="border: 1px solid red;">
          	<rect x="0" y="0" width="100" height="100" fill="green"></rect>
        </svg>
    	~~~
    

在这里插入图片描述
这次我们得到同样的结果,在svg元素中的部分是整个dom的1/4,而且渲染出的dom大小仍然遵循之前的规律。所以我们可以知道,viewBox的前面两个参数对缩放的倍数无影响。此时我们改变前两个参数试试。

  1. viewBox=" 50 100 300 300"
    <svg width="300px" height="300px" viewBox="50 100 300 300" style="border: 1px solid red;">
      	<rect x="0" y="0" width="100" height="100" fill="green"></rect>
    </svg>
    

在这里插入图片描述
这里我们发现,第一个参数控制横向移动的距离,第二个参数控制纵向的移动距离,正方向为左、上。那么移动的距离是如何计算的呢?我们发现,前面放大的倍数虽然不同,但是我们的 viewBox前两个参数没变内部 rect 元素的设置的宽高也没变,但是都是很巧合地均有 1/4 渲染在了 svg 元素中,所以这里的viewBox前两个参数效果有两种可能,要么是具体的像素值,然后在缩放之前进行移动,要么就是存在某种比例关系,在缩放之后移动。下面我们继续进行分析:

  1. viewBox="100 100 300 300"
    <svg width="300px" height="300px" viewBox="20 20 100 100" style="border: 1px solid red;">
      	<rect x="0" y="0" width="100" height="100" fill="green"></rect>
    </svg>
    

在这里插入图片描述
通过这个,如果 上述第一种假设(前两个参数是具体值,先移动,再放大)的话,移动完之后的中心点是(30,30),放大之后的被隐藏掉的部分的宽就应该是 100 * 3 - 30 = 270,但是现在是60,所以这种假设不成立。
现在来验证第二种假设,先放大,那么放大之后的中心点的坐标为(150,150),再进行移动,移动的距离为 20 /100 * 3 = 60,符合事实。那么细心的朋友就会问了,为什么之前的数据刚好对的上呢,是因为 50 这个数字,既可以在第一种假设中充当50px,又可以在后面的缩放中充当 50% 这个比例, 50% * 100 =50,这是一个巧合。
所以我们现在弄清楚viewBox四个参数的作用:后面两个与缩放的倍数有关,前面两个与缩放之后移动的比例有关。

回想——如果宽高的放大的倍数不一致呢

现在我们弄清楚了这四个参数的作用。当时我们留下一个问题,就是缩放时,宽高比不一致该如何呢?

  1. 设置viewBox="0 0 50 100"
    在这里插入图片描述
    渲染的dom的宽高是初始宽高的 3倍,这里 svg的width / viewBox的width = 6svg的height/ viewBox的height = 3,所以我们猜测是按照较小的倍数进行缩放。下面进行验证:
  2. 设置viewBox="0 0 150 100"
    在这里插入图片描述
    上述比值较小的为 2,这个也放大到了原来的 2倍。那我们要是缩小呢?
  3. 设置viewBox="0 0 600 1200"
    在这里插入图片描述
    这里比值较小的为 1/4,渲染出来的dom也是原来的 1/4,由此可以证实结论:如果对应的宽高不一致的话,那么按照比值较小的那个比例进行缩放。

(不过,细心的朋友们会发现,这里并没有在左上角对齐,这里就与<svg>的另一个属性preserverAspectRatio有关系了,这里我们先不讨论)

结案

我们终于将“案情”查了个水落石出,下面就来对“案子”进行总结:
假设有如下svg元素:

<svg width="width-1" height="height-1" viewBox="min-x min-y width-2 height-2">
	/* 内部元素…… */
	<rect width="width-3" height="height-3" fill="green"></rect>
</svg>

那么,内部元素就会先按照 width-1 / width-2height-1 / height-2较小的那个比例进行缩放(假设这个较小的比例为 m),然后在缩放的基础上,水平方向上移动 min-x / width-3 * m 个像素,正值向左移动,负值向右移动,竖直方向上移动 min-y / height-3 * m 个像素,正值向上移动,负值向下移动(这两个方向与通常情况下的坐标系的正方向相反)。最后感谢大家能够看到这里,不妨留下一个三连吧✨!

标签:dom,SVG,缩放,width,标签,svg,100,viewBox
From: https://blog.csdn.net/m0_73777400/article/details/141190827

相关文章

  • JS脚本内追加的标签无法触发事件问题处理
    通过JS追加的标签无法触发事件时,就把事件挂载给这个标签父级标签,如下。//后追加标签事件不生效,挂载在父级标签varparentElement=document.getElementById('layout_detail_toolbar_0');parentElement.addEventListener('change',function(event){letta......
  • svg 图标设置背景颜色
    是的,你可以设置背景图片和渐变颜色的组合。要实现这一点,你可以使用background属性同时指定background-image和background渐变,并结合background-blend-mode进行混合。以下是如何实现的例子:.element{background-image:linear-gradient(toright,rgba(255,0,0,......
  • 12.无语义标签,字符实体
    一.无语义布局标签 顾名思义,这个标签就是单纯用来划分区域布局,并没有什么功能,有<div>还有<span>标签,<div>标签独占一行,<span>标签则不换行<div>这是div</div><div>这是div</div><span>这是span标签</span><span>这是span标签</span>这就是这两个标签的效果,先知......
  • bugbountyhunter scope BARKER:第十滴血 存储型 Storage Cross-Site Scripting XSS 添
    登录后点击MemberDogs,Addyourdog头像处可以上传SVG图片检查xsspayload:https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSSInjection#xss-in-files使用SVG进行图片上传,发现SVG文件上传成功并返回图片地址poc:https://cfceb12f2bfd-sec875.a.barker......
  • bugbountyhunter scope BARKER:第九滴血 存储型 Storage Cross-Site Scripting XSS SVG
    登录后来到Myprofile页面,页面里存在一个EditProfile头像处可以上传SVG图片检查xsspayload:https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSSInjection#xss-in-files使用SVG进行图片上传,发现SVG文件上传成功并返回图片地址poc:https://cfceb12f2......
  • bugbountyhunter scope BARKER:第八滴血 存储型 Storage Cross-Site Scripting XSS SVG
    登录后来到home页面,留言中存在一个Attachimage检查xsspayload:https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSSInjection#xss-in-files使用SVG进行图片上传,发现SVG文件上传成功并返回图片地址poc:https://cfceb12f2bfd-sec875.a.barker-social.com......
  • 智能车创意组地平线赛道--Yolov5数据集标注xml文件时统一标签问题
    废话不多说,直接给出代码。'''通过解析xml文件,批量修改xml文件里的标签名称,比如把标签zero改成num'''importos.pathimportglobimportxml.etree.ElementTreeasETpath=r'D:\test'#存储标签的路径,修改为自己的Annotations标签路径forxml_fileinglob.glob(pa......
  • html标签
    目录1.1什么是网页1.2什么事HTML1.3网页的形成1.4网页总结浏览器内核Web标准(重点)3.1为什么需要web标准3.2web标准的构成hTML语法规范1.1基本语法概述1.2标签关系html基本结构标签2.1第一个html网页文档类型声明标签3.1文档类型声明标签3.2lang语言种类3.3字......
  • 浏览器标签页多行显示:使用Floorp浏览器 最先进的跨平台 Firefox 衍生品 开源之光
    浏览器打开了很多标签页,查看需要滚动 这查找效率就不是O(1)了,比如在编辑器中标签页直接多行显示 找了解决方案平常的主力浏览器是Firefoxchromesafarifirefoxfirefox之前有拓展TabMix可以用,现在弄得跟孙子似得,官方拓展不承认还要安装还要好的步骤,也没成功还有就是使......
  • 如何使用 beautifulsoup4 选择部分 HTML 标签进行网页抓取
    这是我试图从中抓取数据的网站的链接:https://www.fotmob.com/leagues/47/stats/season/20720/players/goals/premier-league我想使用beautifulsoup4选择class='css-653rx1-StatsContainereozqs6r5'的部分。在您提到find()和find_all()之前,我已经使用了两......