Skip to content

How to extend EraseBrush class to make custom brush shapes? #52

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

Closed
Khushalikg opened this issue Feb 18, 2025 · 6 comments
Closed

How to extend EraseBrush class to make custom brush shapes? #52

Khushalikg opened this issue Feb 18, 2025 · 6 comments

Comments

@Khushalikg
Copy link

Hello. I am currently trying to make some custom canvas brushes, such as square brush and lasso brush. I want to make them both for PencilBrush and for erasing those said Pencil lines. I was successfully able to make the lasso pencil brush like below, but I don't know how I can extend your EraserBrush to make a similar lasso eraser brush. Can you help me out with this as I am not able to understand the process of erasing by seeing your code.

import { Polygon, PencilBrush } from "fabric";

class LassoMaskingBrush extends PencilBrush {
    _finalizeAndAddPath() {
        const ctx = this.canvas.contextTop || this.canvas.getContext('top');
        ctx.closePath();

        if (this.decimate) {
            this._points = this.decimatePoints(this._points, this.decimate);
        }

        // Create a lasso polygon from the drawn points
        const lassoPolygon = new Polygon(this._points, {
            fill: "rgba(255, 0, 247, 0.55)",
            selectable: false,
            evented: false,
            erasable: true,
        });

        this.canvas.add(lassoPolygon);

        // Render updates
        this.canvas.requestRenderAll();

        // Clear the top drawing context
        this.canvas.clearContext(ctx);
        this._resetShadow();
    }
}

// Export as default
export default LassoMaskingBrush;
@ShaMan123
Copy link
Owner

ShaMan123 commented Feb 19, 2025

Your code doesn't say what you want to do. I understand from it that on pointerup a polygon is created instead of a path.

@ShaMan123
Copy link
Owner

ShaMan123 commented Feb 19, 2025

If that is the case you need to call preventDefault and pass down the polygon to the commit call from the end event. There is a detailed example in the readme

@Khushalikg
Copy link
Author

@ShaMan123 I'm trying to create an eraser that works based on polygon shapes rather than just a freehand path. In my previous code, I used a free-drawing pencil brush to create polygon shapes. Similar to it, I want to make a polygon-based brush that erases objects below it instead of drawing.

I looked at the example you sent but it does not seems to be working and giving me error saying
Cannot read properties of undefined (reading 'includes') on const isErased = e.targets.includes(circle);

I have created a code sandbox to show this error. Can you help me in resolving this error? Also, I’d appreciate any guidance on how to properly implement a polygon-shaped eraser. I have added the Lasso/Polygon brush tool in the sandbox to show how I want the eraser to work - I just need it to erase instead of draw.

Fabric Polygon Test Sandbox

@ShaMan123
Copy link
Owner

https://codesandbox.io/p/sandbox/fabric-polygon-eraser-forked-dfjywh

@Khushalikg
Copy link
Author

@ShaMan123 Thank you so much!! You are life saver, I spent so much time trying to implement this. 😊👍

@ShaMan123
Copy link
Owner

Happy to help.
I think I should add some info in the readme about the rendering of ClippingGroup so that it is clear how to subclass like in your case.
I expected in your case to use the inverted prop but I think that the problem was that the inverted prop was overriding globalCompositeOperation under the hood in the render method.
Anyways, I am moving to a different rendering technique altogether and will probably redo the eraser approach and make everything more straight forward. The current approach is derived from fabric and does not fit all cases unfortunately but is pretty good anyways.

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