tldraw / tldraw

SDK for creating whiteboards and canvas experiences on the web.

Home Page:https://tldraw.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: viewportScreenBounds calculated wrong after load a snapshot from different screen size

merobal opened this issue · comments

What happened?

We have a content editor inside our page (a worksheet for students). We call editor.zoomToFit() after saving the image / clicking on cancel, and it works (almost) well with v2.0, but it's totally broken with v2.1

How can we reproduce the bug?

I posted a video about it on Discord

What browsers are you seeing the problem on?

Chrome

Contact Details

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

https://stackblitz.com/edit/vitejs-vite-jnqyji?file=src%2FApp.tsx

  1. Edit
  2. Draw something
  3. Save
  4. Resize the screen
  5. Edit again
  6. Cancel (loads back the saved snapshot from different viewport size)
  7. Edit again => broken

Hi! Sorry for the delay in getting back to you.

This issue is caused by using the 'all' option when calling editor.store.getSnapshot('all'). This saves literally all of the information in the in-memory store, which includes session-specific stuff like the viewport size, or which shape is currently being hovered over, and so on. For lots of this data it doesn't make sense to serialize and reinstate it blindly.

If you need to persist certain bits of UI state (camera position, current page, which shapes are selected, etc) then we have some separate tools for persisting and reloading this kind of 'session' state (look for the substring sessionState in this file), but they're currently not documented well and the api is not as user-friendly as it could be. I'm going to change that because you're not the first person to run into this kind of issue.

In the meantime it looks like the app you've linked doesn't need that so you can probably just remove the 'all' param.

Hi! Sorry, I just posted a very few pieces of info here, but we discussed this in detail on Discord and found the workaround, too!

So even call getSnapshot without the param all the same bug happens.

But calling this snippet after loadSnapshot fixes the issue:

    const rect = container.current.getBoundingClientRect();
    const next = new Box(
      rect.left || rect.x,
      rect.top || rect.y,
      Math.max(rect.width, 1),
      Math.max(rect.height, 1)
    );
    editor.updateViewportScreenBounds(next);

@MitjaBezensek led me to find this solution.

The actual fix could be a higher-level editor.load functionality or just mentioning this snippet in the snapshots docs (or just creating a dedicated public API for this snippet to call as a single line).