diff --git a/packages/block-library/src/cover/edit/index.js b/packages/block-library/src/cover/edit/index.js index 932281b1ab6f1b..678a9f8bc14db0 100644 --- a/packages/block-library/src/cover/edit/index.js +++ b/packages/block-library/src/cover/edit/index.js @@ -158,7 +158,7 @@ function CoverEdit( { dimRatio, overlayColor.color ); - setMedia( newMedia, isDarkSetting ); + await setMedia( newMedia, isDarkSetting ); }; const onClearMedia = async () => { diff --git a/packages/block-library/src/cover/shared.js b/packages/block-library/src/cover/shared.js index 72a42c0d5c70b8..8d95d060d9d995 100644 --- a/packages/block-library/src/cover/shared.js +++ b/packages/block-library/src/cover/shared.js @@ -42,7 +42,7 @@ export function dimRatioToClass( ratio ) { } export function attributesFromMedia( setAttributes, dimRatio ) { - return ( media, isDark ) => { + return async ( media, isDark ) => { if ( ! media || ! media.url ) { setAttributes( { url: undefined, id: undefined, isDark } ); return; @@ -73,12 +73,22 @@ export function attributesFromMedia( setAttributes, dimRatio ) { mediaType = media.type; } + let customOverlayColor = await getAverageMediaColor( media.url ); + /*eslint no-bitwise: ["error", { "allow": ["|","<<"] }] */ + customOverlayColor = customOverlayColor + ? '#' + + ( customOverlayColor.r | ( 1 << 8 ) ).toString( 16 ).slice( 1 ) + + ( customOverlayColor.g | ( 1 << 8 ) ).toString( 16 ).slice( 1 ) + + ( customOverlayColor.b | ( 1 << 8 ) ).toString( 16 ).slice( 1 ) + : customOverlayColor; + setAttributes( { isDark, dimRatio: dimRatio === 100 ? 50 : dimRatio, url: media.url, id: media.id, alt: media?.alt, + customOverlayColor, backgroundType: mediaType, focalPoint: undefined, ...( mediaType === VIDEO_BACKGROUND_TYPE @@ -200,3 +210,32 @@ export async function getCoverIsDark( url, dimRatio = 50, overlayColor ) { const composite = compositeSourceOver( overlay, background ); return colord( composite ).isDark(); } + +export async function getAverageMediaColor( url ) { + if ( url ) { + try { + const imgCrossOrigin = applyFilters( + 'media.crossOrigin', + undefined, + url + ); + const { + value: [ r, g, b, a ], + } = await retrieveFastAverageColor().getColorAsync( url, { + // Previously the default color was white, but that changed + // in v6.0.0 so it has to be manually set now. + defaultColor: [ 255, 255, 255, 255 ], + // Errors that come up don't reject the promise, so error + // logging has to be silenced with this option. + silent: process.env.NODE_ENV === 'production', + crossOrigin: imgCrossOrigin, + } ); + // FAC uses 0-255 for alpha, but colord expects 0-1. + return { r, g, b, a: a / 255 }; + } catch ( error ) { + // If there's an error, just assume the image is dark. + return false; + } + } + return false; +}