question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature - expose the raw doc object to Canvas's paint callback (or a new element to do the same)

See original GitHub issue

I’d like to use svg-to-pdfkit to render an SVG into a PDF I’m building. It requires a handle to the PDFKit document, which I don’t see an obvious way to get. The closest we get is the Canvas element’s paint callback, which receives the painter object. However, this isn’t sufficiently powerful for svg-to-pdfkit’s purposes.

I’d like to either have the paint callback pass the root object as an available parameter:

paint(painter, width, height, root)

Or I’d like a new element, like <RawCanvas render={(doc) => void} />, which would require a render callback to which the this.root.instance handle would be passed, and it would hand off the rendering work to the implementor (in this case, svg-to-pdfkit).

Or, just taking the shortcut even further, an <SVGToPDFKit svg={...} width={...} height={...} /> element which wraps up the whole kit and kaboodle. If we went that route, we could make svg-to-pdfkit a peer dependency, so it’s not shipped by default.

If any of these are appropriate paths forward, I’d be happy to submit a PR implementing the desired solution.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
chealdcommented, Mar 17, 2022

Echoing @steschi’s sentiment, the current 2.0 implementation is not sufficient for all SVGs, and access to the raw handle for svg-to-pdfkit would still be very useful. For example, there is no facility to put text on a path in the current setup, and it’s still a giant PITA to consume raw SVGs in react-pdf, since they have to be translated to react-pdf’s <Svg> syntax.

Another alternative would be to remove the method filtering from the painter object, so the full (augmented) pdfkit handle is available to the paint function.

If either of these would be welcome, I am happy to send a PR.

4reactions
chealdcommented, Aug 11, 2020

https://github.com/cheald/react-pdf/commit/453e8a57bcbf8080559fb270d9c1b258ec7900c8

This is the simplest change necessary to enable this workflow. svg-to-pdfkit works like a champ. I now just have an <Svg> component, like so:

type AspectRatioPosition =
  | "xMaxYMax"
  | "xMaxYMid"
  | "xMaxYMin"
  | "xMidYMax"
  | "xMidYMid"
  | "xMidYMin"
  | "xMinYMax"
  | "xMinYMid"
  | "xMinYMin";

type AspectRatioBehavior = "meet" | "slice";

type SVGIsh = string | React.ReactNode | SVGImageElement;

function svgishToString(svg: SVGIsh) {
  if (React.isValidElement(svg)) {
    return ReactDOMServer.renderToStaticMarkup(svg);
  } else if (typeof svg === "string") {
    return svg;
  } else {
    return (svg as SVGImageElement).innerHTML;
  }
}

function Svg({
  svg,
  children,
  width,
  height,
  assumePt = true,
  aspectRatio = ["xMidYMid", "meet"],
  ...props
}: Omit<ReactPDF.CanvasProps, "paint"> & {
  children?: SVGIsh;
  svg?: SVGIsh;
  width?: number | string;
  height?: number | string;
  assumePt?: boolean;
  aspectRatio: [AspectRatioPosition, AspectRatioBehavior];
}) {
  const source = React.useMemo(() => svgishToString(children || svg), [
    children,
    svg,
  ]);

  return (
    <Canvas
      style={{ height, width }}
      {...props}
      paint={(_, width, height, root) => {
        SVGToPDFKit(root, source, 0, 0, {
          width,
          height,
          assumePt,
          preserveAspectRatio: aspectRatio.join(" "),
        });
      }}
    />
  );
}

I have to have the SVG already available (either as source, as a React component building the SVG, or as an SVG element DOM node). Pulling remote SVGs will need a new react-pdf element which can do the async/await stuff that React doesn’t like to do, as it appears that react-pdf doesn’t like to re-render the PDF on a React tree change.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Manipulating video using canvas - Web APIs | MDN
This code grabs references to the elements in the HTML document that are of particular interest, namely the video element and the two...
Read more >
ImageView - Android Developers
FOCUS_DOWN If the reference refers to a view that does not exist or is part of ... a Canvas from either a Bitmap...
Read more >
Backbone.js
Bind a callback function to an object. The callback will be invoked whenever the event is fired. If you have a large number...
Read more >
JavaScript: Extract video frames reliably - html - Stack Overflow
This method allows us to schedule a callback to whenever a new frame will be painted on the HTMLVideoElement. It is higher level...
Read more >
Painting in AWT and Swing - Oracle
Although repaint() results in a call to paintImmediately() , it is not considered the paint "callback", and client paint code should not be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found