SVGEditor Test
撰写时间:2024-07-06
修订时间:2026-01-07
由于输出面板中只有一个svg元素,因此要求其大小必须精准到像素级别。
SVG默认宽高值
输出面板高度值默认为150px。此外,SVGEditor使用了以下默认设置:
将box-sizing设置为border-box,可让我们在设置svg的宽高值时,不会超出输出面板的范围而出现滚动条,当我们扫动 Magic Mouse 时,不会出现晃动的感觉。
将height设置为100vh,可在不为svg元素指定height属性值、或未通过CSS设置height值、或未将result-div-height的值指定为auto时,均能自动铺满整个输出面板。
未设置宽高值
直接编写代码,无需考虑具体的宽、高值。
输出:
输出面板的区域为视口区域(这里的视口指HTML中的视口,而非SVG的viewport)。视口宽度自动拉伸,视口高度为固定的150px。
svg的宽、高自动铺满整个视口。
SVG的内容超出输出面板的范围
默认情况下,SVG使用viewport (视口) 机制来建立起两套坐标系,因此当子元素的内容超出视口范围时,它不会出现滚动条。
下面的代码绘制了一个宽度值为1500px的矩形,显然,在大多数情况下我们都无法看到其全貌。
根据SVGviewport的特点,只需通过viewBox建立起一个范围足够包含所有子元素内容的viewport,就能自动地在HTML视口中等比缩放并显示所有的内容。
编写代码:
效果:
因为未为svg显式地指定宽度、高度值,因此svg的宽度能动态地撑开整个输出面板的宽度,其高度取svg的默认高度150px。这是目标坐标系 (target coordinates)。
而svg只有一个rect子元素,其高度未超出svg的默认高度值150px,因此viewBox所建立起的viewport的高度值取150px即可。rect的宽度值为1500px,则viewBox所建立起的viewport的宽度值取值比其稍大一点,以在svg的目标坐标系的右边留出一些空白,视觉上更好看一些。
通过viewBox所建立起的viewport,称为源坐标系 (source coordinates)。这样,SVG自动帮我们将超大的内容按比例缩放至整个输出面板中。
这种方式的好处是,在svg的150px默认高度值内,我们可以随心所欲地编写代码,而svg的内容自动吸附输出面板,不会因内容太多而出现烦人的滚动条。运行代码后,根据效果来调节viewBox即可。
改变默认宽高值
通过CSS设置宽高值
又分为两种情况。第一种情况,只设置值。
这种情况不会改变输出面板的高度。如果svg的高度值超出输出面板的高度,输出面板将出现滚动条。
第二种情况,当希望改变输出面板的高度时,可将SVGEditor的result-div-height属性值设置为auto:
则:
CSS中的height值可少于svg默认高度值150px。
注:body的line-height会影响自动高度的精准计算,从而导致svg的下方会多出一点点的留白。由于该属性又是被各种子元素自动继承的属性,因此,在父类LiveEditor中,只将body自身的值初始化为0px,子元素则取默认值:
设置SVG元素的内联宽高值
有时需要为svg指定内联的宽高值,从而无需额外的CSS设置。
此时,情况变为较为复杂,主要涉及到:
- iframe与输出面板的高度如何相互适应
- CSS属性值的继承与覆盖
为此,LiveEditor引入了新的钩子方法doAfterApplyHTMLFromTab,SVGEditor调用其以进行进一步的设置。
当有任一svg元素设置了内联的宽高值时,将取消原有的自动铺满整个输出面板的设置,但为每个svg保留了block及边框的设置。
则有以下效果:
这种情况,不会改变输出面板的高度。
此时如果result-div-height的值为auto,则高度值优先取自CSS所设置的高度值;若CSS无相应的设置高度的值,再取自svg所声明的height值。这两种情况,都会钳制输出面板的高度。
较好的方式
综合以上各种方法,应用自动高度功能,再加上preserveAspectRatio,可取得非常理想的效果。
输出:
上面作法兼顾了用户体验及编写代码的便捷,具体优势为,无需额外指定CSS,用户可自行决定输出面板的宽度及高度,输出结果自动按比率缩放后在输出面板居中;编写代码只需在viewBox所指定的范围内编写即可。
若将svg的width设置为具体的数值,则可得到空间紧凑、且有清晰边框的图像。
当设置了viewBox属性值后,可以仅设置width或height其中的一个。
甚至width及height属性值一概不予指定。
这种方式,宽度将自动铺满整个输出面板,且按viewBox所指定的比例确定高度。其优点是只需指定viewBox而无需指定width及height,要编写的代码量变少了。但其缺点是,viewBox的坐标系只能限定在较小范围内,否则输出面板的高度将因太大而不好看;且一旦修改viewBox的设置值,svg各个子元素的代码也需随之修改。
综合考虑以上几种方式的利弊,最便利的方式是:
同时设置viewBox及preserveAspectRatio属性值,先保证代码比例缩放在输出面板中;然后再根据需要,仅设置width或height其中的一个值,或者同时设置。
SVGGrids
svg-editor内置支持背景网格。
在JavaScript
面板中调用:
即可。第1个参数为svg的id。第2个参数为长刻度标尺的间距(将根据此间距自动创建值为一半、但无标签的短刻度)。第3个参数表示是否绘制背景网格。待编写完SVG所有内容后,将此参数改为false,则可得到一份无背景网格、干净的图像。
SVGGrid支持viewBox属性。
两个问题。一是为何标签字体较小;二是在桌面系统中,左右有留白。
主要原因是,通过viewBox所指定的源坐标系过大,而通过width及height所指定的目标坐标系过小所导致。为了要保持源坐标系的比例,有效区域只能取width及height的最小值(SVG引擎自动计算的结果)。
解决的方法有二。
第一种解决方法是缩小源坐标系。但这会导致两个问题。
1、右下角的圆位于源坐标系的边缘,若缩小源坐标系,则该圆将被裁剪掉。
2、若仍要缩小源坐标系,则必须同步调整SVG各个子元素的坐标值。这较麻烦。并且,有时出于研究的需要,我们会将第三方的源代码粘帖进SVGEditor中以查看运行效果、调试其代码,如果该源代码较多时,一一修正各个子元素的坐标无疑是场噩梦。
因此这种方式比较笨拙。
第二种解决方法是,因上面设置了按比例居中缩放的方式,因此,左右出现留白,说明目标坐标系的水平空间很充裕,但高度不够。此时可适当加大height属性值。本例中若将height值改为标尺刻度最大值700后再运行,则上下左右均不会出现留白,这是最理想的缩放效果,字体将变大而醒目。
调整后若上下出现留白,说明height值调得过大了,将其值适当调小即可。
