Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Export to image #9037

Merged
merged 55 commits into from Apr 12, 2023
Merged

Feat: Export to image #9037

merged 55 commits into from Apr 12, 2023

Conversation

sprocketc
Copy link
Collaborator

@sprocketc sprocketc commented Apr 5, 2023

This PR was originally about whiteboards, but I decided to expand its functionality to blocks and pages. The initial problem was the fact that tldraw converts all shapes to SVGs to export them. In our case, converting portals to svgs would be extremely complicated, so I decided to use html2canvas.

Related to
https://discuss.logseq.com/t/whiteboards-requests/16288
https://discord.com/channels/725182569297215569/1055672588162048110/1055672588162048110

Quoting their docs

The script traverses through the DOM of the page it is loaded on. It gathers information on all the elements there, which it then uses to build a representation of the page. In other words, it does not actually take a screenshot of the page, but builds a representation of it based on the properties it reads from the DOM.

So what does this have to offer compared to simply taking a screenshot?

  • We can hide ui elements like grids and toolbars (see data-html2canvas-ignore attribute)
  • We can remove the background
  • We can export the whole page, even if it's partially out of view
  • We can limit the export to selected shapes/blocks
  • We can fix the zoom level on whiteboards

I used out existing export modal. I also added a "save to file" that should also work for preexisting formats (text, html etc).

We can now export

  • Pages (page title context menu -> Export)
    The whole page will be exported. Lazily loaded elements that are not part of the DOM yet, won't be included.
  • Single blocks (block context menu -> Copy as)
  • Whiteboards (page title context menu -> Export || Shapes context menu -> Export)
    Only selected shapes will be included. If there are no selected shapes, all of them will be exported. The visible viewport will be used, but the zoom/scale will be corrected upon export. The image bounds will also be restricted to the current selection, when we use the context menu.
  • Graphs (graph filters -> Export)
    Graphs were already rendered to a canvas, so we don't need html2canvas in this case. The reason I added this in this PR, is that exporting images of graphs with transparent background, could be useful to some users.

UI features

  • Solid/transparent background option
  • Image preview
  • Save to file button
  • Copy to clipboard button

The currently supported format is PNG. Supporting JPGs and WEBPs should be trivial. I chose PNG because it has alpha channel support, so we can have a transparent background.

Caveats

  • iFrames not supported (embedded videos, tweets). Tldraw does not support this either.
  • Some css properties are not currently supported (see https://html2canvas.hertzen.com/features/)
  • Can't export to vector based formats (PDF, SVG). We might be able to use jsPDF for that
Screencast.from.2023-04-07.20-37-23.webm

@github-actions github-actions bot added the :type/feature New feature label Apr 5, 2023
/* fixes an html2canvas issue */
img {
@apply inline-block;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor tweaks to the existing styles might be required to improve the result.

Copy link
Collaborator

@logseq-cldwalker logseq-cldwalker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sprocketc QAed all the exports and they work great! 👍 Left minor comments. When QAing any of the new export functionality it failed on publishing:

Screen Shot 2023-04-10 at 4 56 29 PM

I pushed up a fix assuming you want this functionality on publishing but feel free to also disable export on publishing or do something else

@@ -264,6 +264,7 @@
:-webkit-font-smoothing "subpixel-antialiased"}}

[:div.whiteboard-page-title-root
{:data-html2canvas-ignore true}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be useful to document or comment somewhere when to use this option and why. I saw it in the PR but having dev docs in PRs aren't easy to find

public/index.html Show resolved Hide resolved
@andelf andelf added this to the 0.9.2 milestone Apr 12, 2023
Copy link
Contributor

@tiensonqin tiensonqin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent PR!
I've QAed all the cases, and they all function perfectly!

I observed a UI inconsistency issue, the PNG button is missing when selecting multiple blocks and copy/export as.

Only the first selected block will be exported as PNG.

Additionally, the default option for "copy/export as" blocks is now PNG export, which might not align with users' preferences.

Another minor bug is that the generated title when saving a file is not user-friendly.
For pages, the lower-cased page name is used instead of its original name,
for blocks, the title example is [#uuid _64365bd1-e340-4690-ad00-6d898c214f6d_],
I suggest using logseq_{page} for any page and logseq_{timestamp} for block(s).

I recorded a video on it:
https://www.loom.com/share/8500691f9c924f4fafb0d948d0798bd4

@sprocketc
Copy link
Collaborator Author

I observed a UI inconsistency issue, the PNG button is missing when selecting multiple blocks and copy/export as.
Only the first selected block will be exported as PNG.
Additionally, the default option for "copy/export as" blocks is now PNG export, which might not align with users' preferences.

Multi-block export is not supported, but the last selected type was used. I had to reset the type on export to avoid this.

I suggest using logseq_{page} for any page and logseq_{timestamp} for block(s).

Handled.

@tiensonqin
Copy link
Contributor

@sprocketc Good to know that multiple blocks exported as PNG is not supported.

I suggest using logseq_{page} for any page and logseq_{timestamp} for block(s).

Handled.

Works as described.

@tiensonqin tiensonqin self-requested a review April 12, 2023 09:37
@tiensonqin tiensonqin merged commit 95149e1 into master Apr 12, 2023
8 checks passed
@tiensonqin tiensonqin deleted the feat/export-to-image branch April 12, 2023 09:39
bendyorke pushed a commit that referenced this pull request May 9, 2023
* feat: export to image

* chore: export selection on whiteboards

* fix: whiteboards zoom on export

* fix: loading position

* chore: support video thumb

* core: add export to  whiteboards context menu

* fix: context menu entry

* fix; copy image to clipboard

* fix: copy / export label

* fix: hide ui elements

* fix: remove random character

* fix: graph export

* chore: remove console log and jpg format

* style: run prettier

* fix: disable on multiple selected blocks

* fix: multiple blocks

* enhance: restrict bounds of selected shapes

* chore: export selection on whiteboards

* fix: whiteboards zoom on export

* chore: support video thumb

* core: add export to  whiteboards context menu

* fix: context menu entry

* fix; copy image to clipboard

* fix: copy / export label

* fix: hide ui elements

* fix: remove random character

* fix: graph export

* chore: remove console log and jpg format

* style: run prettier

* fix: disable on multiple selected blocks

* fix: multiple blocks

* enhance: restrict bounds of selected shapes

* Fix any html2canvas related functionality failing in publishing

* fix: portal header gradient on export

* chore: add comment about html2canvas-ignore attr

* fix: use export padding constant

* fix: export collapsed portals with size >  medium

* fix: reset export type

* enhance: export filename

---------

Co-authored-by: Gabriel Horner <gabriel@logseq.com>
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:type/feature New feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants