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 fabric.js be used to create an overlay blur mask? #5982

Closed
jurgenwerk opened this issue Nov 18, 2019 · 9 comments
Closed

Can fabric.js be used to create an overlay blur mask? #5982

jurgenwerk opened this issue Nov 18, 2019 · 9 comments

Comments

@jurgenwerk
Copy link

Is it possible to use fabric.js to achieve an effect like this? An object that can be moved freely and blurs the image behind

image

@asturur
Copy link
Member

asturur commented Nov 18, 2019

yes and no.
Is a full app more than a simple function.

In 2 words, you organize your canvas with the objects.
Every change on your canvas you export the canvas to a copy element.
you create a fabricImage from that element
you apply a blur filter to that fabricImage
at this point you have a blurred copy of your canvas with all the objects.

Now you have a couple of ways to cut it and position it where you want.

you either you cropX/cropY and width/height on the image to obtain the area of the canvas you are interested in, or you create a Rect and you use the image as a filler for the rect ( a Pattern ).

If this is your first experience with fabricJS all of this may sound complicated, but is not.

Look in the docs for the following things:

StaticCanvas.toCanvasElement

fabric.Image.filters.Blur

fabric.Image.cropX, fabric.Image.cropY.

fabric.Pattern

@jurgenwerk
Copy link
Author

jurgenwerk commented Nov 19, 2019

@asturur thanks for your help. I managed to get it working when moving the selection, but not when scaling the selection.

Please check this screen video: https://media.giphy.com/media/VdWsw45mXAoHpRpn2c/giphy.gif

You can see that when scaling the image, the blur just gets scaled. The desired outcome is that the image shouldn't get scaled, but simply cover more area in the background image and be reflected in the blur. Is that possible to achieve? If yes, how?

Fiddle here: https://jsfiddle.net/jurgenwerk/r0sh2o5u/6/

Also posted this on StackOverflow: https://stackoverflow.com/questions/58942104/how-to-prevent-the-image-from-scaling-in-fabric-js-implement-a-blur-mask

@asturur
Copy link
Member

asturur commented Nov 20, 2019

can t really open any code right now, but you can use the on('scaling') event to change image size rather than scaling. I ll check later

@jurgenwerk
Copy link
Author

@asturur thanks for the tip. I'm interested in how to calculate the image and copied canvas dimensions on scaling so that the masking image will adjust properly (not stretching). Thanks!

@jurgenwerk
Copy link
Author

@asturur I managed to solve this issue. JSFiddle here: https://jsfiddle.net/jurgenwerk/top84ye6/1/

@asturur
Copy link
Member

asturur commented Nov 23, 2019 via email

@Rosga
Copy link

Rosga commented Nov 25, 2019

Another blur solution that I use in my project:

  1. Use additional image (not canvas, simple <div /> html tag and background-image css property) under the Fabric's canvas and blur it using CSS filter.
  2. Extend rect's render method to simply draw fully transparent rectangle.
    As a result, it would make a "hole" in the canvas that shows blurred image under the fabric's canvas.

pros: the solution is highly performant and allows easily using several blur items on the screen. it only uses one additional image that is blurred, so no need to create and manipulate with canvas objects

cons:

  • it is not straightforward and requires some math logic to locate background image for zoom and crop functionality
  • .toDataURL() method returns blank rectangle (workaround: override the method, replace render for rects with blur algorithm, and after the dataURL extracted - replace with original one)
  • works only as an image background blur. It doesn't blur canvas

@Zhouqchao
Copy link

@asturur is it possible to use fabric.js to achieve same blur effect while rendering video in requestAnimFrame function? I want to make a blur mask, which can blur some part of video frame and make it move freely, thanks.

@iampava
Copy link

iampava commented Sep 23, 2020

Hey! I have the same requirements as @Zhouqchao. I was thinking of using a Rect element and overwriting the _render function.

Do you see any red flags regarding this approach?

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

5 participants