felixfbecker / dom-to-svg

Library to convert a given HTML DOM node into an accessible SVG "screenshot".
MIT License
383 stars 44 forks source link

Text size does not scale corretly #167

Open ghost opened 3 years ago

ghost commented 3 years ago

Hi, When exporting DOM elements, everything works well except the Text elements in the SVG are not scaled properly, the position is correct but it's warped because of wrong size (too big).

felixfbecker commented 3 years ago

Could you post a screenshot and the SVG output?

ghost commented 3 years ago

Thats how its supposed to look like: correct Thats how its looking like: incorrect

I also just noticed that the border radius is somewhat off but that's no problem in my particular case

felixfbecker commented 3 years ago

Could you share the SVG? And which browser were you using?

ghost commented 3 years ago

Using chrome.

<g data-tag="div" id="react-flow__node11" class="react-flow__node react-flow__node-valveNode selectable" data-z-index="3" data-stacking-context="true" aria-owns="iqm-node8">
                                <g data-tag="div" id="iqm-node8" class="iqm-node" data-z-index="auto" data-stacking-context="true" aria-owns="react-flow__handle21 react-flow__handle22 div36">
                                    <g data-stacking-layer="rootBackgroundAndBorders">
                                        <rect width="70.46246337890625" height="55.6907958984375" x="718.4822387695312" y="408.3946838378906" fill="rgb(140, 174, 209)" stroke="rgb(34, 78, 122)" stroke-width="1px" rx="10" ry="10"/>
                                    </g>
                                    <g data-tag="div" id="react-flow__handle21" class="react-flow__handle react-flow__handle-left nodrag target connectable" data-z-index="auto" data-stacking-context="true">
                                        <g data-stacking-layer="rootBackgroundAndBorders">
                                            <rect width="2.0374755859375" height="2.0374755859375" x="717.1239624023438" y="435.2213439941406" fill="rgb(85, 85, 85)" stroke="rgb(255, 255, 255)" stroke-width="1px" rx="1.01873779296875" ry="1.01873779296875"/>
                                        </g>
                                    </g>
                                    <g data-tag="div" id="react-flow__handle22" class="react-flow__handle react-flow__handle-right nodrag source connectable" data-z-index="auto" data-stacking-context="true">
                                        <g data-stacking-layer="rootBackgroundAndBorders">
                                            <rect width="2.0374755859375" height="2.0374755859375" x="788.2655029296875" y="435.2213439941406" fill="rgb(85, 85, 85)" stroke="rgb(255, 255, 255)" stroke-width="1px" rx="1.01873779296875" ry="1.01873779296875"/>
                                        </g>
                                    </g>
                                    <g data-tag="div" id="div36" data-z-index="auto" data-stacking-context="true" aria-owns="div37 div38 iqm-node-content8">
                                        <g data-tag="div" id="div37" data-z-index="auto" data-stacking-context="true" aria-owns="b8">
                                            <g data-tag="b" id="b8" data-z-index="auto" data-stacking-context="true">
                                                <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="20px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="700" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                    <tspan xml:space="preserve" x="722.2175903320312" y="419.9403381347656" textLength="41.6619873046875" lengthAdjust="spacingAndGlyphs">valveNode29</tspan>
                                                </text>
                                            </g>
                                        </g>
                                        <g data-tag="div" id="div38" data-z-index="auto" data-stacking-context="true" aria-owns="i8">
                                            <g data-tag="i" id="i8" data-z-index="auto" data-stacking-context="true">
                                                <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="14px" font-stretch="100%" font-style="italic" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                    <tspan xml:space="preserve" x="722.2175903320312" y="427.4110412597656" textLength="22.3060302734375" lengthAdjust="spacingAndGlyphs">Regelventil</tspan>
                                                </text>
                                            </g>
                                        </g>
                                        <g data-tag="div" id="iqm-node-content8" class="iqm-node-content" data-z-index="auto" data-stacking-context="true" aria-owns="img8 iqm-node-values8">
                                            <g data-tag="img" id="img8" data-z-index="auto" data-stacking-context="true">
                                                <g data-stacking-layer="rootBackgroundAndBorders"/>
                                                <g data-stacking-layer="childStackingContextsWithNegativeStackLevels"/>
                                                <g data-stacking-layer="inFlowNonInlineNonPositionedDescendants"/>
                                                <g data-stacking-layer="nonPositionedFloats"/>
                                                <g data-stacking-layer="inFlowInlineLevelNonPositionedDescendants"/>
                                                <g data-stacking-layer="childStackingContextsWithStackLevelZeroAndPositionedDescendantsWithStackLevelZero"/>
                                                <g data-stacking-layer="childStackingContextsWithPositiveStackLevels"/>
                                                <image id="img8-image" xlink:href="http://localhost:3000/symbols/02.0_controlValve_2way_transparent.svg" x="722.2175903320312" y="446.7669982910156" width="13.5831298828125" height="13.5831298828125"/>
                                            </g>
                                            <g data-tag="div" id="iqm-node-values8" class="iqm-node-values" data-z-index="auto" data-stacking-context="true" aria-owns="div39 div40">
                                                <g data-tag="div" id="div39" data-z-index="auto" data-stacking-context="true" aria-owns="br57 br58 br59 sub8 br60">
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="739.196533203125" y="435.2213439941406" textLength="9.30120849609375" lengthAdjust="spacingAndGlyphs">Q =</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br57" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="739.196533203125" y="443.3712158203125" textLength="6.39361572265625" lengthAdjust="spacingAndGlyphs">dp</tspan>
                                                    </text>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="745.5901489257812" y="443.3712158203125" textLength="5.205078125" lengthAdjust="spacingAndGlyphs"> =</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br58" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="739.196533203125" y="451.5210876464844" textLength="10.12896728515625" lengthAdjust="spacingAndGlyphs">Hub</tspan>
                                                    </text>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="749.3255004882812" y="451.5210876464844" textLength="5.205078125" lengthAdjust="spacingAndGlyphs"> =</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br59" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="739.196533203125" y="459.67095947265625" textLength="3.04559326171875" lengthAdjust="spacingAndGlyphs">P</tspan>
                                                    </text>
                                                    <g data-tag="sub" id="sub8" data-z-index="auto" data-stacking-context="true">
                                                        <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="12px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                            <tspan xml:space="preserve" x="742.2421264648438" y="460.3501281738281" textLength="8.68572998046875" lengthAdjust="spacingAndGlyphs">Hydr</tspan>
                                                        </text>
                                                    </g>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)">
                                                        <tspan xml:space="preserve" x="750.9278564453125" y="459.67095947265625" textLength="5.205078125" lengthAdjust="spacingAndGlyphs"> =</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br60" data-z-index="auto" data-stacking-context="true"/>
                                                </g>
                                                <g data-tag="div" id="div40" data-z-index="auto" data-stacking-context="true" aria-owns="br61 br62 br63 br64">
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)" visu-simple-live-value="">
                                                        <tspan xml:space="preserve" x="759.5287475585938" y="435.2213439941406" textLength="25.68060302734375" lengthAdjust="spacingAndGlyphs">########</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br61" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)" visu-simple-live-value="">
                                                        <tspan xml:space="preserve" x="759.5287475585938" y="443.3712158203125" textLength="25.68060302734375" lengthAdjust="spacingAndGlyphs">########</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br62" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)" visu-simple-live-value="">
                                                        <tspan xml:space="preserve" x="759.5287475585938" y="451.5210876464844" textLength="25.68060302734375" lengthAdjust="spacingAndGlyphs">########</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br63" data-z-index="auto" data-stacking-context="true"/>
                                                    <text color="rgb(34, 78, 122)" dominant-baseline="text-after-edge" font-family="-apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, &quot;Noto Sans&quot;, &quot;Liberation Sans&quot;, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(34, 78, 122)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="none" fill="rgb(34, 78, 122)" visu-simple-live-value="">
                                                        <tspan xml:space="preserve" x="759.5287475585938" y="459.67095947265625" textLength="25.68060302734375" lengthAdjust="spacingAndGlyphs">########</tspan>
                                                    </text>
                                                    <g data-tag="br" id="br64" data-z-index="auto" data-stacking-context="true"/>
                                                </g>
                                            </g>
                                        </g>
                                    </g>
                                </g>
                            </g>
