Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
40c4786
Sort style.scss
ajlende Apr 29, 2020
411939b
Add color effects block
ajlende Apr 29, 2020
cb240e4
Add InnerBlocks template
ajlende Apr 29, 2020
a517475
Fix canvas z-index in editor
ajlende Apr 29, 2020
0e9f260
Add min height adjust
ajlende Apr 29, 2020
4bc8285
Refactor ResizableBox
ajlende Apr 30, 2020
9b25dde
Disable webgl when prefers-reduced-motion is set
ajlende May 1, 2020
924c642
Disable rendering for devices without hardware acceleration
ajlende May 1, 2020
8246b76
Remove comment about multiple shaders
ajlende May 1, 2020
aac450b
Remove unused dependency
ajlende May 1, 2020
d39512d
Fix running effect when adding a block
ajlende May 1, 2020
d9dffc4
Remove lodash dependency
ajlende May 1, 2020
af8fb82
Add fallback gradient
ajlende May 1, 2020
8a49c7b
Show default colors in color panel
ajlende May 1, 2020
ee0d325
Refactor to hooks
ajlende May 1, 2020
65cd125
Add padding to inner container
ajlende May 1, 2020
71e2d04
Fix height resize bugs
ajlende May 2, 2020
dd0d949
Re-enable the effect after configuing the fallback
ajlende May 2, 2020
e8d67ed
Fix spacing
ajlende May 2, 2020
c2012d6
Still render pattern when reduce motion is set
ajlende May 2, 2020
9b972c4
Allow multiple
ajlende May 2, 2020
de24a9c
Fix z-index on animation
ajlende May 2, 2020
3e1b286
Rename Gradient to Color
ajlende May 5, 2020
a96addd
Refactor out fallback style
ajlende May 5, 2020
22eee61
Use default colors from theme
ajlende May 5, 2020
fee1805
Fix asset file name
ajlende May 5, 2020
1f47b70
Micro optimization for renderLiquidEffect
ajlende May 6, 2020
364d4b3
Fix initial block editor loading
ajlende May 6, 2020
edf37b2
Add spacing for code readability
ajlende May 6, 2020
65b5f49
Fix eslint warnings
ajlende May 6, 2020
494dca5
Refactor render arguments
ajlende May 6, 2020
bbf2cfc
Refactor shouldAnimate
ajlende May 6, 2020
83423b8
Refactor shader code out of run
ajlende May 6, 2020
ba28630
Refactor init
ajlende May 6, 2020
8658cb1
Refactor out render functions
ajlende May 6, 2020
7c29951
Add rendered image as fallback
ajlende May 6, 2020
25430cf
Change defaults
ajlende May 11, 2020
59279c7
Adjust the complexity range
ajlende May 14, 2020
88fcf6c
Add color-effects bundle
ajlende May 14, 2020
3077129
Adjust complexity range
ajlende May 20, 2020
467d9c9
Adjust initial colors to only 3 colors
ajlende May 20, 2020
be3427f
Lower default complexity
ajlende May 20, 2020
704de5f
Refactor mouse and fluid speed functions
ajlende May 21, 2020
e51824e
Add doc comment for init
ajlende May 21, 2020
bd4564d
Lower default values for mouse and fluid speed
ajlende May 21, 2020
c6b1398
Add block assets
ajlende May 21, 2020
fb74f12
Rename color-effects to waves
ajlende May 21, 2020
ebf1fc2
Add waves icon
ajlende May 21, 2020
9e85a22
i18n strings
ajlende May 21, 2020
c7752ac
Namespace i18n strings
ajlende May 21, 2020
ef7f432
Add wp-dom-ready dependency
ajlende May 21, 2020
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
21 changes: 21 additions & 0 deletions blocks/waves/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* Editor styles */

.wp-block-a8c-waves {
&__inner-container
> .block-editor-inner-blocks
> .block-editor-block-list__layout {
margin-left: 0;
margin-right: 0;
}

&__resize-container:not( .is-resizing ) {
// Important is used to have higher specificity than the inline style set by re-resizable library.
height: auto !important;
}

[data-align='left'] > &,
[data-align='right'] > & {
max-width: 290px;
width: 100%;
}
}
1 change: 1 addition & 0 deletions blocks/waves/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ "twgl/twgl.js", "waves.js" ]
31 changes: 31 additions & 0 deletions blocks/waves/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

