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

Improve control over display of canvas #2

Open
mmarras opened this issue Oct 21, 2024 · 1 comment
Open

Improve control over display of canvas #2

mmarras opened this issue Oct 21, 2024 · 1 comment

Comments

@mmarras
Copy link

mmarras commented Oct 21, 2024

I want to make a two column page layout, some Dash stuff left, the PDF right. Below a minimal example of the generated DOM:

<html>
  <head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">  
  </head>
  <body>
    <div class ="container">
      <div class="row">
        <div class="col-6">
          <div id="pdf-viewer">
            <div class="react-pdf__Document" style="--scale-factor: 1">
              <div
                class="react-pdf__Page"
                data-page-number="1"
                style="
                  --scale-factor: 1;
                  background-color: white;
                  position: relative;
                  min-width: min-content;
                  min-height: min-content;
                "
              >
                <canvas
                  class="react-pdf__Page__canvas"
                  dir="ltr"
                  width="850"
                  height="1063"
                  style="display: block; user-select: none; width: 567px; height: 709px"
                ></canvas>
              </div>
            </div>
            <div class="d-flex">
              <p class="">Page 1 of 4</p>
              <button type="button" disabled="" class="btn btn-outline-primary">
                Previous</button
              ><button type="button" class="btn btn-outline-primary">Next</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

I want the pdf to take up all the space of the column, how to remove the <canvas> style properties? The provided class handles only allow to tweak the buttons. Better not to enforce style tag anyways and let users define classes for it.

@mmarras
Copy link
Author

mmarras commented Oct 21, 2024

Not the most concise, and horrible timeout-wizzardy in lack of some solid async hooks, but a functional work-around for the time being:

assuming your dash_pdf id is 'pdf-viewer' like in the example.

assets/javascript.js

window.addEventListener("DOMContentLoaded", function () {
    function waitForTargetNode() {
        var targetNode = document.getElementById('pdf-viewer');
        if (!targetNode) {
            console.log('pdf-viewer not found yet, retrying...');
            setTimeout(waitForTargetNode, 100); // Try again after 100ms
            return;
        }

        console.log('pdf-viewer found, proceeding...');
        initializeObserver(targetNode); // Proceed once the targetNode is available
    }

    function removeStyle(queryString, observer = null) {
        var canvas = document.querySelector(queryString);
        if (canvas) {
            canvas.style.cssText = "";  // Resetting styles
            console.log("Canvas found and style updated.");

            // Attach event handlers to buttons for future interactions
            let buttons = document.querySelectorAll('#pdf-viewer button');
            if (buttons.length > 0) {
                for (let i = 0; i < buttons.length; i++) {
                    buttons[i].onclick = function () {
                        console.log("Button clicked, checking for new canvas...");
                        setTimeout(() => removeStyle(queryString), 100); // Small delay to wait for new content
                    };
                }
            }

            if (observer) {
                observer.disconnect(); // Stop observing once the canvas is found
            }

            return true; // Return true to indicate canvas was found
        }
        return false; // Return false if not found
    }

    function initializeObserver(targetNode) {
        // Initial check with retry for canvas
        function checkInitialCanvas() {
            if (!removeStyle('#pdf-viewer canvas')) {
                console.log("Initial canvas not found, retrying...");
                setTimeout(checkInitialCanvas, 100); // Retry until the initial canvas is found
            }
        }

        checkInitialCanvas(); // Start checking for the initial canvas

        // Set up the observer to detect dynamic changes in the pdf-viewer div
        var observer = new MutationObserver(function (mutationsList, observer) {
            if (removeStyle('#pdf-viewer canvas', observer)) {
                console.log("Canvas found by MutationObserver.");
            }
        });

        // Observe with specific options
        observer.observe(targetNode, {
            childList: true,
            subtree: true,
            attributes: false,
            characterData: false,
        });
    }

    // Start waiting for the pdf-viewer element to appear
    waitForTargetNode();
});

removes the "style" from the canvas block on startup and when the next/previous page is clicked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant