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

Add PaintTarget from Client? #26

Open
wolfmcnally opened this issue Jan 13, 2025 · 4 comments
Open

Add PaintTarget from Client? #26

wolfmcnally opened this issue Jan 13, 2025 · 4 comments

Comments

@wolfmcnally
Copy link

Your docs say:

Canvas and SVG are currently supported. If you need to paint to a new kind of surface, contributions are welcome. It is relatively easy to add a new paint target (see the PaintBackend interface in src/paint.ts).

I see this in the source code, but is there a way I can "plug in" my own PaintBackEnd or write a paintMySurface() function without having to change the dropflow codebase?

@chearon
Copy link
Owner

chearon commented Jan 13, 2025

I'd be interested in doing that if there's a good use case for it, with the caveat that the PaintBackend interface could change. Could be like an undocumented "use at your own risk" type of thing.

@wolfmcnally
Copy link
Author

wolfmcnally commented Jan 13, 2025

You'll notice from my previous comment here that I'm also loading CanvasKit. In fact, the two back-ends I would like to be able to paint to for my purposes are:

  • CanvasKit wasm, returning a Paragraph that I can then cache and repaint multiple times, as I am using it to render my mixed-graphics and text document that animates in real time. (I also already have a CanvasKit FontMgr with all the same Noto Sans fonts loaded as I'm registering with DropFlow.)
  • SVG.js, returning a DOM that I can further manipulate, for instance to implement rounding of floating point numbers.

I'd be overjoyed if you'd make these available directly in DropFlow, but failing that, export your API.

Failing that, if you could provide me with an example of how I can walk your laid-out tree and extract the boxes, positions, and other style info in drawing order, using your existing API, that would be super helpful and save me some serious reverse-engineering time.

@wolfmcnally
Copy link
Author

Oh, and BTW the reason I've turned to DropFlow is that CanvasKit Paragraph objects, while being laid out very nicely, including RTL text, give me no way of walking them to determine all the layout info. So my alternative is to try to use DropFlow as my layout engine, and using that to build identically laid-out Paragraph objects for onscreen rendering and SVG DOM for export.

@wolfmcnally
Copy link
Author

wolfmcnally commented Jan 15, 2025

So I realized (duh) that I could just provide a duck-typed CanvasRenderingContext2D as you define it in your codebase to the paintToCanvas function, and that gives me all the drawing commands in order that I can now pipe to SVG.js and CanvasKit!

class RenderingContext {
  moveTo(x: number, y: number): void {
    console.log(`moveTo(${x}, ${y})`);
  }

// ...
}

// ...

  test('Render to custom context' , () => {
    const text = 'Any sufficiently advanced technology is indistinguishable from magic.';
    const elem: HTMLElement = h('div', text);
    const root = flow.dom(elem);
    const container: BlockContainer = flow.generate(root);
    flow.layout(container, 200, 200);
    const width = flow.staticLayoutContribution(container);
    flow.layout(container, width, 200);
    const context = new RenderingContext();
    flow.paintToCanvas(container, context);
  });

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

2 participants