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

Can not capture the deault content inside a slot, and styling of progress bar is missing #470

Open
cWenyu opened this issue Jul 30, 2024 · 1 comment
Labels

Comments

@cWenyu
Copy link

cWenyu commented Jul 30, 2024

Missing default slot content and progress element styling

I have a sample page that includes basic HTML elements, shadow dom, slots, and a progress bar, and I want to convert the DOM element into an image but the result is wrong. The default content (text, div) inside the slot is missing and also the styling of the progress bar is wrong.

Expected Behavior

Convert the default slot content and capture the progress bar styling, as image below:
image

Current Behavior

htmlToImage (1)

Possible Solution

To solve the content inside the slot, need to check if the slot element has child elements and attach theme to children Array:

children = toArray<T>(nativeNode.assignedNodes())

I don't have the solution yet for the progress bar.

Steps To Reproduce

Copy the following code into index.html and open the file in Chrome or Firefox, click button, and an image will be downloaded.

<!DOCTYPE html>
<html>

<head>
  <title>Copy HTML to Clipboard</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html-to-image/1.11.11/html-to-image.min.js"></script>
  <style>
    #content-to-copy {
      background-color: white;
      width: 300px;
      height: fit-content;
      border: 1px solid #000;
      padding: 20px;
    }

    h1 {
      background-color: blue;
      color: chartreuse;
    }

    #shadow-host {
      margin: 20px 0;
    }

    #lightdom-div {
      background-color: #000;
      color: aliceblue;
    }
  </style>
</head>

<body>
  <div id="content-to-copy">
    <h1>Hello World</h1>
    <p>This is a sample content with <strong>HTML</strong> elements.</p>
    <div id="shadow-host"></div>

    <!-- Define the custom element -->
    <my-element>
      <div slot="content" id="lightdom-div">Slotted div element inside custom element shadow dom</div>
    </my-element>

    <!-- progress tag -->
    <label for="file">Progress bar</label>
    <progress id="file" value="32" max="100"> 32% </progress>
  </div>
  <button id="download-button">Download HTML as Image</button>
  <script>

    // Define a class for the custom element
    class MyElement extends HTMLElement {
      constructor() {
        super();
        const shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `
        <style>
            div {
              color: blue;
              border: 1px solid black;
              padding: 10px;
              margin: 10px;
            }

            slot[name='title'] > *{
              color: purple;
              background-color: aqua;
            }
          </style>

          <span>Custom Element</span>
          <div>
            <slot name="title">
              <div>A div element inside title slot.</div>
            </slot>
            
            <slot name="content"></slot>

            <slot name="footer">Default footer content</slot>
          </div>
        `;
      }
    }

    // Register the custom element
    customElements.define('my-element', MyElement);

    const body = document.querySelector('body');

    const shadowHost = document.querySelector('#shadow-host');
    const shadowRoot = shadowHost.attachShadow({ mode: 'open', slotAssignment: 'manual' });

    // shadow div
    const shadowContent = document.createElement('div');
    shadowContent.id = 'shadow-content';
    shadowContent.textContent = 'Attached shadow DOM content';

    // append slot elements
    shadowRoot.appendChild(shadowContent);

    const content = document.querySelector('#content-to-copy');

    function downloadElementAsImg() {
      htmlToImage.toCanvas(content).then(canvas => {

        // create a link and download image
        const a = document.createElement('a');

        canvas.toBlob((blob) => {
          const url = URL.createObjectURL(blob);

          a.download = "htmlToImage.png";
          a.href = url;
          a.style.display = 'none';
          body.appendChild(a);
          a.click();

          body.removeChild(a);
        });
      });
    }

    document.getElementById('download-button').addEventListener('click', downloadElementAsImg);
  </script>
</body>

</html>

Your Environment

  • html-to-image: 1.11.11
  • OS: Windows
  • Browser: Chrome 126.0.6478.185, Firefox 128.0.2
@cWenyu cWenyu added the bug label Jul 30, 2024
@biiibooo
Copy link
Contributor

biiibooo bot commented Jul 30, 2024

👋 @cWenyu

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it.
To help make it easier for us to investigate your issue, please follow the contributing guidelines.

We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

@cWenyu cWenyu changed the title Can not capture the deault content inside a slot, and styling of prohgress bar is missing Can not capture the deault content inside a slot, and styling of progress bar is missing Jul 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant