diff --git a/blocks/cloud-image/cloud-image.css b/blocks/cloud-image/cloud-image.css new file mode 100644 index 0000000..7838fbd --- /dev/null +++ b/blocks/cloud-image/cloud-image.css @@ -0,0 +1,71 @@ +.cloud-image-wrapper { + height: 100vh; + position: relative; + + .cloud-image { + height: 100%; + + & h1:first-of-type { + font-size: clamp(2rem, 7vw + .25rem, 5.625rem); + } + + .icon.icon-logo-big { + height: 100px; + width: 140px; + } + + .cloud-image-header { + position: absolute; + width: 100%; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + opacity: 1; + z-index: 1; + } + + .cloud-image-element { + position: absolute; + top: 0; + left: 0; + max-width: 60vw; + max-height: 40vh; + animation: cloud 36s infinite; + animation-delay: 0s; + opacity: 0; + z-index: 0; + } + } +} + +/* Keyframe cloud animation */ +@keyframes cloud { + 0% { + transform: scale(0.1); + filter: blur(10px); + opacity: 0; + } + + 6% { + opacity: 1; + } + + 13% { + filter: blur(0); + } + + 25% { + filter: blur(0); + opacity: 1; + } + + 33% { + transform: scale(1); + filter: blur(15px); + opacity: 0; + } + + 100% { + opacity: 0; + } +} \ No newline at end of file diff --git a/blocks/cloud-image/cloud-image.js b/blocks/cloud-image/cloud-image.js new file mode 100644 index 0000000..47c6f29 --- /dev/null +++ b/blocks/cloud-image/cloud-image.js @@ -0,0 +1,71 @@ +function addClassToDivsWithPicture() { + const cloudImageElements = document.querySelectorAll('.cloud-image'); + cloudImageElements.forEach((cloudImage) => { + const childDivs = cloudImage.querySelectorAll(':scope > div'); + if (childDivs.length >= 2) { + const wrapper = document.createElement('div'); + wrapper.classList.add('cloud-image-header', 'text-center'); + childDivs[0].before(wrapper); + wrapper.appendChild(childDivs[0]); + wrapper.appendChild(childDivs[1]); + } + + childDivs.forEach((div) => { + if (div.querySelector('picture')) { + div.classList.add('cloud-image-element'); + } + }); + }); +} + +function setDataAttributes() { + // Arrays for top and left values calculation (mocked from the original site that seems random) + const topValues = [ + 20, 0, 50, 70, 100, 60, 90, 20, 0, 40, + 90, 80, 60, 60, 90, 10, 40, 50, 80, + ]; + const leftValues = [ + 50, 90, 60, 80, 30, 80, 0, 20, 60, 90, + 10, 70, 100, 30, 90, 0, 50, 90, 90, 30, + ]; + const delayValues = [ + 4, 5, 2, 34, 3, 7, 8, + 9, 15, 15, 12, 22, 20, 26, 33, 31, 25, 27, + ]; + const cloudImagePictureElements = document.querySelectorAll('.cloud-image-element'); + + cloudImagePictureElements.forEach((div, index) => { + const leftIndex = index % leftValues.length; + const topIndex = index % topValues.length; + const delayIndex = index % delayValues.length; + div.setAttribute('data-left', leftValues[leftIndex]); + div.setAttribute('data-top', topValues[topIndex]); + div.setAttribute('data-delay', delayValues[delayIndex]); + }); +} + +function positionImageInTheCloud() { + const cloudImgContainer = document.querySelector('.cloud-image-wrapper'); + const cloudImagePictureElements = document.querySelectorAll('.cloud-image-element'); + + const { + width: containerWidth, + height: containerHeight, + } = cloudImgContainer.getBoundingClientRect(); + + cloudImagePictureElements.forEach((element) => { + const img = element.querySelector('img'); + if (!img) return; + const { width: imgWidth, height: imgHeight } = img; + const elementStyleTop = `${element.dataset.left * (1 - imgWidth / containerWidth)}`; + const elementStyleLeft = `${element.dataset.top * (1 - imgHeight / containerHeight) * 0.96}`; + element.style.left = (elementStyleLeft > 60) ? `${60}%` : `${elementStyleLeft}%`; + element.style.top = (elementStyleTop > 57) ? `${57}%` : `${elementStyleTop}%`; + element.style.animationDelay = `${element.dataset.delay - 36}s`; + }); +} + +export default positionImageInTheCloud; + +addClassToDivsWithPicture(); +setDataAttributes(); diff --git a/scripts/scripts.js b/scripts/scripts.js index a661372..82cdfb6 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -12,6 +12,7 @@ import { loadSections, loadCSS, } from './aem.js'; +import positionImageInTheCloud from '../blocks/cloud-image/cloud-image.js'; /** * Builds hero block and prepends to main in a new section. @@ -80,7 +81,6 @@ async function loadEager(doc) { document.body.classList.add('appear'); await loadSection(main.querySelector('.section'), waitForFirstImage); } - try { /* if desktop (proxy for fast connection) or fonts already loaded, load fonts.css */ if (window.innerWidth >= 900 || sessionStorage.getItem('fonts-loaded')) { @@ -89,6 +89,11 @@ async function loadEager(doc) { } catch (e) { // do nothing } + /** + * Executing function that manipulate position of the + * cloud image block upon loading the page. + */ + positionImageInTheCloud(); } /**