fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser
http://fabricjs.com
Other
29.13k stars 3.52k forks source link

[Feature]: Is it possible to add linear-burn, linear-dodge and linear-light in blend mode? #9912

Open sudipto-28 opened 5 months ago

sudipto-28 commented 5 months ago

CheckList

Description

Summary Implementing the linear burn, linear dodge, and linear light blend modes in Fabric.js will enhance the library's ability to handle complex graphic compositions. These blend modes are essential for achieving advanced visual effects, commonly used in photo editing and graphic design software.

Description Fabric.js is a powerful JavaScript library for manipulating canvas elements. While it supports several blend modes, the addition of linear burn, linear dodge, and linear light would significantly expand its utility, particularly for users requiring more sophisticated image processing capabilities.

Linear Burn Linear burn darkens the base color to reflect the blend color by decreasing the brightness. The result is a darker, more intense color, creating deep shadows and contrast. It's useful for adding depth and richness to images.

Formula: Result

Base + Blend − 1 Result=Base+Blend−1

Linear Dodge Linear dodge (also known as Add) brightens the base color to reflect the blend color by increasing the brightness. This mode is ideal for highlighting areas of an image and creating glowing effects.

Formula: Result

Base + Blend Result=Base+Blend

Linear Light Linear light combines linear burn and linear dodge by increasing the contrast. It is a combination of a linear dodge with a half-strength linear burn, used for adding high contrast and emphasizing details.

Formula: Result

Base + 2 × Blend − 1 Result=Base+2×Blend−1

Implementation Considerations Performance: Ensure that the implementation of these blend modes does not significantly degrade performance, especially when handling large canvases or multiple blend operations. Compatibility: Maintain compatibility with existing blend modes and ensure that new modes integrate seamlessly into the existing API. Accuracy: The mathematical operations for these blend modes should be implemented accurately to reflect the expected visual outcomes. Testing: Comprehensive testing across different browsers and devices to ensure consistent behavior. Benefits Enhanced Creativity: These additional blend modes will provide developers and designers with more tools to create visually compelling and complex graphics. Feature Request: Addition of Linear Burn, Linear Dodge, and Linear Light Blend Modes in Fabric.js Summary Implement linear burn, linear dodge, and linear light blend modes in Fabric.js to enhance the library's graphic composition capabilities. These modes are essential for advanced visual effects in photo editing and graphic design.

Description Fabric.js is a robust JavaScript library for manipulating canvas elements. Currently, it supports several blend modes, but adding linear burn, linear dodge, and linear light will significantly increase its utility for more sophisticated image processing tasks.

Linear Burn Linear burn darkens the base color by decreasing brightness, resulting in deep shadows and contrast, adding depth and richness to images.

Formula: Result

Base + Blend − 1 Result=Base+Blend−1

Linear Dodge Linear dodge brightens the base color by increasing brightness, ideal for highlighting areas and creating glowing effects.

Formula: Result

Base + Blend Result=Base+Blend

Linear Light Linear light combines linear burn and linear dodge, increasing contrast and emphasizing details.

Formula: Result

Base + 2 × Blend − 1 Result=Base+2×Blend−1

Implementation Considerations Performance: Ensure that these blend modes do not degrade performance, especially with large canvases or multiple blend operations. Compatibility: Maintain compatibility with existing blend modes and ensure seamless integration into the API. Accuracy: Implement the mathematical operations accurately to reflect expected visual outcomes. Testing: Conduct comprehensive testing across different browsers and devices to ensure consistent behavior. Benefits Enhanced Creativity: Provides developers and designers with more tools to create visually compelling and complex graphics.

Current State

there is other blend mode currently in fabric js

Additional Context

No response

asturur commented 5 months ago

Are you talking about doing it in the BlendImage filter? or through the globalCompositeOperation?

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation Those should be supported out of the box for objects in real time, while for filters it needs to be implemented

guyikcgg commented 5 months ago

I'd love that FabricJS could understand the mix-blend-mode style defined on my SVGs and apply the corresponding globalCompositeOperation (not sure if that's the right way to implement it though). Then, it would be great that exported SVGs would get this property translated the other way round. This is related to my comment here: https://github.com/fabricjs/fabric.js/issues/1883#issuecomment-2164013612

asturur commented 5 months ago

exporting complex composite operation to canvas from svg should be possible with the filter primitives. I m not sure how useful and common is of a use case. is 'mix-blend-mode' how css decided to call globalCompositeOperation?

guyikcgg commented 5 months ago

Ciao Andrea! Grazie mille per aver risposto! As far as I've been able to read, 'mix-blend-mode' is the CSS equivalent to canvas' globalCompositeOperation. I'm using Inkscape to generate SVG images using different blend modes and the browser interpret it correctly. I know the purpose for FabricJS is not to fully support SVG (at least in the short time), but I think converting mix-blend-mode to globalCompositeOperation and vice versa (when possible) should be pretty straight forward :thinking:

I'll be glad to help implementing this if someone points me how it should be done! Thank you for considering these comments!!

asturur commented 5 months ago

Yes it can be pretty straight forward. We can't support all css features, that is completely out of question. We can support the one that could be commonly used and that have a big visual impact like this. this is a mapping between 2 names in the parser, not big deal. But i m not sure how many software that provide svg export actually leverage css.

guyikcgg commented 5 months ago

Sorry, I don't get the point. Aren't properties such as fill or stroke always stored in the style CSS-like attribute of SVG? These properties are (almost) always there and they're correctly parsed, so I guess other CSS styles that may be commonly used could be parsed as well, right? Sorry if I didn't understand you right :pray:

asturur commented 5 months ago

Wait there is some overlap here. We do support css parsing with style in elements. We don't support all css features that browser may decide to support for svg elements, because are too many. I do think fill and stroke today are correctly parsed from attributes, inline style or style tags in the svg file

But this issue is about the global composite operation support from css

durlav-bose commented 4 months ago

I think he wants to implement linear burn, dodge, and light blend modes in Fabric Js. Fabric Js does not provide these modes. But is there any way to implement these modes? Pixi.js provides these blend modes. @asturur

Sample Fabric Js 'multiply' blend mode code.

var filter = new fabric.Image.filters.Blend({
 color: '#000',
 mode: 'multiply'
});

var filter = new fabric.Image.filters.Blend({
 image: fabricImageObject,
 mode: 'multiply',
 alpha: 0.5
});
object.filters.push(filter);
object.applyFilters(canvas.renderAll.bind(canvas));
asturur commented 4 months ago

Of course they can ve implemented if the browser do not support them, but you have to dig out the formula

shubhamshete682 commented 3 months ago

Yes i have used this blend mode property you can use it. try using key globalCompositeOperation & opacity as well

var filter = new fabric.Image.filters.Blend({ image: fabricImageObject, globalCompositeOperation: 'multiply', alpha: 0.5 });