SVG长度仅针对收缩而不能针对拉伸进行调整 [英] SVG lengthAdjust only for shrinking but not for stretching
问题描述
是否有一种简便易行的方法来具有 textLength ),以便在必要时缩小文本(如果太宽),但从不尝试拉伸文本?
Is there a nice and easy way to to have the functionality of lengthAdjust (together with textLength) for shrinking text if necessary (if too wide) but never attempting to stretch it?
我想到了两种通过JS生成的SVG的可能解决方案:
Two possible solutions for a SVG generated through JS come to my mind:
- 计算字符(或更确切地说是字素簇)并基于此(连同一些启发式方法,除非使用固定宽度的字体)决定是否设置
textLength
. - 首先在不设置
textLength
的情况下执行此操作,然后使用getBBox()
确定是否需要缩小文本,在这种情况下将设置textLength
.
- Count characters (or rather grapheme clusters) and based on that (together with some heuristics unless a fixed-width size font is used) determine whether to set
textLength
or not. - First do it without
textLength
set and then determine usinggetBBox()
whether the text needs some shrinking in which casetextLength
will be set.
这两种解决方案都是恕我直言的丑陋(可能是我回忆起过去与getBBox()
的接触所引起的错误).我可能错过了一些更好的解决方案吗?
Both solutions are IMHO quite ugly (and possibly buggy from my recollections of past encounters with getBBox()
). Is there maybe some nicer solution I missed?
推荐答案
看看这个: https://stackoverflow.com/a/39886640/1925631 本质上,创建一条路径,该路径跨越要在路径上散布文本的确切坐标.测量此路径.然后,以1px的字体大小(和其他所需的字体功能)测量文本所需的像素数.现在,调整字体大小以填充所需的可用路径前进宽度百分比.调整开始偏移和文本锚.现在,最后计算您的作者指定的textLength并选择一个lengthAdjust值,以在低精度/不一致的渲染器上获得精确对齐.
Have a look at this: https://stackoverflow.com/a/39886640/1925631 Essentially, make a path which spans the exact coordinates where you want to spread your text on a path. Measure this path. Then, measure how many pixels your text requires, with a font-size of 1px (and other desired font-features). Now adjust the font-size to fill your desired percentage of the available path advance width. Adjust start-offset and text-anchor. Now finally calculate your author specified textLength and choose a lengthAdjust value to get exact alignment on low precision / non-conformant renderers.
最后,如果需要在路径呈现支持上支持不带文本的查看器,则可以使用具有javascript支持的兼容查看器来创建向后兼容/后备版本.渲染内容并使用SVG DOM API获取每个字符/字形的x,y并旋转值,现在使用指定的那些属性创建一个新的SVG DOM表示形式.您可能还需要JavaScript来计算svg根元素的绝对宽度和高度,以及正确指定的viewBox,并将所有css选择器/规则/属性级联/解析/转换为内联属性.但是通过这种方式,您可以获得跨平台,跨浏览器/查看器的文本呈现,并且每个不可变的源文件版本只需一个编译步骤.
Finally, if you need to support viewers without text on a path rendering support, you can use a conformant viewer with javascript support to create a backwards compatible/fallback version. Render the content and use the SVG DOM api to fetch the x, y and rotate values for each character/glyph, now create a new SVG DOM representation with those attributes specified. You might need javascript to calculate absolute width and height for the root svg element as well, and a correctly specified viewBox, and cascade/resolve/convert all css selectors/rules/properties to inline attributes. But this way you can get cross-platform, cross-browser/viewer rendering of text, with a single compilation step per immutable source file version.
我还提出了要点,以简化最后一步,即解析CSS并删除所有className,同时保留呈现的最终结果:
I've also made a gist to ease the last step, of resolving the css and removing all classNames, while preserving the rendered end-result: https://gist.github.com/msand/4b37d3ce04246f83cb28fdbfe4716ecc
这是出于单个通用svg + javascript代码库和web + ios + android软件开发(基于react + react-native + react-native-svg)的目的
This is for the purpose of a single universal svg + javascript codebase, and web+ios+android software development (based on react + react-native + react-native-svg)
这篇关于SVG长度仅针对收缩而不能针对拉伸进行调整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!