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

Enable transparency for duotone #34130

Merged
merged 14 commits into from
Oct 29, 2021
Merged

Conversation

ajlende
Copy link
Contributor

@ajlende ajlende commented Aug 17, 2021

Description

Fixes #34121

Adds the ability to set transparency for duotone colors.

Also allows passing through enableAlpha for the color picker.

How has this been tested?

  1. Create cover or image block
  2. Add duotone filter
  3. Adjust filter to use transparency with the custom color picker (bar and list view)

I used the Skatepark theme colors for the examples below, but I've saved all the colors as custom colors, so they should appear the same regardless of the theme you are using.

Screenshots

Match background

This example shows three different ways that transparency can be applied with duotone. The first and last show a transparent value in use for the duotone filter, and the middle one shows a png with transparency. Code is below to try it out yourself.

duotone with gradient background

<!-- wp:columns {"align":"wide","style":{"color":{"background":"#b9fb9c"}}} -->
<div class="wp-block-columns alignwide has-background" style="background-color:#b9fb9c"><!-- wp:column {"width":"50%"} -->
<div class="wp-block-column" style="flex-basis:50%"><!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)","style":{"color":{}}} -->
<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)"><div class="wp-block-cover__inner-container"><!-- wp:image {"sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["#000","rgba(0, 0, 0, 0)"]}}} -->
<figure class="wp-block-image size-large"><img src="https://upload.wikimedia.org/wikipedia/commons/5/57/Aristotle_transparent.png" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:preformatted {"textColor":"primary","fontSize":"small"} -->
<pre class="wp-block-preformatted has-primary-color has-text-color has-small-font-size">[
    "#000",
    "rgba(0, 0, 0, 0)"
]</pre>
<!-- /wp:preformatted --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:column -->

<!-- wp:column {"width":"50%"} -->
<div class="wp-block-column" style="flex-basis:50%"><!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)","style":{"color":{}}} -->
<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)"><div class="wp-block-cover__inner-container"><!-- wp:image {"sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["#000","#FFF"]}}} -->
<figure class="wp-block-image size-large"><img src="https://upload.wikimedia.org/wikipedia/commons/5/57/Aristotle_transparent.png" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:preformatted {"textColor":"primary","fontSize":"small"} -->
<pre class="wp-block-preformatted has-primary-color has-text-color has-small-font-size">[
    "#000",
    "#FFF"
]</pre>
<!-- /wp:preformatted --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:column -->

<!-- wp:column {"width":"50%"} -->
<div class="wp-block-column" style="flex-basis:50%"><!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)","style":{"color":{}}} -->
<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(201,228,237) 50%,rgb(243,178,169) 50%)"><div class="wp-block-cover__inner-container"><!-- wp:image {"sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["rgba(255, 255, 255, 0)","#FFF"]}}} -->
<figure class="wp-block-image size-large"><img src="https://upload.wikimedia.org/wikipedia/commons/5/57/Aristotle_transparent.png" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:preformatted {"textColor":"primary","fontSize":"small"} -->
<pre class="wp-block-preformatted has-primary-color has-text-color has-small-font-size">[
    "rgba(255, 255, 255, 0)",
    "#FFF"
]</pre>
<!-- /wp:preformatted --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:column --></div>
<!-- /wp:columns -->

Image Layering

In an advanced use-case, you could overlay a transparent duotone image on top of another image. Some might call this a "double exposure" effect, but it's not quite the same since we're not using full-color images. It's also a bit like an image mask, but you're not letting the background show through; you're just letting the image obscure some parts of the image below it.

Olly Moss has some cool examples of something that could be achieved with layered transparent duotone. In the images below, the tan/cream outline could be one duotone image "masking" the contents. In this specific example, because the background of the composition incorporates elements that need specific positioning to complete the effect, this exact composition is probably more suited for editing in Photoshop than WordPress, but it could theoretically be achieved in WordPress with this change.

Using the two images below, we can create our own "double exposure" effect. I just grabbed a couple of CC0-licensed images, but choosing a better image mask could make for a better composition.

hilly background imagewhite on black silhouette of a raven

duotone image mask

