fabricjs / fabric.js

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

Use SVG Patterns in Retina Displays #5967

Open SooChang-Lee opened 5 years ago

SooChang-Lee commented 5 years ago

Hi~. I want to apply SVG patterns to mobile users using Retina displays.

If draw an SVG group on a pattern source canvas and apply the pattern to a Rect on the target Retina display canvas, the pattern quality will be too low. (Mostly when reducing the pattern size)

Setting the enableRetinaScaling value to true or false also degrades the quality.

You can check the fiddle by opening it on a high density mobile phone.

https://jsfiddle.net/SooChangLee/50894xmL/

If you run jsfiddle on your mobile phone, it's hard to see, so I attach the same version of the link

http://mac.soochang.pe.kr/pattern_source_canvas_retina_false.jsp http://mac.soochang.pe.kr/pattern_source_canvas_retina_true.jsp

How can I apply high quality patterns to High dpi mobile phone?

image image

SooChang-Lee commented 5 years ago

@asturur Hi asturur Can I hear your opinion on this issue? I'm looking forward to improving this feature.

asturur commented 5 years ago

I need to sit down with a proper pattern and try. Because as of now i m confused. I need a pattern with lines of 1px, space by 1px so that i can really see when they are sharp and when not.

SooChang-Lee commented 5 years ago

I understood that testing is needed with a 1px striped pattern. Did I understand correctly?

I tested with a 1px stripe pattern. (Added two regular and diagonal stripe patterns to the previous example.)

I updated it in jsfiddle and the url below. https://jsfiddle.net/SooChangLee/50894xmL/ http://mac.soochang.pe.kr/pattern_source_canvas_retina_true.jsp http://mac.soochang.pe.kr/pattern_source_canvas_retina_false.jsp

When you use Retina Scaling on your mobile phone, you can easily find blurry, clunky displays no matter what pattern you use. When pattern source height is less than 200

Screenshot_20191118-150109_Chrome Screenshot_20191118-150116_Chrome Screenshot_20191118-150122_Chrome Screenshot_20191118-150128_Chrome Screenshot_20191118-150135_Chrome

Screenshot_20191118-150414_Chrome Screenshot_20191118-150421_Chrome Screenshot_20191118-150426_Chrome Screenshot_20191118-150431_Chrome Screenshot_20191118-150437_Chrome

SooChang-Lee commented 5 years ago

@asturur Did I understand correctly?

asturur commented 5 years ago

yes, i just need some time to make some test. I m fix low hanging fruits first

SooChang-Lee commented 5 years ago

Thank you for your efforts. I hope this issue will be improved.

SooChang-Lee commented 4 years ago

@asturur If the pattern source canvas and the target canvas are Retinas, the pattern size of the target canvas is enlarged by devicePixelRatio. (When devicePixelRatio is 2, twice the image quality degradation)

I think if the pattern source canvas and the target canvas are Retinas, the display size should be 1: 1 with high density.

image

SooChang-Lee commented 4 years ago

@asturur I found a way. I tested how to scale without degrading the quality of the pattern.

Using canvasPattern's setTransform allows you to scale the retina pattern without degrading its quality. (https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern/setTransform)

I changed the source code of toLive ().

return ctx.createPattern(source, this.repeat);

to

var matrix = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix(); canvasPattern.setTransform(matrix.scale(1 / fabric.devicePixelRatio)); return canvasPattern;

However, canvasPattern's setTransform method is called an experimental API. It is not supported by Explorer and Edge.

Anyway, it is supported by browser except explorer and edge. This is how to display a pattern of retina quality.

SooChang-Lee commented 4 years ago

@asturur https://mac.soochang.pe.kr/pattern_highdpi_canvas.jsp image