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

CSS Animations edge case: Race Condition in calculateDimensionsWithPadding Affecting ViewBox Calculation #6146

Open
Vanuan opened this issue Dec 21, 2024 · 3 comments
Labels
Status: Triage Needs to be verified, categorized, etc Type: Bug / Error Something isn't working or is incorrect

Comments

@Vanuan
Copy link

Vanuan commented Dec 21, 2024

Description

There is a race condition that causes incorrect results when calculating the viewBox in the calculateDimensionsWithPadding function. Specifically, when trying to calculate the dimensions of the SVG after rendering, the bounding box values (getBBox()) are returned incorrectly, resulting in a viewBox with incorrect height (for example, 2036).

This happens when the SVG has not yet been fully rendered or its dimensions have not been updated properly by the time the calculation occurs.

Steps to reproduce

  1. Initialize an SVG element using Mermaid (or another library that dynamically generates SVG content).
  2. Add a breakpoint after the calculateDimensionsWithPadding function.
  3. Check the viewBox attribute of the SVG element after calling setupViewPortForSVG.
  4. The viewBox might incorrectly show a very large height, such as 2036, which doesn't match the actual size of the rendered SVG.
  5. Add a breakpoint before calculateDimensionsWithPadding, and observe that the correct values are returned when paused, but not when running without the breakpoint.

Screenshots

No response

Code Sample

No response

Setup

No response

Suggested Solutions

To resolve the race condition:

  • Use requestAnimationFrame or another method to ensure that the SVG is fully rendered before calculating its bounding box (getBBox()). This will ensure the dimensions are accurate and prevent issues where the viewBox is incorrectly set.
  • Alternatively, check for SVG readiness before calculating the bounding box by either waiting for the SVG rendering to complete or retrying after a short delay.

Example fix:

// Use requestAnimationFrame to ensure that the SVG is fully rendered before calculating dimensions
requestAnimationFrame(() => {
  const { width, height, x, y } = calculateDimensionsWithPadding(svg, padding);
  configureSvgSize(svg, height, width, useMaxWidth);
  const viewBox = createViewBox(x, y, width, height, padding);
  svg.attr('viewBox', viewBox);
});

Additional Context

  • The issue seems to be related to the Mermaid rendering process, which generates SVGs asynchronously. The getBBox() function might not return accurate values if the SVG is not yet fully rendered or updated when the function is called.
  • Adding breakpoints and pausing the execution shows that the correct values are available after the SVG is fully rendered.
@Vanuan Vanuan added Status: Triage Needs to be verified, categorized, etc Type: Bug / Error Something isn't working or is incorrect labels Dec 21, 2024
@Vanuan
Copy link
Author

Vanuan commented Dec 21, 2024

The culprit is here:

const bounds = svg.node()?.getBBox() || { width: 0, height: 0, x: 0, y: 0 };

@Vanuan
Copy link
Author

Vanuan commented Dec 21, 2024

This might me the root cause of many issues here, related to incorrect zooming or positioning.

@Vanuan
Copy link
Author

Vanuan commented Dec 21, 2024

Found a workaround:

svg, svg * {
  transition: none !important;
}

This issue happens in Storybook, where all transitions are animated.

@Vanuan Vanuan changed the title Race Condition in calculateDimensionsWithPadding Affecting ViewBox Calculation CSS Animations edge case: Race Condition in calculateDimensionsWithPadding Affecting ViewBox Calculation Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Triage Needs to be verified, categorized, etc Type: Bug / Error Something isn't working or is incorrect
Projects
None yet
Development

No branches or pull requests

1 participant