diff --git a/blueprint.json b/blueprint.json index c08d5f7..9b62d18 100644 --- a/blueprint.json +++ b/blueprint.json @@ -1,7 +1,7 @@ { "$schema": "https://playground.wordpress.net/blueprint-schema.json", "meta": { - "name": "My Scroll Block", + "title": "My Scroll Block", "description": "A WordPress plugin that adds scroll-driven animation capabilities to core blocks using CSS scroll timelines.", "author": "Fellyph Cintra" }, @@ -16,7 +16,7 @@ }, { "step": "runPHP", - "code": " 'Simple post from PHP', 'post_content' => '

A trip to Portugal is an immersion into a land where history, culture, and nature blend seamlessly. From the sun-drenched beaches of the Algarve to the rugged volcanic landscapes of the Azores, Portugal offers a stunning diversity of scenery.

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

\"\"/

Portugal's rich past is visible everywhere, from medieval castles to the monuments of the Age of Discoveries, while its modern spirit thrives in vibrant cities and a welcoming, laid-back culture.

Cities of Portugal

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

\"\"/
\"\"
\"\"/
\"\"/
\"\"

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

', 'post_author' => 1, 'post_status' => 'publish')); ?>" + "code": " 'Simple post from PHP', 'post_content' => '

A trip to Portugal is an immersion into a land where history, culture, and nature blend seamlessly. From the sun-drenched beaches of the Algarve to the rugged volcanic landscapes of the Azores, Portugal offers a stunning diversity of scenery.

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

\"\"/

Portugal's rich past is visible everywhere, from medieval castles to the monuments of the Age of Discoveries, while its modern spirit thrives in vibrant cities and a welcoming, laid-back culture.

Cities of Portugal

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

\"\"/
\"\"
\"\"/
\"\"/
\"\"

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

', 'post_author' => 1, 'post_status' => 'publish')); ?>" } ] } diff --git a/generate_content.py b/generate_content.py new file mode 100644 index 0000000..88679db --- /dev/null +++ b/generate_content.py @@ -0,0 +1,78 @@ + +content = r''' +

A trip to Portugal is an immersion into a land where history, culture, and nature blend seamlessly. From the sun-drenched beaches of the Algarve to the rugged volcanic landscapes of the Azores, Portugal offers a stunning diversity of scenery.

+ + + +

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

+ + + +
+ + + +

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

+ + + +

Cities of Portugal

+ + + +

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

+ + + +
+
+
+
+ + + +
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

+ + + +

Wander through Lisbon's historic, tiled streets, where traditional fado music echoes from old neighborhoods. Or explore Porto, the capital of the Douro Valley, the world's oldest wine region.

+''' + +# Step 1: Escape ' to \' for PHP +# We want the output to contain literal \' for every ' +php_content = content.replace("'", "\\'") + +# Step 2: Flatten to single line +php_content = php_content.replace("\n", "") + +# Step 3: Escape " to \" for JSON +json_content = php_content.replace('"', '\\"') + +print(json_content) diff --git a/src/index.js b/src/index.js index b2825d3..26bca85 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import { addFilter } from '@wordpress/hooks'; import { __ } from '@wordpress/i18n'; import { createHigherOrderComponent } from '@wordpress/compose'; import { InspectorControls } from '@wordpress/block-editor'; -import { PanelBody, SelectControl, RangeControl } from '@wordpress/components'; +import { PanelBody, SelectControl, RangeControl, ToggleControl } from '@wordpress/components'; import { dispatch } from '@wordpress/data'; import './style.css'; @@ -32,10 +32,14 @@ const ANIMATION_OPTIONS = [ { label: __('Scale Up', 'my-scroll-block'), value: 'scale-up' }, { label: __('Rotate In', 'my-scroll-block'), value: 'rotate-in' }, { label: __('Blur In', 'my-scroll-block'), value: 'blur-in' }, + { label: __('3D Rotate In', 'my-scroll-block'), value: 'rotate-3d-in' }, + { label: __('Circle Reveal', 'my-scroll-block'), value: 'circle-reveal' }, + { label: __('Curtain Reveal', 'my-scroll-block'), value: 'curtain-reveal' }, { label: __('🔄 Fade In & Out', 'my-scroll-block'), value: 'fade-in-out' }, { label: __('🔄 Slide Up In & Out', 'my-scroll-block'), value: 'slide-up-in-out' }, { label: __('🔄 Scale In & Out', 'my-scroll-block'), value: 'scale-in-out' }, { label: __('🔄 Rotate In & Out', 'my-scroll-block'), value: 'rotate-in-out' }, + { label: __('🔄 3D Rotate In & Out', 'my-scroll-block'), value: 'rotate-3d-in-out' }, ]; const RANGE_OPTIONS = [ @@ -79,6 +83,14 @@ addFilter('blocks.registerBlockType', 'my-scroll-block/extend-attributes', (sett type: 'number', default: 100, }, + parallaxEnabled: { + type: 'boolean', + default: false, + }, + parallaxStrength: { + type: 'number', + default: 50, + }, }, }; }); @@ -97,6 +109,8 @@ const withAnimationControls = createHigherOrderComponent((BlockEdit) => { animationEntryEnd = 100, animationExitStart = 0, animationExitEnd = 100, + parallaxEnabled = false, + parallaxStrength = 50, }, setAttributes, } = props; @@ -219,6 +233,26 @@ const withAnimationControls = createHigherOrderComponent((BlockEdit) => { )} )} + + + setAttributes({ parallaxEnabled: value })} + help={__('Adds a parallax scrolling effect to the block background or content.', 'my-scroll-block')} + /> + + {parallaxEnabled && ( + setAttributes({ parallaxStrength: value })} + min={10} + max={200} + step={10} + help={__('Higher values create more movement.', 'my-scroll-block')} + /> + )} @@ -244,9 +278,11 @@ addFilter( animationEntryEnd = 100, animationExitStart = 0, animationExitEnd = 100, + parallaxEnabled = false, + parallaxStrength = 50, } = attributes; - if (animationType === 'none') { + if (animationType === 'none' && !parallaxEnabled) { return extraProps; } @@ -272,6 +308,15 @@ addFilter( } } + if (parallaxEnabled) { + extraProps['data-parallax'] = '1'; + extraProps['data-parallax-strength'] = parallaxStrength; + extraProps.style = { + ...extraProps.style, + '--parallax-strength': `${parallaxStrength}px`, + }; + } + return extraProps; } ); @@ -292,6 +337,8 @@ addFilter( animationEntryEnd = 100, animationExitStart = 0, animationExitEnd = 100, + parallaxEnabled = false, + parallaxStrength = 50, } = props.attributes; const extraProps = {}; @@ -316,6 +363,16 @@ addFilter( } } } + + + if (parallaxEnabled) { + extraProps['data-parallax'] = '1'; + extraProps['data-parallax-strength'] = parallaxStrength; + extraProps.style = { + ...props.style, + '--parallax-strength': `${parallaxStrength}px`, + }; + } return ; }; }, 'withListExtraProps') @@ -345,9 +402,9 @@ addFilter( if (!SUPPORTED_BLOCKS.includes(props.name)) { return ; } - const { animationType = 'none' } = props.attributes; + const { animationType = 'none', parallaxEnabled = false } = props.attributes; - if (animationType === 'none') { + if (animationType === 'none' && !parallaxEnabled) { return ; } diff --git a/src/style.css b/src/style.css index 57ccf70..e20a2db 100644 --- a/src/style.css +++ b/src/style.css @@ -18,6 +18,12 @@ initial-value: 5vh; } +@property --parallax-strength { + syntax: ""; + inherits: true; + initial-value: 50px; +} + @supports (animation-timeline: view()) { /* Entry-only animations */ @@ -28,7 +34,10 @@ .scroll-anim-slide-in-down, .scroll-anim-scale-up, .scroll-anim-rotate-in, - .scroll-anim-blur-in { + .scroll-anim-blur-in, + .scroll-anim-rotate-3d-in, + .scroll-anim-circle-reveal, + .scroll-anim-curtain-reveal { animation-timeline: view(); animation-range: entry 20% cover 100%; } @@ -41,7 +50,10 @@ [data-anim-range="quick"].scroll-anim-slide-in-down, [data-anim-range="quick"].scroll-anim-scale-up, [data-anim-range="quick"].scroll-anim-rotate-in, - [data-anim-range="quick"].scroll-anim-blur-in { + [data-anim-range="quick"].scroll-anim-blur-in, + [data-anim-range="quick"].scroll-anim-rotate-3d-in, + [data-anim-range="quick"].scroll-anim-circle-reveal, + [data-anim-range="quick"].scroll-anim-curtain-reveal { animation-range: entry 0% cover 50%; } @@ -53,7 +65,10 @@ [data-anim-range="slow"].scroll-anim-slide-in-down, [data-anim-range="slow"].scroll-anim-scale-up, [data-anim-range="slow"].scroll-anim-rotate-in, - [data-anim-range="slow"].scroll-anim-blur-in { + [data-anim-range="slow"].scroll-anim-blur-in, + [data-anim-range="slow"].scroll-anim-rotate-3d-in, + [data-anim-range="slow"].scroll-anim-circle-reveal, + [data-anim-range="slow"].scroll-anim-curtain-reveal { animation-range: entry 10% cover 100%; } @@ -65,7 +80,10 @@ [data-anim-range="late"].scroll-anim-slide-in-down, [data-anim-range="late"].scroll-anim-scale-up, [data-anim-range="late"].scroll-anim-rotate-in, - [data-anim-range="late"].scroll-anim-blur-in { + [data-anim-range="late"].scroll-anim-blur-in, + [data-anim-range="late"].scroll-anim-rotate-3d-in, + [data-anim-range="late"].scroll-anim-circle-reveal, + [data-anim-range="late"].scroll-anim-curtain-reveal { animation-range: entry 50% cover 100%; } @@ -73,9 +91,17 @@ .scroll-anim-fade-in-out, .scroll-anim-slide-up-in-out, .scroll-anim-scale-in-out, - .scroll-anim-rotate-in-out { + .scroll-anim-rotate-in-out, + .scroll-anim-rotate-3d-in-out { animation-timeline: view(); } + + /* Parallax Effect */ + [data-parallax="1"] { + animation-name: scrollParallax; + animation-timeline: scroll(root block); + animation-range: 0% 100%; + } } /* Apply animations - Entry Only */ @@ -127,6 +153,22 @@ filter: blur(10px); } +.scroll-anim-rotate-3d-in { + animation-name: scrollRotate3DIn; + opacity: 0; + transform: perspective(1000px) rotateX(45deg); +} + +.scroll-anim-circle-reveal { + animation-name: scrollCircleReveal; + clip-path: circle(0% at 50% 50%); +} + +.scroll-anim-curtain-reveal { + animation-name: scrollCurtainReveal; + clip-path: inset(0 50% 0 50%); +} + /* Apply animations - In and Out */ .scroll-anim-fade-in-out { animation-name: scrollFadeInOut; @@ -144,6 +186,10 @@ animation-name: scrollRotateInOut; } +.scroll-anim-rotate-3d-in-out { + animation-name: scrollRotate3DInOut; +} + /* CSS animations using keyframes - Entry Only */ @keyframes scrollFadeIn { @@ -249,6 +295,35 @@ } } +@keyframes scrollRotate3DIn { + from { + opacity: 0; + transform: perspective(1000px) rotateX(45deg); + } + to { + opacity: 1; + transform: perspective(1000px) rotateX(0); + } +} + +@keyframes scrollCircleReveal { + from { + clip-path: circle(0% at 50% 50%); + } + to { + clip-path: circle(100% at 50% 50%); + } +} + +@keyframes scrollCurtainReveal { + from { + clip-path: inset(0 50% 0 50%); + } + to { + clip-path: inset(0 0 0 0); + } +} + /* CSS animations using keyframes - In and Out */ @keyframes scrollFadeInOut { @@ -342,6 +417,34 @@ } } +@keyframes scrollRotate3DInOut { + entry 0% { + opacity: 0; + transform: perspective(1000px) rotateX(-45deg); + } + entry 100% { + opacity: 1; + transform: perspective(1000px) rotateX(0); + } + exit 0% { + opacity: 1; + transform: perspective(1000px) rotateX(0); + } + exit 100% { + opacity: 0; + transform: perspective(1000px) rotateX(45deg); + } +} + +@keyframes scrollParallax { + from { + transform: translateY(0); + } + to { + transform: translateY(var(--parallax-strength)); + } +} + /* Respect reduced motion */ @media (prefers-reduced-motion: reduce) {