浏览代码

Skatepark: dynamic duotone support (#4740)

* added duotone support for blocks, removed it from the patterns markup

* Add duotone to site logo too

* If the user changes colors via the customizer also update the default Duotone filter

* created a new filter for the custom duotone

Co-authored-by: Sarah Norris <sarah@sekai.co.uk>

* delete new transient

* fix customizer preview and invert darker palettes

* check luminescence on php to see if we need to invert before saving

* Refactoring the code to make it easier to understand

* Remove closure

* refactor for readability

* merge user filter with theme ones

* Whitespace

* Check the array keys exist properly

* remove var_dumps

* check for the correct values when we define the custom filter

* minified colord file

* updated changelog and credited the colord library

* minified version of colord.js

* removed filter from logo

* Removed duplicated comment

Co-authored-by: Ben Dwyer <ben@scruffian.com>
Co-authored-by: Sarah Norris <sarah@sekai.co.uk>
Maggie 3 年之前
父节点
当前提交
f1a3133076

文件差异内容过多而无法显示
+ 1 - 0
blockbase/inc/customizer/vendors/colord.min.js


+ 1 - 5
blockbase/inc/customizer/wp-customize-color-palettes.php

@@ -87,11 +87,7 @@ class GlobalStylesColorPalettes {
 	}
 
 	function sanitize_color_palette( $palette ) {
-		$palette['slug']  = sanitize_title( $palette['slug'] );
-		$palette['color'] = sanitize_hex_color( $palette['color'] );
-		$palette['name']  = sanitize_title( $palette['name'] );
-
-		return $palette;
+		return sanitize_title($palette);
 	}
 }
 

+ 47 - 0
blockbase/inc/customizer/wp-customize-colors-preview.js

@@ -24,4 +24,51 @@ function blockBaseUpdateColorsPreview( palette ) {
 		'global-styles-colors-customizations-inline-css'
 	);
 	styleElement.innerHTML = innerHTML;
+
+	if ( userColorDuotone ) {
+		const colors = palette.map( ( paletteItem ) => paletteItem.color );
+		//we are inverting the order when we have a darker background so that duotone looks good.
+		colors.sort( ( first, second ) => {
+			if (
+				colord( first ).brightness() > colord( second ).brightness()
+			) {
+				return 1;
+			}
+
+			return -1;
+		} );
+
+		const colorValues = getValuesFromColors( colors );
+
+		updateDuotoneFilter( '#wp-duotone-default-filter', colorValues );
+		updateDuotoneFilter( '#wp-duotone-custom-filter', colorValues );
+	}
+}
+
+function updateDuotoneFilter( filterID, colors ) {
+	if ( document.querySelector( filterID ) ) {
+		document
+			.querySelector( filterID + ' feFuncR' )
+			.setAttribute( 'tableValues', colors.r.join( ' ' ) );
+		document
+			.querySelector( filterID + ' feFuncG' )
+			.setAttribute( 'tableValues', colors.g.join( ' ' ) );
+		document
+			.querySelector( filterID + ' feFuncB' )
+			.setAttribute( 'tableValues', colors.b.join( ' ' ) );
+	}
+}
+
+// This function is from Gutenberg.
+function getValuesFromColors( colors = [] ) {
+	const values = { r: [], g: [], b: [] };
+
+	colors.forEach( ( color ) => {
+		const rgbColor = colord( color ).toRgb();
+		values.r.push( rgbColor.r / 255 );
+		values.g.push( rgbColor.g / 255 );
+		values.b.push( rgbColor.b / 255 );
+	} );
+
+	return values;
 }

+ 62 - 0
blockbase/inc/customizer/wp-customize-colors.php

