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

Add duotone to image block #26751

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ The settings section has the following structure and default values:
"color": {
"custom": true, /* false to opt-out, as in add_theme_support('disable-custom-colors') */
"customGradient": true, /* false to opt-out, as in add_theme_support('disable-custom-gradients') */
"duotone": [ ... ], /* duotone presets, a list of { "colors": [ "#000", "#FFF" ] } */
"gradients": [ ... ], /* gradient presets, as in add_theme_support('editor-gradient-presets', ... ) */
"link": false, /* true to opt-in, as in add_theme_support('experimental-link-color') */
"palette": [ ... ], /* color presets, as in add_theme_support('editor-color-palette', ... ) */
Expand Down
2 changes: 1 addition & 1 deletion lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ function gutenberg_reregister_core_block_types() {
'group',
'heading',
'html',
'image',
'list',
'media-text',
'missing',
Expand Down Expand Up @@ -55,6 +54,7 @@ function gutenberg_reregister_core_block_types() {
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
'cover.php' => 'core/cover',
'image.php' => 'core/image',
'latest-comments.php' => 'core/latest-comments',
'latest-posts.php' => 'core/latest-posts',
'navigation.php' => 'core/navigation',
Expand Down
16 changes: 16 additions & 0 deletions lib/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,22 @@ public static function get_core_data() {
}
}

$default_duotone_i18n = array(
'dark-grayscale' => __( 'Dark grayscale', 'gutenberg' ),
'grayscale' => __( 'Grayscale', 'gutenberg' ),
'purple-yellow' => __( 'Purple and yellow', 'gutenberg' ),
'blue-red' => __( 'Blue and red', 'gutenberg' ),
'midnight' => __( 'Midnight', 'gutenberg' ),
'magenta-yellow' => __( 'Magenta and yellow', 'gutenberg' ),
'purple-green' => __( 'Purple and green', 'gutenberg' ),
'blue-orange' => __( 'Blue and orange', 'gutenberg' ),
);
if ( ! empty( $config['global']['settings']['color']['duotone'] ) ) {
foreach ( $config['global']['settings']['color']['duotone'] as &$gradient ) {
$gradient['name'] = $default_duotone_i18n[ $gradient['slug'] ];
}
}

$default_font_sizes_i18n = array(
'small' => __( 'Small', 'gutenberg' ),
'normal' => __( 'Normal', 'gutenberg' ),
Expand Down
1 change: 1 addition & 0 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class WP_Theme_JSON {
'gradients' => null,
'link' => null,
'palette' => null,
'duotone' => null,
),
'spacing' => array(
'customPadding' => null,
Expand Down
59 changes: 59 additions & 0 deletions lib/duotone-filter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Duotone filter markup.
*
* @package gutenberg
*/

/**
* SVG and stylesheet needed for rendering the duotone filter.
*
* @param string $selector CSS selectors to apply the duotone to.
* @param string $id Unique slug for this duotone filter.
* @param array $values R, G, and B values to filter with.
* @return string Duotone stylesheet and SVG.
*/
function gutenberg_render_duotone_filter( $selector, $id, $values ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this thing not absorbed in the block support?

Copy link
Contributor Author

@ajlende ajlende Feb 26, 2021

Choose a reason for hiding this comment

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

It's needed later in the image block render and in any block that wants to implement duotone without block supports

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking that ideally, all blocks should rely on the block support and don't implement this adhoc. Is this possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, if we go with what you said in #26751 (comment), we can make that happen. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this is getting moved exclusively to block supports, you can start reviewing the blocks supports parts unique to https://github.com/WordPress/gutenberg/pull/26752/files#diff-fd626ca219f3d805667d480eabb2d890a5a8d2e015b37f03cf8980edf1ae3d58 and WordPress/wordpress-develop#984

ob_start();

?>

<style>
<?php echo $selector; ?> {
filter: url( <?php echo esc_url( '#' . $id ); ?> );
}
</style>

<svg
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 0 0"
width="0"
height="0"
focusable="false"
role="none"
style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
>
<defs>
<filter id="<?php echo esc_attr( $id ); ?>">
<feColorMatrix
type="matrix"
<?php // phpcs:disable Generic.WhiteSpace.DisallowSpaceIndent ?>
values=".299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
0 0 0 1 0"
<?php // phpcs:enable Generic.WhiteSpace.DisallowSpaceIndent ?>
/>
<feComponentTransfer color-interpolation-filters="sRGB" >
<feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $values['r'] ) ); ?>" />
<feFuncG type="table" tableValues="<?php echo esc_attr( implode( ' ', $values['g'] ) ); ?>" />
<feFuncB type="table" tableValues="<?php echo esc_attr( implode( ' ', $values['b'] ) ); ?>" />
</feComponentTransfer>
</filter>
</defs>
</svg>

<?php

return ob_get_clean();
}
42 changes: 42 additions & 0 deletions lib/experimental-default-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,48 @@
"slug": "midnight"
}
],
"duotone": [
{
"name": "Dark grayscale" ,
"colors": [ "#000000", "#7f7f7f" ],
"slug": "dark-grayscale"
},
{
"name": "Grayscale" ,
"colors": [ "#000000", "#ffffff" ],
"slug": "grayscale"
},
{
"name": "Purple and yellow" ,
"colors": [ "#8c00b7", "#fcff41" ],
"slug": "purple-yellow"
},
{
"name": "Blue and red" ,
"colors": [ "#000097", "#ff4747" ],
"slug": "blue-red"
},
{
"name": "Midnight" ,
"colors": [ "#000000", "#00a5ff" ],
"slug": "midnight"
},
{
"name": "Magenta and yellow" ,
"colors": [ "#c7005a", "#fff278" ],
"slug": "magenta-yellow"
},
{
"name": "Purple and green" ,
"colors": [ "#a60072", "#67ff66" ],
"slug": "purple-green"
},
{
"name": "Blue and orange" ,
"colors": [ "#1900d8", "#ffa96b" ],
"slug": "blue-orange"
}
],
"custom": true,
"link": false,
"customGradient": true
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/experiments-page.php';
require __DIR__ . '/global-styles.php';
require __DIR__ . '/query-utils.php';
require __DIR__ . '/duotone-filter.php';

