-
Notifications
You must be signed in to change notification settings - Fork 381
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
[amp-stories sub-task] Add front-end animation. #1385
Changes from 4 commits
47b3f15
54b1272
6b5cb8b
2b51ab1
5e9a535
853f7fb
afa038c
1870954
8518dae
10826df
6c569c8
32b7524
e111fa4
549c7b0
e9ffbcb
d73ab0d
64cad60
2eb230d
596a0c7
04ed6a7
4923569
ad4ecbb
002bda3
38932ff
cb0fd56
673206e
c3d5c34
0a2916d
c2a297c
224ef00
def0ce0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,84 @@ var ampStoryEditorBlocks = ( function() { // eslint-disable-line no-unused-vars | |
value: 'lower-third', | ||
label: __( 'Lower Third', 'amp' ) | ||
} | ||
], | ||
ampAnimationTypeOptions: [ | ||
{ | ||
value: '', | ||
label: __( 'None', 'amp' ) | ||
}, | ||
{ | ||
value: 'drop', | ||
label: __( 'Drop', 'amp' ) | ||
}, | ||
{ | ||
value: 'fade-in', | ||
label: __( 'Fade In', 'amp' ) | ||
}, | ||
{ | ||
value: 'fly-in-bottom', | ||
label: __( 'Fly In Bottom', 'amp' ) | ||
}, | ||
{ | ||
value: 'fly-in-left', | ||
label: __( 'Fly In Left', 'amp' ) | ||
}, | ||
{ | ||
value: 'fly-in-right', | ||
label: __( 'Fly In Right', 'amp' ) | ||
}, | ||
{ | ||
value: 'fly-in-top', | ||
label: __( 'Fly In Top', 'amp' ) | ||
}, | ||
{ | ||
value: 'pulse', | ||
label: __( 'Pulse', 'amp' ) | ||
}, | ||
{ | ||
value: 'rotate-in-left', | ||
label: __( 'Rotate In Left', 'amp' ) | ||
}, | ||
{ | ||
value: 'rotate-in-right', | ||
label: __( 'Rotate In Right', 'amp' ) | ||
}, | ||
{ | ||
value: 'twirl-in', | ||
label: __( 'Twirl In', 'amp' ) | ||
}, | ||
{ | ||
value: 'whoosh-in-left', | ||
label: __( 'Whoosh In Left', 'amp' ) | ||
}, | ||
{ | ||
value: 'whoosh-in-right', | ||
label: __( 'Whoosh In Right', 'amp' ) | ||
}, | ||
{ | ||
value: 'pan-left', | ||
label: __( 'Pan Left', 'amp' ) | ||
}, | ||
{ | ||
value: 'pan-right', | ||
label: __( 'Pan Right', 'amp' ) | ||
}, | ||
{ | ||
value: 'pan-down', | ||
label: __( 'Pan Down', 'amp' ) | ||
}, | ||
{ | ||
value: 'pan-up', | ||
label: __( 'Pan Up', 'amp' ) | ||
}, | ||
{ | ||
value: 'zoom-in', | ||
label: __( 'Zoom In', 'amp' ) | ||
}, | ||
{ | ||
value: 'zoom-out', | ||
label: __( 'Zoom Out', 'amp' ) | ||
} | ||
] | ||
} | ||
}; | ||
|
@@ -119,6 +197,16 @@ var ampStoryEditorBlocks = ( function() { // eslint-disable-line no-unused-vars | |
if ( attributes.ampStoryPosition ) { | ||
ampAttributes[ 'grid-area' ] = attributes.ampStoryPosition; | ||
} | ||
if ( attributes.ampAnimationType ) { | ||
ampAttributes[ 'animate-in' ] = attributes.ampAnimationType; | ||
|
||
if ( attributes.ampAnimationDelay ) { | ||
ampAttributes[ 'animate-in-delay' ] = attributes.ampAnimationDelay + 'ms'; | ||
} | ||
if ( attributes.ampAnimationDuration ) { | ||
ampAttributes[ 'animate-in-duration' ] = attributes.ampAnimationDuration + 'ms'; | ||
} | ||
} | ||
|
||
return _.extend( ampAttributes, props ); | ||
}; | ||
|
@@ -131,14 +219,26 @@ var ampStoryEditorBlocks = ( function() { // eslint-disable-line no-unused-vars | |
* @return {Object} Settings. | ||
*/ | ||
component.addAMPAttributes = function addAMPAttributes( settings, name ) { | ||
// Add the "thirds" template position option. | ||
// Add the "thirds" template position option and animation settings. | ||
if ( -1 !== component.data.allowedBlocks.indexOf( name ) ) { | ||
if ( ! settings.attributes ) { | ||
settings.attributes = {}; | ||
} | ||
settings.attributes.ampStoryPosition = { | ||
type: 'string' | ||
}; | ||
// @todo We could map all the blocks to their tag and use attribute as source instead. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this would be good. Is it not done at the moment because AMP requires the value to have the time unit, e.g. Maybe the hpq library allows a custom Or, if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe it's rather because we don't know the element name to select? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed these settings to |
||
settings.attributes.ampAnimationType = { | ||
type: 'string' | ||
}; | ||
settings.attributes.ampAnimationDelay = { | ||
type: 'number', | ||
default: 0 | ||
}; | ||
settings.attributes.ampAnimationDuration = { | ||
type: 'number', | ||
default: 0 | ||
}; | ||
} | ||
return settings; | ||
}; | ||
|
@@ -183,27 +283,28 @@ var ampStoryEditorBlocks = ( function() { // eslint-disable-line no-unused-vars | |
} | ||
|
||
if ( 'thirds' !== parentBlock.attributes.template ) { | ||
// Return original. | ||
return [ | ||
el( BlockEdit, _.extend( { | ||
key: 'original' | ||
}, props ) ) | ||
]; | ||
inspectorControls = el( InspectorControls, { key: 'inspector' }, | ||
el( PanelBody, { title: __( 'AMP Story Settings', 'amp' ), key: 'amp-story' }, | ||
component.getAnimationControls( props ) | ||
) | ||
); | ||
} else { | ||
inspectorControls = el( InspectorControls, { key: 'inspector' }, | ||
el( PanelBody, { title: __( 'AMP Story Settings', 'amp' ), key: 'amp-story' }, | ||
el( SelectControl, { | ||
key: 'position', | ||
label: __( 'Placement', 'amp' ), | ||
value: attributes.ampStoryPosition, | ||
options: component.data.ampStoryPositionOptions, | ||
onChange: function( value ) { | ||
props.setAttributes( { ampStoryPosition: value } ); | ||
} | ||
} ), | ||
component.getAnimationControls( props ) | ||
) | ||
); | ||
} | ||
|
||
inspectorControls = el( InspectorControls, { key: 'inspector' }, | ||
el( PanelBody, { title: __( 'AMP Story Settings', 'amp' ) }, | ||
el( SelectControl, { | ||
label: __( 'Placement', 'amp' ), | ||
value: attributes.ampStoryPosition, | ||
options: component.data.ampStoryPositionOptions, | ||
onChange: function( value ) { | ||
props.setAttributes( { ampStoryPosition: value } ); | ||
} | ||
} ) | ||
) | ||
); | ||
|
||
return [ | ||
inspectorControls, | ||
el( BlockEdit, _.extend( { | ||
|
@@ -213,5 +314,44 @@ var ampStoryEditorBlocks = ( function() { // eslint-disable-line no-unused-vars | |
}; | ||
}; | ||
|
||
component.getAnimationControls = function getAnimationControls( props ) { | ||
var RangeControl = wp.components.RangeControl, | ||
el = wp.element.createElement, | ||
SelectControl = wp.components.SelectControl, | ||
attributes = props.attributes; | ||
|
||
return [ | ||
el( SelectControl, { | ||
key: 'animation-type', | ||
label: __( 'Animation type', 'amp' ), | ||
value: attributes.ampAnimationType, | ||
options: component.data.ampAnimationTypeOptions, | ||
onChange: function( value ) { | ||
props.setAttributes( { ampAnimationType: value } ); | ||
} | ||
} ), | ||
el( RangeControl, { | ||
key: 'animation-duration', | ||
label: __( 'Animation duration (ms)', 'amp' ), | ||
value: attributes.ampAnimationDuration, | ||
min: 0, | ||
max: 5000, | ||
onChange: function( value ) { | ||
props.setAttributes( { ampAnimationDuration: value } ); | ||
} | ||
} ), | ||
el( RangeControl, { | ||
key: 'animation-delay', | ||
label: __( 'Animation delay (ms)', 'amp' ), | ||
value: attributes.ampAnimationDelay, | ||
min: 0, | ||
max: 5000, | ||
onChange: function( value ) { | ||
props.setAttributes( { ampAnimationDelay: value } ); | ||
} | ||
} ) | ||
]; | ||
}; | ||
|
||
return component; | ||
}() ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
import { getAmpStoryAnimationControls } from '../utils'; | ||
|
||
const { __ } = wp.i18n; | ||
const { | ||
registerBlockType | ||
} = wp.blocks; | ||
const { | ||
InspectorControls, | ||
InnerBlocks | ||
} = wp.editor; | ||
const { | ||
Notice | ||
Notice, | ||
PanelBody | ||
} = wp.components; | ||
const { Component } = wp.element; | ||
|
||
|
@@ -50,6 +54,24 @@ export default registerBlockType( | |
category: 'layout', | ||
icon: 'grid-view', | ||
parent: [ 'amp/amp-story-page' ], | ||
|
||
attributes: { | ||
animationType: { | ||
type: 'string', | ||
source: 'attribute', | ||
selector: 'amp-story-grid-layer', | ||
attribute: 'animate-in' | ||
}, | ||
animationDuration: { | ||
type: 'number', | ||
default: 0 | ||
}, | ||
animationDelay: { | ||
type: 'number', | ||
default: 0 | ||
} | ||
}, | ||
|
||
inserter: false, | ||
|
||
/* | ||
|
@@ -99,9 +121,16 @@ export default registerBlockType( | |
<Notice status="error" isDismissible={ false }>{ __( 'Multiple CTA Layers are not allowed. Please remove all but one.', 'amp' ) }</Notice> | ||
); | ||
} | ||
return ( | ||
return [ | ||
<InspectorControls key='controls'> | ||
<PanelBody key='animation' title={ __( 'CTA Layer Animation' ) }> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
{ | ||
getAmpStoryAnimationControls( this.props.setAttributes, this.props.attributes ) | ||
} | ||
</PanelBody> | ||
</InspectorControls>, | ||
<InnerBlocks key='contents' allowedBlocks={ ALLOWED_BLOCKS } /> | ||
); | ||
]; | ||
} | ||
|
||
hasMoreThanOneCtaBlock() { | ||
|
@@ -120,8 +149,19 @@ export default registerBlockType( | |
}, | ||
|
||
save( { attributes } ) { | ||
let layerProps = {}; | ||
if ( attributes.animationType ) { | ||
layerProps[ 'animate-in' ] = attributes.animationType; | ||
|
||
if ( attributes.animationDelay ) { | ||
layerProps[ 'animate-in-delay' ] = attributes.animationDelay + 'ms'; | ||
} | ||
if ( attributes.animationDuration ) { | ||
layerProps[ 'animate-in-duration' ] = attributes.animationDuration + 'ms'; | ||
} | ||
} | ||
return ( | ||
<amp-story-cta-layer template={ attributes.template }> | ||
<amp-story-cta-layer { ...layerProps }> | ||
<InnerBlocks.Content /> | ||
</amp-story-cta-layer> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
import { getAmpStoryAnimationControls } from '../utils'; | ||
|
||
const { __ } = wp.i18n; | ||
const { | ||
registerBlockType | ||
|
@@ -7,7 +9,8 @@ const { | |
InnerBlocks | ||
} = wp.editor; | ||
const { | ||
SelectControl | ||
SelectControl, | ||
PanelBody | ||
} = wp.components; | ||
|
||
const ALLOWED_BLOCKS = [ | ||
|
@@ -59,6 +62,20 @@ export default registerBlockType( | |
selector: 'amp-story-grid-layer', | ||
attribute: 'template', | ||
default: 'vertical' | ||
}, | ||
animationType: { | ||
type: 'string', | ||
source: 'attribute', | ||
selector: 'amp-story-grid-layer', | ||
attribute: 'animate-in' | ||
}, | ||
animationDuration: { | ||
type: 'number', | ||
default: 0 | ||
}, | ||
animationDelay: { | ||
type: 'number', | ||
default: 0 | ||
} | ||
}, | ||
|
||
|
@@ -73,13 +90,13 @@ export default registerBlockType( | |
*/ | ||
|
||
edit( props ) { | ||
const { setAttributes } = props; | ||
const { setAttributes, attributes } = props; | ||
return [ | ||
<InspectorControls key='inspector'> | ||
<SelectControl | ||
key="template" | ||
label={ __( 'Template', 'amp' ) } | ||
value={ props.attributes.template } | ||
value={ attributes.template } | ||
options={ [ | ||
{ | ||
value: 'vertical', | ||
|
@@ -100,6 +117,11 @@ export default registerBlockType( | |
] } | ||
onChange={ value => ( setAttributes( { template: value } ) ) } | ||
/> | ||
<PanelBody key='animation' title={ __( 'Grid Layer Animation' ) }> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
{ | ||
getAmpStoryAnimationControls( setAttributes, attributes ) | ||
} | ||
</PanelBody> | ||
</InspectorControls>, | ||
<div key='contents' className={ 'amp-grid-template amp-grid-template-' + props.attributes.template }> | ||
<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } /> | ||
|
@@ -108,8 +130,22 @@ export default registerBlockType( | |
}, | ||
|
||
save( { attributes } ) { | ||
let layerProps = { | ||
template: attributes.template | ||
}; | ||
if ( attributes.animationType ) { | ||
layerProps[ 'animate-in' ] = attributes.animationType; | ||
|
||
if ( attributes.animationDelay ) { | ||
layerProps[ 'animate-in-delay' ] = attributes.animationDelay + 'ms'; | ||
} | ||
if ( attributes.animationDuration ) { | ||
layerProps[ 'animate-in-duration' ] = attributes.animationDuration + 'ms'; | ||
} | ||
} | ||
|
||
return ( | ||
<amp-story-grid-layer template={ attributes.template }> | ||
<amp-story-grid-layer { ...layerProps }> | ||
<InnerBlocks.Content /> | ||
</amp-story-grid-layer> | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list is duplicated with the array in
getAmpStoryAnimationControls
, is it not? I think there should be a commongetAnimationTypeOptions
function in theutils
module to eliminate this duplication. Even if the list is not exactly the same, the function could still return the full list and then you couldfilter
out the ones that aren't allowed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is duplicated, however, the
utils.js
gets compiled, not sure what would be the best way to use the module like this withinamp-story-editor-blocks.js
, thoughts?Created a separate helpers file for AMP Stories specifically within 4923569 since the
utils.js
always gets enqueued, however,getAmpStoryAnimationControls
is needed for AMP Stories post type only, thought that then maybe we could add an inline script for defining thegetAnimationTypeOptions
globally to avoid duplication but not sure if that would be a good way to go.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right. So this is actually dependent on #1298 which will convert
amp-story-editor-blocks.js
into a module. So once that happens then this problem would go away, right?