ghost commented 3 years ago

Just double checked on edge and firefox. Same problem. Its actually only the text height that's off, width seem alright

ghost commented 3 years ago

@felixfbecker do you have an idea what can cause this? So i can look for my own, need to fix this asap...

felixfbecker commented 3 years ago

Sorry I don't have enough context. What website was this on? Can you share the URL, or a webarchive of it?

There are many different factors that could cause this. We use the browser's APIs to get positioning of elements. This gets hairy especially when there are nested SVGs, or when there are CSS transforms applied. There are even browser bugs in the implementation of those APIs we work around.

ghost commented 3 years ago

This is from a web app I build for a client currently, therefore it's hard to share the actual website. Basically i use react-flow to build a flow, i then use query selectors to extract certain parts of that flow. The edges are already svg, the nodes are DOM, so I want to convert them to svg using your library (This is my original discussion at the react flow github https://github.com/wbkd/react-flow/discussions/1139#discussion-3338598). If you have further question I can try to mock a similar situation. Thanks in advance!

ci7lus commented 2 years ago

I have encountered this issue in several tweets.

Example: https://twitter.com/TwitterSpaces/status/1451239134798942208 Actual: image

ghost commented 2 years ago

I Actually found a workaround:

You can get the zoom factor from the Provider, use it to scale the font height in the generated svg on the nodes. This way its all proportional.

3rd commented 11 months ago

Made it export perfectly for https://tsdiagram.com by using an iframe, if anyone needs this check out: https://github.com/3rd/tsdiagram/blob/dbd7cdfbe445c2b16a6159b2c822429b4e681639/src/utils/svg-export.ts