@@ -20,6 +20,10 @@ class GlobalStylesColorCustomizer {
 		wp_enqueue_script( 'customizer-preview-color', get_template_directory_uri() . '/inc/customizer/wp-customize-colors-preview.js', array( 'customize-preview' ) );
 		wp_add_inline_script( 'customizer-preview-color', 'var userColorSectionKey="' . $this->section_key . '";', 'before' );
 		wp_localize_script( 'customizer-preview-color', 'userColorPalette', $this->user_color_palette );
+		if ( $this->theme_duotone_settings ) {
+			wp_enqueue_script( 'colord', get_template_directory_uri() . '/inc/customizer/vendors/colord.min.js' );
+			wp_localize_script( 'customizer-preview-color', 'userColorDuotone', $this->theme_duotone_settings );
+		}
 	}
 
 	function update_user_color_palette( $wp_customize ) {
@@ -48,9 +52,21 @@ class GlobalStylesColorCustomizer {
 
 	function initialize( $wp_customize ) {
 		$this->user_color_palette = $this->build_user_color_palette();
+		$this->theme_duotone_settings = $this->get_theme_duotone_settings();
 		$this->register_color_controls( $wp_customize, $this->user_color_palette );
 	}
 
+	function get_theme_duotone_settings() {
+		// Get the merged theme.json.
+		$theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
+
+		if ( array_key_exists( 'settings', $theme_json ) && array_key_exists( 'color', $theme_json['settings'] ) && array_key_exists( 'duotone', $theme_json['settings']['color'] ) && array_key_exists( 'theme', $theme_json['settings']['color']['duotone'] ) ) {
+			return $theme_json['settings']['color']['duotone']['theme'];
+		}
+
+		return false;
+	}
+
 	function build_user_color_palette() {
 		// Get the merged theme.json.
 		$theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
@@ -161,6 +177,50 @@ class GlobalStylesColorCustomizer {
 				array( 'settings', 'color', 'palette' ),
 				$this->user_color_palette
 			);
+
+			$primary_key = array_search('primary', array_column($this->user_color_palette, 'slug'));
+			$background_key = array_search('background', array_column($this->user_color_palette, 'slug'));
+
+			if (  $this->theme_duotone_settings && $primary_key !== null && $background_key !== null ) {
+
+				$primary = $this->user_color_palette[$primary_key];
+				$background = $this->user_color_palette[$background_key];
+
+				//we invert the colors when the background is darker than the primary color
+				if( colorLuminescence($primary['color']) > colorLuminescence($background['color']) ) {
+					$primary = $this->user_color_palette[$background_key];
+					$background = $this->user_color_palette[$primary_key];
+				}
+
+				$custom_duotone_filter = array(
+					array(
+						"colors" => array( $primary['color'], $background['color'] ),
+						"slug" => "custom-filter",
+						"name" => "Custom filter"
+					)
+				);
+
+				$custom_duotone_filter_variable = "var(--wp--preset--duotone--custom-filter)";
+				$user_theme_json_post_content = set_settings_array(
+					$user_theme_json_post_content,
+					array( 'settings', 'color', 'duotone' ),
+					array_merge( $custom_duotone_filter, $this->theme_duotone_settings )
+				);
+
+				//replace the new filter in all blocks using duotone
+				$theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
+				if ( $theme_json['styles'] && $theme_json['styles']['blocks'] ) {
+					foreach ( $theme_json['styles']['blocks'] as $key => $block ) {
+						if( $block['filter'] ) {
+							$user_theme_json_post_content = set_settings_array(
+								$user_theme_json_post_content,
+								array( 'styles', 'blocks', $key, 'filter', 'duotone' ),
+								$custom_duotone_filter_variable
+							);
+						}
+					}
+				}
+			}
 		}
 
 		// Update the theme.json with the new settings.
@@ -168,8 +228,10 @@ class GlobalStylesColorCustomizer {
 		wp_update_post( $user_theme_json_post );
 		delete_transient( 'global_styles' );
 		delete_transient( 'gutenberg_global_styles' );
+		delete_transient( 'gutenberg_global_styles_' . get_stylesheet() );
 	}
 
+
 	function check_if_colors_are_default() {
 		foreach ( $this->user_color_palette as $palette_color ) {
 			if ( strtoupper( $palette_color['color'] ) !== strtoupper( $palette_color['default'] ) ) {

+ 1 - 0
blockbase/inc/customizer/wp-customize-fonts.php

@@ -509,6 +509,7 @@ class GlobalStylesFontsCustomizer {
 		wp_update_post( $user_theme_json_post );
 		delete_transient( 'global_styles' );
 		delete_transient( 'gutenberg_global_styles' );
+		delete_transient( 'gutenberg_global_styles_' . get_stylesheet() );
 	}
 
 }

+ 47 - 0
blockbase/inc/customizer/wp-customize-utils.php

@@ -40,3 +40,50 @@ function get_settings_array( $array, $object ) {
 
 	return $object;
 }
+
+// These functions are borrowed from the colorline lib
+function hex_to_rgb( $hex ) {
+	return sscanf( str_replace( '#', '', $hex), '%02X%02X%02X' );
+}
+
+// RGB values: 0-255
+// LUM values: 0-1
+function rgb_to_lum( $rgb ) {
+	list( $r, $g, $b ) = $rgb;
+	return sqrt( 0.241 * $r * $r + 0.691 * $g * $g + 0.068 * $b * $b ) / 255;
+}
+
+// RGB values:    0-255, 0-255, 0-255
+// HSV values:    0-360, 0-100, 0-100, 0-100
+function rgb_to_hsvl( $rgb ) {
+	$l                 = rgb_to_lum( $rgb );
+	list( $r, $g, $b ) = $rgb;
+	$r                 = $r / 255;
+	$g                 = $g / 255;
+	$b                 = $b / 255;
+	$max_rgb           = max( $r, $g, $b );
+	$min_rgb           = min( $r, $g, $b );
+	$chroma            = $max_rgb - $min_rgb;
+	$v                 = 100 * $max_rgb;
+	if ( $chroma > 0 ) {
+		$s = 100 * ( $chroma / $max_rgb );
+		if ( $r === $min_rgb ) {
+			$h = 3 - ( ( $g - $b ) / $chroma );
+		} elseif ( $b === $min_rgb ) {
+			$h = 1 - ( ( $r - $g ) / $chroma );
+		} else { // $g === $min_rgb
+			$h = 5 - ( ( $b - $r ) / $chroma );
+		}
+		$h = 60 * $h;
+		return array( $h, $s, $v, $l );
+	} else {
+		return array( 0, 0, $v, $l );
+	}
+}
+
+function colorLuminescence( $hex ) {
+	$rgb = hex_to_rgb( $hex );
+	$hsvl = rgb_to_hsvl( $rgb );
+
+	return $hsvl[3];
+}

+ 7 - 0
blockbase/readme.txt

@@ -18,6 +18,9 @@ For more information see our README.md file.
 
 == Changelog ==
 
+= 1.2.23 =
+* Added dynamic duotone support to the customizer #4740
+
 = 1.2.22 =
 * Add Kerr as a child theme
 
@@ -125,3 +128,7 @@ The Water Fan, by Winslow Homer
 License: CC0
 Source: https://www.artic.edu/artworks/38666/the-water-fan
 Included in theme screenshot.
+
+Colord library
+License: MIT
+Source: https://github.com/omgovich/colord

+ 1 - 1
skatepark/block-templates/index.html

@@ -10,7 +10,7 @@
 	<hr class="wp-block-separator is-style-wide"/>
 	<!-- /wp:separator -->
 
-	<!-- wp:post-featured-image {"isLink":true,"style":{"color":{"duotone":["#000","#B9FB9C"]}}} /-->
+	<!-- wp:post-featured-image {"isLink":true} /-->
 
 	<!-- wp:post-title {"isLink":true,"fontSize":"normal"} /-->
 

+ 1 - 2
skatepark/block-templates/page.html

@@ -8,8 +8,7 @@
 <main class="wp-block-group" style="padding-bottom:5em">
 
 <!-- wp:group {"align":"full"} -->
-<div class="wp-block-group">
-<!-- wp:post-featured-image {"align":"full","style":{"color":{"duotone":["#000","#B9FB9C"]}}} /--></div>
+<div class="wp-block-group alignfull"><!-- wp:post-featured-image {"align":"full"} /--></div>
 <!-- /wp:group -->
 
 <!-- wp:post-content {"layout":{"inherit":true}} /-->

+ 1 - 1
skatepark/block-templates/single.html

@@ -9,7 +9,7 @@
 
 <!-- wp:group {"align":"full"} -->
 <div class="wp-block-group alignfull">
-<!-- wp:post-featured-image {"align":"full","style":{"color":{"duotone":["#000","#B9FB9C"]}}} /--></div>
+<!-- wp:post-featured-image {"align":"full"} /--></div>
 <!-- /wp:group -->
 
 <!-- wp:post-content {"layout":{"inherit":true}} /-->

+ 18 - 0
skatepark/child-theme.json

@@ -262,15 +262,33 @@
 				}
 			},
 			"core/cover": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				},
 				"spacing": {
 					"padding": "15vh"
 				}
 			},