if ( ! class_exists( 'WP_Block_Supports' ) ) {
require_once __DIR__ . '/class-wp-block-supports.php';
Expand Down
81 changes: 81 additions & 0 deletions packages/block-editor/src/components/duotone-filter/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* WordPress dependencies
*/
import { SVG } from '@wordpress/components';

/**
* Values for the SVG `feComponentTransfer`.
*
* @typedef Values {Object}
* @property {number[]} r Red values.
* @property {number[]} g Green values.
* @property {number[]} b Blue values.
*/

/**
* SVG and stylesheet needed for rendering the duotone filter.
*
* @param {Object} props Duotone props.
* @param {string} props.selector Selector to apply the filter to.
* @param {string} props.id Unique id for this duotone filter.
* @param {Values} props.values R, G, and B values to filter with.
* @return {WPElement} Duotone element.
*/
export default function DuotoneFilter( { selector, id, values } ) {
const stylesheet = `
${ selector } {
filter: url( #${ id } );
}
`;

return (
<>
<SVG
xmlnsXlink="http://www.w3.org/1999/xlink"
viewBox="0 0 0 0"
width="0"
height="0"
focusable="false"
role="none"
style={ {
visibility: 'hidden',
position: 'absolute',
left: '-9999px',
overflow: 'hidden',
} }
>
<defs>
<filter id={ id }>
<feColorMatrix
type="matrix"
// Use perceptual brightness to convert to grayscale.
// prettier-ignore
values=".299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
0 0 0 1 0"
/>
<feComponentTransfer
// Use sRGB instead of linearRGB to be consistent with how CSS gradients work.
colorInterpolationFilters="sRGB"
>
<feFuncR
type="table"
tableValues={ values.r.join( ' ' ) }
/>
<feFuncG
type="table"
tableValues={ values.g.join( ' ' ) }
/>
<feFuncB
type="table"
tableValues={ values.b.join( ' ' ) }
/>
</feComponentTransfer>
</filter>
</defs>
</SVG>
<style dangerouslySetInnerHTML={ { __html: stylesheet } } />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* WordPress dependencies
*/
import { __experimentalCustomGradientBar as CustomGradientBar } from '@wordpress/components';

/**
* Internal dependencies
*/
import {
getColorStopsFromValues,
getCustomDuotoneIdFromColorStops,
getGradientFromValues,
getValuesFromColorStops,
} from './utils';

const PLACEHOLDER_VALUES = {
r: [ 0.2, 0.8 ],
g: [ 0.2, 0.8 ],
b: [ 0.2, 0.8 ],
};

export default function CustomDuotoneBar( { value, onChange } ) {
const hasGradient = !! value?.values;
const values = hasGradient ? value.values : PLACEHOLDER_VALUES;
const background = getGradientFromValues( values );
const controlPoints = getColorStopsFromValues( values );
return (
<div className="components-custom-duotone-picker">
<CustomGradientBar
disableInserter
disableAlpha
background={ background }
hasGradient={ hasGradient }
value={ controlPoints }
onChange={ ( newColorStops ) => {
const newDuotone = {
id: getCustomDuotoneIdFromColorStops( newColorStops ),
values: getValuesFromColorStops( newColorStops ),
};
onChange( newDuotone );
} }
/>
</div>
);
}
Loading