fskpf / svg2roughjs

Create sketchy, hand-drawn-like images from SVGs
https://fskpf.github.io/
MIT License
158 stars 13 forks source link

text on svg from mermaidjs does not appear #77

Closed holeybit closed 2 years ago

holeybit commented 2 years ago

Was hoping to pass flowchart created by mermaidjs, but it seems the text is not getting thru. Maybe due to the use of foreignObject tag instead of text?

<svg id="graph-div" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="60" style="max-width: 170.984375px;" viewBox="0 0 170.984375 60"><style>#graph-div {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#graph-div .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#graph-div .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#graph-div .edge-thickness-normal{stroke-width:2px;}#graph-div .edge-thickness-thick{stroke-width:3.5px;}#graph-div .edge-pattern-solid{stroke-dasharray:0;}#graph-div .edge-pattern-dashed{stroke-dasharray:3;}#graph-div .edge-pattern-dotted{stroke-dasharray:2;}#graph-div .marker{fill:#0b0b0b;stroke:#0b0b0b;}#graph-div .marker.cross{stroke:#0b0b0b;}#graph-div svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#graph-div .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#graph-div .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#graph-div .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#graph-div .label text,#graph-div span{fill:#333;color:#333;}#graph-div .node rect,#graph-div .node circle,#graph-div .node ellipse,#graph-div .node polygon,#graph-div .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#graph-div .node .label{text-align:center;}#graph-div .node.clickable{cursor:pointer;}#graph-div .arrowheadPath{fill:undefined;}#graph-div .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#graph-div .flowchart-link{stroke:#0b0b0b;fill:none;}#graph-div .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#graph-div .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#graph-div .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#graph-div .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#graph-div .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#graph-div div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid undefined;border-radius:2px;pointer-events:none;z-index:100;}#graph-div :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"></g><g class="edgeLabels"></g><g class="nodes"><g class="node default" id="flowchart-A-126" transform="translate(85.4921875,30)" style="opacity: 1;"><rect rx="5" ry="5" x="-77.4921875" y="-22" width="154.984375" height="44" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-67.4921875,-12)"><foreignObject width="134.984375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Hello Svg2Rough.js</div></foreignObject></g></g></g></g></g></g></svg>

https://mermaid-js.github.io/mermaid-live-editor/view#pako:eNo1jcEKwjAQRH8l7EmhePCYm1DBs_W4l7VZkkiTlHQjSOm_u1Kc08zwhllhLI7Bgq80B_PoMRvV5XDjaSpmePvzvTQfTq_liBk6SFwTRaeL9YciSODECFbtkxZ1mDfl2uxI-OqilApWauMOqEkZPnn8553pI-l52svtC02KMJs

ygra commented 2 years ago

Yeah, we don't handle foreignObject. Which, frankly, is a bit complicated as well, since it basically is an island of HTML content in the middle of SVG. Writing an SVG renderer isn't easy already. Doing the same for HTML get even worse, sadly.

Perhaps we could try at least injecting the chosen font, since Comic Sans everywhere is a necessity, right?

fskpf commented 2 years ago

I guess it shouldn't be too hard to just include the foreignObject in the resulting sketch (at least for SVG output), albeit not sketched then. This may be sufficient for text content and we could even try to inject Comic Sans FTW.

I've toyed around with it and noticed that mermaid seems to use viewBox scaling which is currently not really supported, so that the result is scaled differently. I've created a separate issue for this: #78

Once this is fixed, I'll give the foreignObject a shot.

fskpf commented 2 years ago

@holeybit I've pushed a simple implementation for the foreignObject elements and updated https://fskpf.github.io/ Please try it there with more, common mermaid samples and post your feedback. I'd expect some artefacts, because the current implementation is still very superficial.

The implementation just copies the foreignObject to the output SVG, thus it's only rendered for the SVG output. That said, this entire foreignObject element is problematic, because it often relies on CSS rules that don't apply anymore after the sketching (due to the remodeling of the output DOM).

To better support the given mermaid sample, I've inlined font related CSS rules directly on the output element. To fix this more thoroughly, the CSS inlining should be done recursively on the entire foreignObject and all (not just font related) properties.

About applying Comic Sans: The foreignObject's overflow defaults to hidden which clips the Comic Sans text most likely. Unconditionally setting overflow to visible is not really an option IMO because the foreignObject may contain anything...

holeybit commented 2 years ago

@fskpf and @ygra -- thank you!! I was actually browsing the source tree about an hour ago (maybe less) and saw foreign-object.ts in geom and though 'hmm, there is something here...'

I tested a few other diagrams that I made from mermaid, they are all look good. Appreciate the added feature. As far as I can tell, svg2roughjs has the best looking implementation out of a handful of options that I was looking at. Thanks again!

fskpf commented 2 years ago

Thank you for your feedback! I've released the fix as new version (https://github.com/fskpf/svg2roughjs/releases/tag/v2.3.0), so I'd consider this closed. If you find some odd artefacts please open a new issue then.