remix logo

Hacker Remix

Show HN: I created snapDOM to capture DOM nodes as images with exceptional speed

115 points by tinchox6 1 day ago | 40 comments

streptomycin 1 day ago

I've been using html2canvas for a long time in https://play.basketball-gm.com/ so I gave your library a try. It was much slower (I know your README has benchmarks saying the opposite so idk) and the result looked a lot worse.

html2canvas: https://i.imgur.com/zfSwNR1.png

snapdom: https://i.imgur.com/FxowTzp.png

Also I recommend putting the npm package name clearly in your README. I guess I don't really know what other people are doing these days, but I think most people are like me and consume packages like this from npm rather than a <script> tag.

tinchox6 1 day ago

Thank you for testing it out and sharing the screenshots!

I’ve run some performance tests using Vitest Bench, and SnapDOM was faster. I also created a few manual demos, and SnapDOM won in both speed and accuracy.

That said, I still need to run more real-world tests. So, thanks again for your help!

tinchox6 3 hours ago

I'm working on enabling a special full mode for those who don't mind the final size:

https://github.com/zumerlab/snapdom/issues/1

hirako2000 1 day ago

How can svg be faster, and especially more accurate (lets throw some IMG or CSS shadows for fun) than canvas?

kaoD 1 day ago

You can embed HTML in an SVG via foreignObject. Seems like that's exactly what the library is doing[0].

Whether that's faster or more reliable, I don't know. Seems likely to render different depending on where you view the SVG (especially out of browsers).

[0]: https://github.com/search?q=repo%3Azumerlab%2Fsnapdom%20fore...

tinchox6 1 day ago

I added to README the npm / yarn reference. Thanks!

Sephr 8 hours ago

Awesome! I was making exactly this library 13 years ago but only made it as far as creating CSS and other asset inlining+normalization tools before I ran into a few major roadblocks.

The most significant roadblock was that drawing SVG <foreignObject> with inline subresources (data: and blob: URIs) tainted canvases in Chrome and Safari, and this was partially resolved in 2019[1].

Notably, some issues still remain but apparently it's now workable. As is apparent from snapDOM, completely accurate CSS normalization is still an unsolved problem.

While I'm excited to see the HTML-in-foreignObject use case mature, it is also important to point out that the Media Capture API now has the ability to capture individual elements natively in Chrome[2].

1. https://issues.chromium.org/issues/41054640#comment49

2. https://developer.mozilla.org/en-US/docs/Web/API/CropTarget/...

jdiff 1 day ago

Capturing HTML as scalable SVGs is huge, how do you manage condensing all of CSS and its quirks into an SVG? Do you only support a subset of styling properties and rely on the browser to calculate layouts for you?

tinchox6 1 day ago

I was upset about the size of generated svg file because at first all styles were inlined in each element. So I created a function to make mini css classes (.c1, c2, c3,...) So the final size is quite small.

krebby 1 day ago

How does this compare to something like the the Media Capture API? Looks like this uses `canvas.toDataURL()` which can be slow to serialize compared to `toBlob` or `canvas.captureStream(0).getVideoTracks()`

I've been using CropTarget.fromElement with a CaptureController: https://gist.github.com/akre54/e93ab2ce27999aecb109e38085f2e...

tinchox6 1 day ago

Hi! Insaw this API when I was starting to work on snapDOM but I thought it was not ok for my needs so I discarded it. Regarding other API it would be great if View Transitions API could exposed the old view in a future

krebby 1 day ago

What were your needs that the API didn't meet?

tinchox6 1 day ago

It requires user intervention and doesn't work for me.

streptomycin 1 day ago

Looks cool, somebody should make a package that puts a nice API around it. However seems that those APIs are only in Chrome now, not Firefox or Safari.

krebby 1 day ago

IMO it's simple enough to just write directly without library code.

For most cases, the Element Capture or Region Capture API should be sufficient: https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capt...

Demos: https://mdn.github.io/dom-examples/screen-capture-api/elemen... https://mdn.github.io/dom-examples/screen-capture-api/region...

If you need cross-browser compatibility (and can't just use a canvas) then yeah html2canvas is the way to go

streptomycin 21 hours ago

idk, your code is 170 lines, html2canvas and similar are 1 line to use.

tinchox6 1 day ago

I tested it on Chrome, Firefox and Safari