+			"core/image": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
+			"core/post-author": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
 			"core/post-date": {
 				"typography": {
 					"fontWeight": "500"
 				}
 			},
+			"core/post-featured-image": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
 			"core/post-terms": {
 				"typography": {
 					"fontWeight": "500"

+ 1 - 1
skatepark/inc/patterns/blog-posts.php

@@ -15,7 +15,7 @@ return array(
 	<hr class="wp-block-separator is-style-wide"/>
 	<!-- /wp:separator -->
 
-	<!-- wp:post-featured-image {"isLink":true,"style":{"color":{"duotone":["#000","#B9FB9C"]}}} /-->
+	<!-- wp:post-featured-image {"isLink":true} /-->
 
 	<!-- wp:post-title {"isLink":true,"fontSize":"normal"} /-->
 

+ 2 - 2
skatepark/inc/patterns/columns-in-container.php

@@ -39,8 +39,8 @@ return array(
 	<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>
 	<!-- /wp:spacer -->
 
-	<!-- wp:image {"align":"wide","id":26,"sizeSlug":"large","linkDestination":"none","style":{"color":{"duotone":["#000","#B9FB9C"]}}} -->
-	<figure class="wp-block-image alignwide size-large"><img src="' . get_stylesheet_directory_uri() . '/assets/images/riding-skateboard.jpeg" alt="' . esc_html__( 'Close-up of a person riding a skateboard, focusing on their feet and the board. One foot is on the board, while the other foot is up, in motion. A skatepark is blurred in the background.', 'skatepark' ) . '" class="wp-image-26"/></figure>
+	<!-- wp:image {"align":"wide","sizeSlug":"large","linkDestination":"none"} -->
+	<figure class="wp-block-image alignwide size-large"><img src="' . get_stylesheet_directory_uri() . '/assets/images/riding-skateboard.jpeg" alt="' . esc_html__( 'Close-up of a person riding a skateboard, focusing on their feet and the board. One foot is on the board, while the other foot is up, in motion. A skatepark is blurred in the background.', 'skatepark' ) . '"/></figure>
 	<!-- /wp:image -->
 
 	<!-- wp:spacer {"height":5} -->

+ 2 - 2
skatepark/inc/patterns/full-width-image-with-aside-caption.php

@@ -8,7 +8,7 @@
 return array(
 	'title'      => __( 'Full width image with aside caption', 'skatepark' ),
 	'categories' => array( 'skatepark' ),
-	'content'    => '<!-- 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="' . get_stylesheet_directory_uri() . '/assets/images/skatepark.jpg" alt="' . esc_attr__( "A skateboarder does a grab trick in a bowl-shaped skate park. In the background is a watching crowd, palm trees, and the ocean.", 'skatepark' ) . '"/><figcaption>' . esc_html__( "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.", 'skatepark' ) . '</figcaption></figure>
+	'content'    => '<!-- wp:image {"align":"full","className":"alignfull size-large is-style-skatepark-aside-caption"} -->
+	<figure class="wp-block-image alignfull size-large is-style-skatepark-aside-caption"><img src="' . get_stylesheet_directory_uri() . '/assets/images/skatepark.jpg" alt="' . esc_attr__( "A skateboarder does a grab trick in a bowl-shaped skate park. In the background is a watching crowd, palm trees, and the ocean.", 'skatepark' ) . '"/><figcaption>' . esc_html__( "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.", 'skatepark' ) . '</figcaption></figure>
 	<!-- /wp:image -->',
 );

+ 1 - 1
skatepark/inc/patterns/mixed-media-in-container.php

@@ -29,7 +29,7 @@ return array(
 	<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>
 	<!-- /wp:spacer -->
 
-	<!-- wp:image {"sizeSlug":"large","style":{"color":{"duotone":["#000","#BFF5A5"]}}} -->
+	<!-- wp:image {"sizeSlug":"large"} -->
 	<figure class="wp-block-image size-large"><img src="' . get_stylesheet_directory_uri() . '/assets/images/skateboard-sideways.jpg" " alt="' . esc_attr__( 'A skateboard laying on its side on top of concrete.', 'skatepark' ) . '"/></figure>
 	<!-- /wp:image -->
 

+ 18 - 0
skatepark/theme.json

@@ -544,10 +544,28 @@
 				}
 			},
 			"core/cover": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				},
 				"spacing": {
 					"padding": "15vh"
 				}
 			},
+			"core/image": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
+			"core/post-author": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
+			"core/post-featured-image": {
+				"filter": {
+					"duotone": "var(--wp--preset--duotone--default-filter)"
+				}
+			},
 			"core/post-terms": {
 				"typography": {
 					"fontWeight": "500"

部分文件因为文件数量过多而无法显示