| 1 |
( function () { |
| 2 |
var el = wp.element.createElement; |
| 3 |
var Fragment = wp.element.Fragment; |
| 4 |
var __ = wp.i18n.__; |
| 5 |
var registerBlockType = wp.blocks.registerBlockType; |
| 6 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 7 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 8 |
var InnerBlocks = wp.blockEditor.InnerBlocks; |
| 9 |
var PanelBody = wp.components.PanelBody; |
| 10 |
var ToggleControl = wp.components.ToggleControl; |
| 11 |
var RangeControl = wp.components.RangeControl; |
| 12 |
var SelectControl = wp.components.SelectControl; |
| 13 |
|
| 14 |
var ANIMATIONS = [ |
| 15 |
{ label: 'Fade Up', value: 'fade-up' }, |
| 16 |
{ label: 'Fade Down', value: 'fade-down' }, |
| 17 |
{ label: 'Fade Left', value: 'fade-left' }, |
| 18 |
{ label: 'Fade Right', value: 'fade-right' }, |
| 19 |
{ label: 'Fade In', value: 'fade-in' }, |
| 20 |
{ label: 'Zoom In', value: 'zoom-in' }, |
| 21 |
{ label: 'Zoom Out', value: 'zoom-out' }, |
| 22 |
{ label: 'Slide Up', value: 'slide-up' }, |
| 23 |
{ label: 'Slide Down', value: 'slide-down' }, |
| 24 |
{ label: 'Slide Left', value: 'slide-left' }, |
| 25 |
{ label: 'Slide Right', value: 'slide-right' }, |
| 26 |
{ label: 'Flip Left', value: 'flip-left' }, |
| 27 |
{ label: 'Flip Right', value: 'flip-right' }, |
| 28 |
{ label: 'Rotate In', value: 'rotate-in' }, |
| 29 |
{ label: 'Skew Up', value: 'skew-up' }, |
| 30 |
{ label: 'Bounce In', value: 'bounce-in' }, |
| 31 |
]; |
| 32 |
|
| 33 |
var EASINGS = [ |
| 34 |
{ label: 'Ease', value: 'ease' }, |
| 35 |
{ label: 'Ease In', value: 'ease-in' }, |
| 36 |
{ label: 'Ease Out', value: 'ease-out' }, |
| 37 |
{ label: 'Ease In Out', value: 'ease-in-out' }, |
| 38 |
{ label: 'Linear', value: 'linear' }, |
| 39 |
{ label: 'Spring (cubic)', value: 'cubic-bezier(0.34,1.56,0.64,1)' }, |
| 40 |
{ label: 'Back Out (cubic)', value: 'cubic-bezier(0.34,1.3,0.64,1)' }, |
| 41 |
]; |
| 42 |
|
| 43 |
function animLabel(val) { |
| 44 |
var found = ANIMATIONS.find(function (a) { return a.value === val; }); |
| 45 |
return found ? found.label : val; |
| 46 |
} |
| 47 |
|
| 48 |
/* ── edit ───────────────────────────────────────────────────────────────── */ |
| 49 |
function Edit(props) { |
| 50 |
var attributes = props.attributes; |
| 51 |
var setAttributes = props.setAttributes; |
| 52 |
var a = attributes; |
| 53 |
|
| 54 |
var blockProps = useBlockProps({ |
| 55 |
style: { |
| 56 |
paddingTop: a.paddingTop ? a.paddingTop + 'px' : undefined, |
| 57 |
paddingBottom: a.paddingBottom ? a.paddingBottom + 'px' : undefined, |
| 58 |
position: 'relative', |
| 59 |
} |
| 60 |
}); |
| 61 |
|
| 62 |
return el(Fragment, null, |
| 63 |
el(InspectorControls, null, |
| 64 |
|
| 65 |
/* Animation panel */ |
| 66 |
el(PanelBody, { title: __('Animation', 'blockenberg'), initialOpen: true }, |
| 67 |
el(SelectControl, { |
| 68 |
label: __('Animation Type', 'blockenberg'), |
| 69 |
value: a.animation, |
| 70 |
options: ANIMATIONS, |
| 71 |
onChange: function (v) { setAttributes({ animation: v }); } |
| 72 |
}), |
| 73 |
el(SelectControl, { |
| 74 |
label: __('Easing', 'blockenberg'), |
| 75 |
value: a.easing, |
| 76 |
options: EASINGS, |
| 77 |
onChange: function (v) { setAttributes({ easing: v }); } |
| 78 |
}), |
| 79 |
el(RangeControl, { |
| 80 |
label: __('Duration (ms)', 'blockenberg'), |
| 81 |
value: a.duration, |
| 82 |
min: 100, |
| 83 |
max: 2000, |
| 84 |
step: 50, |
| 85 |
onChange: function (v) { setAttributes({ duration: v }); } |
| 86 |
}), |
| 87 |
el(RangeControl, { |
| 88 |
label: __('Delay (ms)', 'blockenberg'), |
| 89 |
value: a.delay, |
| 90 |
min: 0, |
| 91 |
max: 2000, |
| 92 |
step: 50, |
| 93 |
onChange: function (v) { setAttributes({ delay: v }); } |
| 94 |
}), |
| 95 |
el(RangeControl, { |
| 96 |
label: __('Distance (px)', 'blockenberg'), |
| 97 |
value: a.distance, |
| 98 |
min: 0, |
| 99 |
max: 200, |
| 100 |
onChange: function (v) { setAttributes({ distance: v }); }, |
| 101 |
help: __('How far the element travels during the animation.', 'blockenberg') |
| 102 |
}), |
| 103 |
(a.animation === 'zoom-in' || a.animation === 'zoom-out') && el(RangeControl, { |
| 104 |
label: __('Scale Start (%)', 'blockenberg'), |
| 105 |
value: a.scale, |
| 106 |
min: 50, |
| 107 |
max: 110, |
| 108 |
onChange: function (v) { setAttributes({ scale: v }); } |
| 109 |
}), |
| 110 |
(a.animation === 'rotate-in' || a.animation === 'skew-up') && el(RangeControl, { |
| 111 |
label: __('Rotate (deg)', 'blockenberg'), |
| 112 |
value: a.rotate, |
| 113 |
min: -90, |
| 114 |
max: 90, |
| 115 |
onChange: function (v) { setAttributes({ rotate: v }); } |
| 116 |
}), |
| 117 |
el(RangeControl, { |
| 118 |
label: __('Start Opacity', 'blockenberg'), |
| 119 |
value: a.opacity, |
| 120 |
min: 0, |
| 121 |
max: 99, |
| 122 |
onChange: function (v) { setAttributes({ opacity: v }); } |
| 123 |
}), |
| 124 |
el(RangeControl, { |
| 125 |
label: __('Trigger Threshold (%)', 'blockenberg'), |
| 126 |
value: a.threshold, |
| 127 |
min: 0, |
| 128 |
max: 80, |
| 129 |
onChange: function (v) { setAttributes({ threshold: v }); }, |
| 130 |
help: __('% of element visible before trigger fires.', 'blockenberg') |
| 131 |
}), |
| 132 |
el(ToggleControl, { label: __('Animate Once', 'blockenberg'), checked: a.once, onChange: function (v) { setAttributes({ once: v }); }, __nextHasNoMarginBottom: true }), |
| 133 |
el(ToggleControl, { |
| 134 |
label: __('Stagger Children', 'blockenberg'), |
| 135 |
checked: a.stagger, |
| 136 |
onChange: function (v) { setAttributes({ stagger: v }); }, |
| 137 |
__nextHasNoMarginBottom: true, |
| 138 |
help: __('Apply incremental delay to each direct child element.', 'blockenberg') |
| 139 |
}), |
| 140 |
a.stagger && el(RangeControl, { |
| 141 |
label: __('Stagger Delay (ms)', 'blockenberg'), |
| 142 |
value: a.staggerDelay, |
| 143 |
min: 0, |
| 144 |
max: 500, |
| 145 |
step: 25, |
| 146 |
onChange: function (v) { setAttributes({ staggerDelay: v }); } |
| 147 |
}) |
| 148 |
), |
| 149 |
|
| 150 |
/* Spacing */ |
| 151 |
el(PanelBody, { title: __('Spacing', 'blockenberg'), initialOpen: false }, |
| 152 |
el(RangeControl, { label: __('Padding Top (px)', 'blockenberg'), value: a.paddingTop, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingTop: v }); } }), |
| 153 |
el(RangeControl, { label: __('Padding Bottom (px)', 'blockenberg'), value: a.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingBottom: v }); } }) |
| 154 |
) |
| 155 |
), |
| 156 |
|
| 157 |
/* ── editor canvas ── */ |
| 158 |
el('div', blockProps, |
| 159 |
/* badge */ |
| 160 |
el('div', { |
| 161 |
style: { |
| 162 |
position: 'absolute', top: '0', left: '50%', transform: 'translateX(-50%)', |
| 163 |
background: '#6c3fb5', color: '#fff', fontSize: '10px', fontWeight: 600, |
| 164 |
padding: '2px 10px', borderRadius: '0 0 6px 6px', zIndex: 10, |
| 165 |
pointerEvents: 'none', letterSpacing: '.3px', whiteSpace: 'nowrap', |
| 166 |
} |
| 167 |
}, '▶ Scroll Reveal: ' + animLabel(a.animation) + ' · ' + a.duration + 'ms'), |
| 168 |
el(InnerBlocks, { |
| 169 |
renderAppender: InnerBlocks.ButtonBlockAppender, |
| 170 |
}) |
| 171 |
) |
| 172 |
); |
| 173 |
} |
| 174 |
|
| 175 |
/* ── save ───────────────────────────────────────────────────────────────── */ |
| 176 |
function Save(props) { |
| 177 |
var a = props.attributes; |
| 178 |
var blockProps = wp.blockEditor.useBlockProps.save({ |
| 179 |
className: 'bksr-wrap', |
| 180 |
'data-animation': a.animation, |
| 181 |
'data-duration': a.duration, |
| 182 |
'data-delay': a.delay, |
| 183 |
'data-easing': a.easing, |
| 184 |
'data-distance': a.distance, |
| 185 |
'data-scale': a.scale, |
| 186 |
'data-rotate': a.rotate, |
| 187 |
'data-opacity': a.opacity, |
| 188 |
'data-threshold': a.threshold, |
| 189 |
'data-once': a.once ? '1' : '0', |
| 190 |
'data-stagger': a.stagger ? '1' : '0', |
| 191 |
'data-stagger-delay': a.staggerDelay, |
| 192 |
style: { |
| 193 |
paddingTop: a.paddingTop ? a.paddingTop + 'px' : undefined, |
| 194 |
paddingBottom: a.paddingBottom ? a.paddingBottom + 'px' : undefined, |
| 195 |
} |
| 196 |
}); |
| 197 |
|
| 198 |
return el('div', blockProps, |
| 199 |
el(InnerBlocks.Content, null) |
| 200 |
); |
| 201 |
} |
| 202 |
|
| 203 |
registerBlockType('blockenberg/scroll-reveal', { |
| 204 |
edit: Edit, |
| 205 |
save: Save, |
| 206 |
}); |
| 207 |
}() ); |
| 208 |
|