add_action( 'init', function() {
register_block_type( 'a8c/waves', [
'editor_script' => 'block-experiments',
'style' => 'block-experiments',
'editor_style' => 'block-experiments-editor',
'render_callback' => function( $attribs, $content ) {
wp_enqueue_script( 'a8c-waves-js' );
return $content;
},
] );
wp_register_script(
'a8c-twgl-js',
plugins_url( 'twgl/twgl.js', __FILE__ ),
[], // no dependencies
filemtime( plugin_dir_path( __FILE__ ) . 'twgl/twgl.js' ),
true // in footer
);
wp_register_script(
'a8c-waves-js',
plugins_url( 'waves.js', __FILE__ ),
[ 'a8c-twgl-js', 'wp-dom-ready' ],
filemtime( plugin_dir_path( __FILE__ ) . 'waves.js' ),
true // in footer
);
} );

add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script( 'a8c-waves-js' );
} );
325 changes: 325 additions & 0 deletions blocks/waves/src/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
InspectorControls,
PanelColorSettings,
InnerBlocks,
__experimentalUnitControl as UnitControl,
} from '@wordpress/block-editor';
import {
PanelBody,
RangeControl,
ResizableBox,
BaseControl,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { useDispatch, useSelect } from '@wordpress/data';
import { useState, useEffect, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

const DEFAULT_COLORS = {
color1: '#000',
color2: '#555',
color3: '#AAA',
color4: '#FFF',
};

const MIN_HEIGHT = 50;

const CSS_UNITS = [
{ value: 'px', label: 'px', default: 430 },
{ value: 'em', label: 'em', default: 20 },
{ value: 'rem', label: 'rem', default: 20 },
{ value: 'vw', label: 'vw', default: 20 },
{ value: 'vh', label: 'vh', default: 50 },
];

const RESIZABLE_BOX_ENABLE_OPTION = {
top: false,
right: false,
bottom: true,
left: false,
topRight: false,
bottomRight: false,
bottomLeft: false,
topLeft: false,
};

function HeightInput( { onChange, onUnitChange, unit = 'px', value = '' } ) {
const [ temporaryInput, setTemporaryInput ] = useState( null );
const instanceId = useInstanceId( UnitControl );
const inputId = `a8c-waves-height-input-${ instanceId }`;
const isPx = unit === 'px';

const handleOnChange = ( unprocessedValue ) => {
const inputValue =
unprocessedValue !== ''
? parseInt( unprocessedValue, 10 )
: undefined;

if ( isNaN( inputValue ) && inputValue !== undefined ) {
setTemporaryInput( unprocessedValue );
return;
}
setTemporaryInput( null );
onChange( inputValue );
};

const handleOnBlur = () => {
if ( temporaryInput !== null ) {
setTemporaryInput( null );
}
};

const inputValue = temporaryInput !== null ? temporaryInput : value;
const min = isPx ? MIN_HEIGHT : 0;

return (
<BaseControl
label={ __( 'Minimum height of cover', 'waves' ) }
id={ inputId }
>
<UnitControl
id={ inputId }
min={ min }
onBlur={ handleOnBlur }
onChange={ handleOnChange }
onUnitChange={ onUnitChange }
step="1"
style={ { maxWidth: 80 } }
unit={ unit }
units={ CSS_UNITS }
value={ inputValue }
/>
</BaseControl>
);
}

function Edit( { attributes, className, isSelected, setAttributes } ) {
const { toggleSelection } = useDispatch( 'core/block-editor' );
const [ temporaryMinHeight, setTemporaryMinHeight ] = useState( null );
const [ isResizing, setIsResizing ] = useState( false );

const themeColors = useSelect(
( select ) => select( 'core/block-editor' ).getSettings().colors,
[]
);
const colors = {
color1:
attributes.color1 ||
themeColors[ 0 ].color ||
DEFAULT_COLORS.color1,
color2:
attributes.color2 ||
themeColors[ 0 ].color ||
DEFAULT_COLORS.color2,
color3:
attributes.color3 ||
themeColors[ 1 % themeColors.length ].color ||
DEFAULT_COLORS.color3,
color4:
attributes.color4 ||
themeColors[ 2 % themeColors.length ].color ||
DEFAULT_COLORS.color4,
};

const renderPreview = ( newAttributes = {} ) =>
window.a8cColorEffects.renderPreview( {
complexity: attributes.complexity,
mouseSpeed: 1,
fluidSpeed: 1,
...colors,
...newAttributes,
} );

useEffect( () => {
// Defaults need to be saved in the attributes because they are dynamic
// based on theme, and theme settings are not available from save.
Object.entries( colors ).forEach( ( [ key, value ] ) => {
if ( attributes[ key ] === undefined ) {
setAttributes( { [ key ]: value } );
}
} );

// Save the initial preview in the attributes
if ( attributes.previewImage === undefined ) {
const previewImage = renderPreview();
setAttributes( { previewImage } );
}
}, [] );

const minHeightWithUnit = attributes.minHeightUnit
? `${ attributes.minHeight }${ attributes.minHeightUnit }`
: attributes.minHeight;
const style = {
minHeight: temporaryMinHeight || minHeightWithUnit || undefined,
backgroundImage: `url( "${ attributes.previewImage }" )`,
};

const canvasRef = useRef();
useEffect( () => {
return window.a8cColorEffects.run( canvasRef.current );
}, [ canvasRef.current ] );

return (
<>
<InspectorControls>
<PanelBody title={ __( 'Animation', 'waves' ) } initialOpen>
<RangeControl
label={ __( 'Complexity', 'waves' ) }
value={ attributes.complexity }
onChange={ ( complexity ) => {
const previewImage = renderPreview( {
complexity,
} );
setAttributes( { complexity, previewImage } );
} }
min={ 1 }
max={ 10 }
/>
<RangeControl
label={ __( 'Mouse Speed', 'waves' ) }
value={ attributes.mouseSpeed }
onChange={ ( mouseSpeed ) =>
setAttributes( { mouseSpeed } )
}
min={ 1 }
max={ 100 }
/>
<RangeControl
label={ __( 'Fluid Speed', 'waves' ) }
value={ attributes.fluidSpeed }
onChange={ ( fluidSpeed ) =>
setAttributes( { fluidSpeed } )
}
min={ 1 }
max={ 100 }
/>
</PanelBody>
<PanelColorSettings
title={ __( 'Color', 'waves' ) }
initialOpen
colorSettings={ [
{
label: __( 'Color 1', 'waves' ),
value: colors.color1,
onChange: ( color1 ) => {
const previewImage = renderPreview( {
color1,
} );
setAttributes( { color1, previewImage } );
},
},
{
label: __( 'Color 2', 'waves' ),
value: colors.color2,
onChange: ( color2 ) => {
const previewImage = renderPreview( {
color2,
} );
setAttributes( { color2, previewImage } );
},
},
{
label: __( 'Color 3', 'waves' ),
value: colors.color3,
onChange: ( color3 ) => {
const previewImage = renderPreview( {
color3,
} );
setAttributes( { color3, previewImage } );
},
},
{
label: __( 'Color 4', 'waves' ),
value: colors.color4,
onChange: ( color4 ) => {
const previewImage = renderPreview( {
color4,
} );
setAttributes( { color4, previewImage } );
},
},
] }
/>
<PanelBody title={ __( 'Dimensions', 'waves' ) }>
<HeightInput
value={ temporaryMinHeight || attributes.minHeight }
unit={ attributes.minHeightUnit }
onChange={ ( minHeight ) =>
setAttributes( { minHeight } )
}
onUnitChange={ ( minHeightUnit ) =>
setAttributes( { minHeightUnit } )
}
/>
</PanelBody>
</InspectorControls>
<ResizableBox
className={ classnames( `${ className }__resize-container`, {
'is-resizing': isResizing,
} ) }
enable={ RESIZABLE_BOX_ENABLE_OPTION }
onResizeStart={ ( event, direction, elt ) => {
toggleSelection( false );
setAttributes( { minHeightUnit: 'px' } );
setTemporaryMinHeight( elt.clientHeight );
} }
onResize={ ( event, direction, elt ) => {
// Setting is-resizing here instead of onResizeStart fixes
// an issue with the positioning of the resize bar when
// starting a resize after having resized smaller than the
// auto height
setIsResizing( true );
setTemporaryMinHeight( elt.clientHeight );
} }
onResizeStop={ ( event, direction, elt ) => {
toggleSelection( true );
setIsResizing( false );
setAttributes( { minHeight: elt.clientHeight } );
setTemporaryMinHeight( null );
} }
minHeight={ MIN_HEIGHT }
showHandle={ isSelected }
>
<div className={ className } style={ style }>
<canvas
ref={ canvasRef }
data-complexity={ attributes.complexity }
data-mouse-speed={ attributes.mouseSpeed }
data-fluid-speed={ attributes.fluidSpeed }
data-color1={ colors.color1 }
data-color2={ colors.color2 }
data-color3={ colors.color3 }
data-color4={ colors.color4 }
/>
<div className={ `${ className }__inner-container` }>
<InnerBlocks
template={ [
[
'core/paragraph',
{
align: 'center',
fontSize: 'large',
placeholder: __(
'Write title…',
'waves'
),
},
],
] }
/>
</div>
</div>
</ResizableBox>
</>
);
}

export default Edit;
Loading