<!-- wp:cover {"url":"https://upload.wikimedia.org/wikipedia/commons/2/2c/Landscape_in_Transylvania.jpg","dimRatio":0,"align":"wide","className":"duotone-cover-mask","style":{"color":{"duotone":["#000","#C9E4ED"]},"spacing":{"padding":{"top":"0px","right":"0px","bottom":"0px","left":"0px"}}}} -->
<div class="wp-block-cover alignwide duotone-cover-mask" style="padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px"><img class="wp-block-cover__image-background" alt="" src="https://upload.wikimedia.org/wikipedia/commons/2/2c/Landscape_in_Transylvania.jpg" data-object-fit="cover"/><div class="wp-block-cover__inner-container"><!-- wp:image {"sizeSlug":"large","style":{"color":{"duotone":["#B9FB9C","rgba(185, 251, 157, 0)"]}}} -->
<figure class="wp-block-image size-large"><img src="https://upload.wikimedia.org/wikipedia/commons/1/1e/P_Raven_WhiteonBlack.jpg" alt=""/></figure>
<!-- /wp:image --></div></div>
<!-- /wp:cover -->
.duotone-cover-mask .wp-block-cover__inner-container .wp-block-image > img {
	display: block;
}

.duotone-cover-mask .wp-block-cover__inner-container .wp-block-image {
	margin: 0;
}

.duotone-cover-mask .wp-block-cover__inner-container p:last-child {
	display: none; /* Last <p> seems to be included in the output even though it's empty */
}

Types of changes

New feature

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@ajlende
Copy link
Contributor Author

ajlende commented Aug 17, 2021

@jasmussen and @mtias This is another instance of wanting to add some additional toggle to duotone, much like posterize.

With SVG filters we can do a proper full-color double exposure by using a different feColorMatrix, so it may fall under a separate category of filter. And it could be combined with the posterize option. Not sure how relevant those two details are for this, but I figured it's worth mentioning.

Is this something that you think makes sense in core? And if so, what are your thoughts on UI for exposing the feature?

@jasmussen
Copy link
Contributor

This is a cool experiment and a cool effect. It seems somewhat tricky to use to get something compelling, given you have to stack a few things, but nevertheless it's nice to know this is possible.

For that reason, and for the other SVG filters you mention, I feel like an important next step is to explore how we can evolve the filtering interface to accommodate additional controls (if at all). To me there's still so much potential just in the vanilla duotone feature that we want to tread carefully to not dilute it, and to polish that interface to be its very best.

However I'll definitely put on my todo list to explore some mockups for improved filtering. Duotone on its own still needs a little love. Nice one.

