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

Handle semi-transparency in canvas icon-src/icon-color and fill-pattern-src/fill-color combinations #15295

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

mike-000
Copy link
Contributor

@mike-000 mike-000 commented Nov 4, 2023

Fixes #15290
Fixes #15318 (comment)

Makes the handling of alpha in icon-color and icons in IconImage consistent with WebGL

Copy link

github-actions bot commented Nov 4, 2023

📦 Preview the website for this branch here: https://deploy-preview-15295--ol-site.netlify.app/.

@mike-000 mike-000 marked this pull request as ready for review November 4, 2023 12:29
@tschaub
Copy link
Member

tschaub commented Nov 4, 2023

The icon already accepts an opacity. It seems like it would be simpler to parse the color and remove any alpha before rendering it. Then the alpha could be applied as opacity. And we need to decide how to handle cases when both opacity and alpha are supplied.

@mike-000
Copy link
Contributor Author

mike-000 commented Nov 4, 2023

Opacity is an updateable setting for all ol/style/Image subclasses (which might also have alpha in their fill or stroke) and is handled by the canvas layer renderer, while color is applied when the IconImage is constructed. Also an icon can have semi transparent regions (as in the test), which were also not handled consistently compared to WebGL.

Applying an opacity in addition to a color with alpha appears to give consistent results for canvas and WebGL in the test setup, i.e. 'icon-color': [255, 0, 0, 0.25], is equivalent to 'icon-color': [255, 0, 0, 0.5], 'icon-opacity': 0.5, and 'icon-color': [255, 0, 0, 1], 'icon-opacity': 0.25, in both renderers.

Due to the need to handle semi-transparency in the original image, all of this change apart from the single line ctx.globalAlpha = color[3]; would still be needed even if color alpha was combined with opacity, so handling that elsewhere when it is currently unique to IconImage would not be a simplification, especially for fill patterns which do not use opacity.

@mike-000
Copy link
Contributor Author

mike-000 commented Nov 9, 2023

I have checked how well outputs from canvas and WebGL match in a setup similar to the rendering test, and with various combinations of icon-color alpha, icon-opacity and layer opacity, using ol/source/Raster to highlight any pixels which are not exactly the same

image

It is apparent that using 0.5 twice in those situations can produce more differences than using 0.25 once - this is because there is no such thing as a 0.5 alpha, it is either 127/255 or 128/255 - and using those together will produce a better match. However specifying 127/255 as alpha for an icon-color does not work as expected as ol/color#asString rounds alpha to 2 places, which then produces the same result as 128/255.

@mike-000 mike-000 changed the title Fix canvas icon-color alpha handling Handle semi-transparency in canvas icon-src/icon-color and fill-pattern-src/fill-color combinations Nov 15, 2023
@mike-000
Copy link
Contributor Author

The IE fallback removed in #13912 always worked correctly, and was probably faster even without the additional drawImage calls needed to make the multiply globalCompositeOperation work as expected, so is used again as long as the canvas is not tainted.

Copy link

📦 Preview the website for this branch here: https://deploy-preview-15295--ol-site.netlify.app/.

@mike-000
Copy link
Contributor Author

@tschaub @ahocevar Ready for review

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

Successfully merging this pull request may close these issues.

icon-color inconsistency between canvas and WebGL
2 participants