diff --git a/blockbase/inc/customizer/vendors/colord.min.js b/blockbase/inc/customizer/vendors/colord.min.js new file mode 100644 index 0000000000..cf68e229e2 --- /dev/null +++ b/blockbase/inc/customizer/vendors/colord.min.js @@ -0,0 +1,8 @@ +// https://github.com/omgovich/colord +var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return{h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},c=function(r){return{h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=c(this.rgba);return"number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r))})},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; + +var Colord = j; +var colord = w; +var extend = k; +var getFormat = I; +var random = E; diff --git a/blockbase/inc/customizer/wp-customize-color-palettes.php b/blockbase/inc/customizer/wp-customize-color-palettes.php index de7ed2332a..d619304c6b 100644 --- a/blockbase/inc/customizer/wp-customize-color-palettes.php +++ b/blockbase/inc/customizer/wp-customize-color-palettes.php @@ -87,11 +87,7 @@ function color_palette_control( $wp_customize ) { } 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); } } diff --git a/blockbase/inc/customizer/wp-customize-colors-preview.js b/blockbase/inc/customizer/wp-customize-colors-preview.js index a9d1634d9f..eb77b176b6 100644 --- a/blockbase/inc/customizer/wp-customize-colors-preview.js +++ b/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; } diff --git a/blockbase/inc/customizer/wp-customize-colors.php b/blockbase/inc/customizer/wp-customize-colors.php index fa74c44d12..13b43cfd09 100644 --- a/blockbase/inc/customizer/wp-customize-colors.php +++ b/blockbase/inc/customizer/wp-customize-colors.php @@ -20,6 +20,10 @@ function customize_preview_js() { 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 @@ function create_customization_style_element( $wp_customize ) { 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 @@ function handle_customize_save_after( $wp_customize ) { 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 @@ function handle_customize_save_after( $wp_customize ) { 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'] ) ) { diff --git a/blockbase/inc/customizer/wp-customize-fonts.php b/blockbase/inc/customizer/wp-customize-fonts.php index bab93e13ee..ec101eb9a0 100644 --- a/blockbase/inc/customizer/wp-customize-fonts.php +++ b/blockbase/inc/customizer/wp-customize-fonts.php @@ -509,6 +509,7 @@ function handle_customize_save_after( $wp_customize ) { wp_update_post( $user_theme_json_post ); delete_transient( 'global_styles' ); delete_transient( 'gutenberg_global_styles' ); + delete_transient( 'gutenberg_global_styles_' . get_stylesheet() ); } } diff --git a/blockbase/inc/customizer/wp-customize-utils.php b/blockbase/inc/customizer/wp-customize-utils.php index ec99c73cbd..5218b9df55 100644 --- a/blockbase/inc/customizer/wp-customize-utils.php +++ b/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]; +} \ No newline at end of file diff --git a/blockbase/readme.txt b/blockbase/readme.txt index 11099cedfa..cadac2c6b3 100644 --- a/blockbase/readme.txt +++ b/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 diff --git a/skatepark/block-templates/index.html b/skatepark/block-templates/index.html index 5f36b6b9ab..b933d35c91 100644 --- a/skatepark/block-templates/index.html +++ b/skatepark/block-templates/index.html @@ -10,7 +10,7 @@
- + diff --git a/skatepark/block-templates/page.html b/skatepark/block-templates/page.html index a6856ec333..6ebd30dbf3 100644 --- a/skatepark/block-templates/page.html +++ b/skatepark/block-templates/page.html @@ -8,8 +8,7 @@
-
-
+
diff --git a/skatepark/block-templates/single.html b/skatepark/block-templates/single.html index f0769f869d..a5132db174 100644 --- a/skatepark/block-templates/single.html +++ b/skatepark/block-templates/single.html @@ -9,7 +9,7 @@
-
+ diff --git a/skatepark/child-theme.json b/skatepark/child-theme.json index 6d044b8bad..b81da348e9 100644 --- a/skatepark/child-theme.json +++ b/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" diff --git a/skatepark/inc/patterns/blog-posts.php b/skatepark/inc/patterns/blog-posts.php index fd04548cec..d20d58fa39 100644 --- a/skatepark/inc/patterns/blog-posts.php +++ b/skatepark/inc/patterns/blog-posts.php @@ -15,7 +15,7 @@
- + diff --git a/skatepark/inc/patterns/columns-in-container.php b/skatepark/inc/patterns/columns-in-container.php index 84201cd1ce..46b9d6881f 100644 --- a/skatepark/inc/patterns/columns-in-container.php +++ b/skatepark/inc/patterns/columns-in-container.php @@ -39,8 +39,8 @@ - -
' . 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' ) . '
+ +
' . 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' ) . '
diff --git a/skatepark/inc/patterns/full-width-image-with-aside-caption.php b/skatepark/inc/patterns/full-width-image-with-aside-caption.php index 9c77d72bb0..f1ac808967 100644 --- a/skatepark/inc/patterns/full-width-image-with-aside-caption.php +++ b/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' => ' -
' . esc_attr__(
' . 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' ) . '
+ 'content' => ' +
' . esc_attr__(
' . 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' ) . '
', ); diff --git a/skatepark/inc/patterns/mixed-media-in-container.php b/skatepark/inc/patterns/mixed-media-in-container.php index e784c6b1ad..7a3ad8a3da 100644 --- a/skatepark/inc/patterns/mixed-media-in-container.php +++ b/skatepark/inc/patterns/mixed-media-in-container.php @@ -29,7 +29,7 @@ - +
' . esc_attr__( 'A skateboard laying on its side on top of concrete.', 'skatepark' ) . '
diff --git a/skatepark/theme.json b/skatepark/theme.json index 82f6bb628d..65d90b99f3 100644 --- a/skatepark/theme.json +++ b/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"