@annezazu annezazu added [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement. labels Aug 25, 2021
@mtias
Copy link
Member

mtias commented Aug 27, 2021

If this is achieved by just setting one of the colors as transparent, it makes sense to just be an effect of using the alpha slider on the color picker, no? (And it wouldn't need extra UI.)

@jasmussen
Copy link
Contributor

If this is achieved by just setting one of the colors as transparent, it makes sense to just be an effect of using the alpha slider on the color picker, no? (And it wouldn't need extra UI.)

We discussed this exact thing in a chat very recently, and (correct me if I'm wrong Alex) — for the transparency to work on an image, any image that is already transparent (such as a PNG) will have the transparent parts made black when you apply a duotone filter, up until you leverage the duotone transparency at which point it "starts working" again.

Instead of the transparency being something we can toggle on or off to enable this, @ajlende can we just apply the transparency feature only if the alpha transparency is explicitly set to less than 100%?

@ajlende
Copy link
Contributor Author

ajlende commented Aug 27, 2021

@jasmussen is right—that's what I said during our chat. I was thinking that we'd have to add another filter to mask the final output, but I fiddled with some other SVG filter properties this morning in a codepen, and I think I have it working in a single filter.

image

Is there any scenario where we wouldn't want the source alpha to be the final mask for the image? If not, I think I can get this working without needing the switch.

@jasmussen
Copy link
Contributor

Is there any scenario where we wouldn't want the source alpha to be the final mask for the image? If not, I think I can get this working without needing the switch.

I can't think of one! If need be you could group the thing and put a background on the group.

@ajlende
Copy link
Contributor Author

ajlende commented Aug 27, 2021

Now that I have the transparency working, I noticed something unexpected when comparing the color/color with the color/transparent images.

image

Notice that the alpha version isn't exactly the same as the color version. I suspect that this is because sRGB mode still treats the alpha channel as linear since it appears generally darker. I don't have a solution for this yet. It may just be a limitation of SVG filters and/or how browsers have them implemented, but more investigation is needed.

@ajlende
Copy link
Contributor Author

ajlende commented Aug 27, 2021

I think that last commit fixed it.

image

@jasmussen
Copy link
Contributor

This is wild, I love it 👌

@ajlende ajlende marked this pull request as ready for review August 27, 2021 17:51
@MaggieCabrera
Copy link
Contributor

I'm not sure if I'm doing something wrong, but my images look quite different:

Screenshot 2021-08-30 at 09-58-45 Skatepark patterns – fdsfsdf

<!-- wp:image {"align":"full","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["#000","rgba(255, 255, 255, 0)"]},"border":{"radius":"0px"}},"className":"is-style-skatepark-aside-caption"} -->
<figure class="wp-block-image alignfull size-large is-style-skatepark-aside-caption" style="border-radius:0px"><img src="https://skateparkdemo.files.wordpress.com/2021/08/stocksnap_5otfjyvyse.jpg" alt="A skateboarder does a grab trick in a bowl-shaped skate park. In the background is a watching crowd, palm trees, and the ocean."/><figcaption>Learn the basics of skating along with a group of your peers. More advanced at skating? Our skateboarding coaches will work with you 1:1 to advance your technique.</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"align":"full","sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["#000","#BFF5A5"]},"border":{"radius":"0px"}},"className":"is-style-skatepark-aside-caption"} -->
<figure class="wp-block-image alignfull size-large is-style-skatepark-aside-caption" style="border-radius:0px"><img src="https://skateparkdemo.files.wordpress.com/2021/08/stocksnap_5otfjyvyse.jpg" alt="A skateboarder does a grab trick in a bowl-shaped skate park. In the background is a watching crowd, palm trees, and the ocean."/><figcaption>Learn the basics of skating along with a group of your peers. More advanced at skating? Our skateboarding coaches will work with you 1:1 to advance your technique.</figcaption></figure>
<!-- /wp:image -->

@ajlende
Copy link
Contributor Author

ajlende commented Aug 30, 2021

@MaggieCabrera It looks like you have a gradient going from black to transparent white ("duotone":["#000","rgba(255, 255, 255, 0)"]) instead of black to transparent black ("duotone":["#000","rgba(0, 0, 0, 0)"]).

Duotone linearly interpolates between all of the channels including the alpha channel, so the lightness you're seeing at the midpoint is actually a 50% transparent 50% gray instead of 50% transparent black.

@MaggieCabrera
Copy link
Contributor

@MaggieCabrera It looks like you have a gradient going from black to transparent white ("duotone":["#000","rgba(255, 255, 255, 0)"]) instead of black to transparent black ("duotone":["#000","rgba(0, 0, 0, 0)"]).

Duotone linearly interpolates between all of the channels including the alpha channel, so the lightness you're seeing at the midpoint is actually a 50% transparent 50% gray instead of 50% transparent black.

Oh, thanks for explaining, that looks much better!

@jasmussen
Copy link
Contributor

There are a number of things ongoing duotone:

  • The need for default and theme palettes to be available
  • The need for more advanced filtering controls, such as dithering or possibly posterize (Duotone: Add a posterize option #33673)
  • Possibly surfacing tritone as an option, or perhaps even different types of filters including basic color filters

In that vein, I've done some doodles on how to potentially accommodate that in an upgraded "Filter" menu:

Image Filters i14

There are some aspects of the mockup above that still need some thought, which is why I'm posting it here as a comment to just throw it in a part of the loop. Notably whether it's enough to have the defalt presets act both as presets and as filter types, but also whether the "Edit" button to access advanced configuration is clear enough.

@ajlende
Copy link
Contributor Author

ajlende commented Sep 13, 2021

This is what I see in Safari.

transparent-duotone-safari

Transparency seems to work, which is good. The colors look slightly different because of a webkit bug. However, this bug affects the existing duotone filters as well (see the middle image control as an example), so it shouldn't hold up this PR.

The new selector uses rgb instead of hex to support transparency for
duotone
@ajlende ajlende requested review from nerrad and ntwb as code owners September 13, 2021 23:42
Conflicts:
	lib/block-supports/duotone.php
	packages/block-editor/src/hooks/duotone.js
	packages/components/src/color-palette/index.js
	packages/e2e-tests/specs/editor/blocks/heading.test.js
@ajlende ajlende removed request for ntwb and nerrad October 26, 2021 20:25
@ajlende
Copy link
Contributor Author

ajlende commented Oct 26, 2021

Sorry it took me a while to circle back around on this, but it looks like tests are passing again and it's ready for final review!

@ajlende ajlende self-assigned this Oct 28, 2021
@jasmussen jasmussen requested a review from a team October 28, 2021 10:48
Copy link
Member

@mkaz mkaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good, and everything tested well for me.

🚀 🌔

@ajlende ajlende merged commit 56b95cd into WordPress:trunk Oct 29, 2021
@github-actions github-actions bot added this to the Gutenberg 11.9 milestone Oct 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow transparency in duotone filters
6 participants