Sticky-Fullscreen-Headline

I hope you enjoy it...

    Inhaltsangabe
  1. The Code
    1. php
    2. js (backend)
    3. js (frontend)
    4. css

Yesterday I programmed a feature for my blog and would like to make it available to you as well. I write blog posts with a lot of text and many subheadings. So that does not get boring, I’ve been thinking about programming this feature. I also think that this is a nice subdivision of the sections. This is how it looks like:

The Code

I didn’t really do much on the code side. I’ve focused more on my css skills to accomplish that. The codes look like this:

php

<?php
defined( 'ABSPATH' ) || exit;

wp_enqueue_style(
	basename(__DIR__).'-style',
	get_template_directory_uri().'/blocks/'.basename(__DIR__).'/'.basename(__DIR__).'.css'
);

function register_full_image_title() {

	if ( ! function_exists( 'register_block_type' ) ) {
		// Gutenberg is not active.
		return;
	}

	wp_enqueue_script(
		basename(__DIR__),
		get_template_directory_uri().'/blocks/'.basename(__DIR__).'/block.js',
		array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' )
	);


	register_block_type( 'konzeptcode/'.basename(__DIR__), array(
	'editor_script' => basename(__DIR__),
	'style' => basename(__DIR__).'-style',
	'editor_style' => basename(__DIR__).'-style'
	) );


}
add_action( 'enqueue_block_editor_assets', 'register_full_image_title' );
add_action( 'enqueue_block_assets', 'register_full_image_title' );

js (backend)

const { registerBlockType } = wp.blocks;
const { PanelBody, ToggleControl, TextControl, Button } = wp.components;
const { Fragment } = wp.element;
const { InspectorControls, MediaUpload } = wp.editor;
let { withState } = wp.compose;







registerBlockType( 'konzeptcode/full-image-title', {
	title: 'Vollbild mit Titel',
	icon: 'align-center',
	category: 'layout',
	keywords: ['fazit', 'headline', 'full'],
    attributes: {
		text: {
			type: 'string',
			default: '',
		},
        imageData: {
            type: 'object',
			default: {}
        },
	},
    edit: ( props ) => {
        const {
            attributes: {
                text,
				imageData
            },
            setAttributes,
            className
        } = props;




        return <Fragment>
			<div
			class="full-image-title-preview"
			style={{ backgroundImage : (imageData.hasOwnProperty('fhd-url'))? "url("+imageData['fhd-url']+")" : "url("+imageData['full-url']+")" }}
			>
				<TextControl
					label="Headline"
					class="full-image-title-text"
					value={text}
					onChange={ ( text ) => setAttributes( { text } ) }
				/>
				<MediaUpload
					onSelect={ function(media){
						var image = {};
						['uhd','wqhd','fhd'].forEach(function (size){
							if (media.sizes.hasOwnProperty(size)) {
								image[size+'-url'] = media.sizes[size].url;
								image[size+'-width'] = media.sizes[size].width;
								image[size+'-height'] = media.sizes[size].height;
							}
						});

						if(media.sizes.full.width == 1920){
							image['fhd-url'] = media.sizes.full.url;
							image['fhd-width'] = media.sizes.full.width;
							image['fhd-height'] = media.sizes.full.height;

						}

						if(Object.keys(image).length === 0){
							image['full-url'] = media.sizes.full.url;
							image['full-width'] = media.sizes.full.width;
							image['full-height'] = media.sizes.full.height;

						}

						image['thumb-id'] = media.id;


						if(Object.keys(image).length >= 4){
							setAttributes( {
								imageData: image
							} );

						}

					} }
					value={ (imageData.hasOwnProperty('thumb-id')? imageData.id : 0 ) }
					render={ ( { open } ) => (
						<Button isDefault onClick={ open } >
						Bild setzen
						</Button>
					) }
				/>
			</div>
        </Fragment>;
    },
    save: ( props ) => {

		const {
            attributes: {
                text,
				imageData
            },
            setAttributes,
            className
        } = props;

        return <Fragment>
        <div class="full-image-title-image-wrapper" {...imageData}>
			<img class="full-image-title-image" src={imageData['thumbnail-url']} />
		</div>{ (text)? <h2 class="full-image-title-title">{text}</h2> : ''}
        </Fragment>;
    },
} );

js (frontend)

if($('.full-image-title-outer-wrapper').length){
	var w = window.innerWidth;
	var h = window.innerHeight;

	loadTitleImage();
	$( window ).resize(function() { loadTitleImage(); });

    $(window).scroll(function(){

        $('.full-image-title-image-wrapper').each(function(index, el) {

            if(el.getBoundingClientRect().y <= 0){
                $(el).addClass('rollout')
            }else {
				$(el).removeClass('rollout')
            }

        });

    });

}

function loadTitleImage(){
	console.log('loadTitleImage');
	$('.full-image-title-image-wrapper').each(function(index, el) {

		let url = false;
		$(['fhd','wqhd','uhd']).each(function(index, size) {

			if($(el)[0].hasAttribute(size+'-url')) url = $(el).attr(size+'-url');

			if(
				$(el)[0].hasAttribute(size+'-url') &&
				parseInt($(el).attr(size+'-width')) > w &&
				parseInt($(el).attr(size+'-height')) > h
			){
				url = $(el).attr(size+'-url');
				return false;
			}
		});

		if(!url) url = $(el).attr('full-url');

		$(el).find('.full-image-title-image').attr('src', url );

	});
}

css

@import "../scss/vars.scss";

#wrapper{

    .full-image-title-inner-wrapper,
    .full-image-title-outer-wrapper{
        display: block;
        height: 150vh;
    }

	.full-image-title-outer-wrapper,
	.full-image-title-inner-wrapper,
	.full-image-title-image-wrapper{
		position: relative;
		display: block;
		width: 100%;
		padding: 0;
	}
	.full-image-title-outer-wrapper{

		.full-image-title-inner-wrapper{
			max-width: none;

			.full-image-title-image-wrapper{
				position: sticky;
				top: 0;
                overflow: hidden;
                width: 100%;
                max-height: 100vh;
				z-index: -1;



				.full-image-title-image{
					position: relative;
					display: block;
					width: auto;
					height: auto;
					min-width: 100vw;
					min-height: 100vh;
					max-width: none;
					max-height: none;
					top: 50vh;
					left: 50vw;
				    transform: translate(-50%, -50%);
				}

				&:after{
					content: ' ';
					background-color: $white;
					position: absolute;
					top: 0;
					left: 0;
					width: 100%;
					height: 100%;
					opacity: 0;
					transition: all .3s ease-in-out;
				}
				&.rollout{
					&:after{
						opacity: .8;
					}

					& + .full-image-title-title{
						transform: translateY(-50%);
					}
				}
			}

            .full-image-title-title{
				transform: translateY(0);
                z-index: 10;
				font-size: 8vw;
				font-weight: 700;
				text-align: center;
				width: 100%;
				max-width: 75vw;
				margin: 0 auto;
				transition: all .3s ease-in-out;

            }
		}
	}
}

.full-image-title-preview{
	width: 100%;
	height: 320px;
	background-position: center;
	background-size: cover;
}

Topics

design Gutenberg performance Program technology

Beitrag teilen

WhatsApp it

Folgen Sie uns