PageSourceSearch

https://www.yourcloudlibrary.com/content/dam/yourcloudlibrary/en/js/ycl-hero-clouds-1.0.js

js yourcloudlibrary.com collected 2026-10-01 10:28:14 UTC 4,881 bytes, 106 lines download raw bytes

1document.addEventListener("DOMContentLoaded", () => {
2	const widthFactor = 1.5149520833;
3	const ellipses = [
4		{ height: 340, position: { top: -3, left: "0%" }, rotate: -8 },
5		{ height: 140, position: { top: -30, left: "70%" }, rotate: 4 },
6		{ height: 240, position: { left: -2, top: "-15%" }, rotate: 10 },
7		{ height: 470, position: { bottom: -5, right: "5%" }, rotate: -4 },
8		{ height: 300, position: { bottom: "-30%", right: -5 }, rotate: -4 },
9		{ height: 140, position: { bottom: -130, right: "-25%" }, rotate: 2 }, // bottom offscreen
10		{ height: 280, position: { bottom: -170, left: "-20%" }, rotate: -3 }, // bottom offscreen
11		{ height: 440, position: { left: -360, bottom: "20%" }, rotate: 4 }, // left offscreen
12		{ height: 460, position: { right: -420, top: "20%" }, rotate: -4 }, // right offscreen
13	];
14	const title = document.querySelector(".hero_area .title");
15
16	let container = document.createElement("div");
17	container.classList.add("ellipse-container");
18	const targetElement = document.querySelector(".hero_area .cq-colctrl-1-fc-c0");
19	targetElement.appendChild(container);
20
21	function createEllipse(ellipse) {
22		const width = ellipse.height * widthFactor;
23		const wrapper = document.createElement("div");
24		wrapper.classList.add("ellipse-wrapper");
25        wrapper.dataset.rotate = ellipse.rotate;
26		wrapper.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 145.44 96" width="${width}" height="${ellipse.height}" class="ellipse" style="transform:rotate(${ellipse.rotate}deg)" data-rotate="${ellipse.rotate}">
27        <path d="M134.38 20.78a38.49 38.49 0 0 0-27.03-11.49H106c-3.49.06-6.95.62-10.3 1.64a15.03 15.03 0 0 0-5.34-5.88 32.05 32.05 0 0 0-41.18 5.66 38.93 38.93 0 0 0-12.91-1.35 38.6 38.6 0 0 0-25.24 11.63 38.54 38.54 0 0 0-11 25.49 38.4 38.4 0 0 0 10.79 28.36 38.4 38.4 0 0 0 27.9 11.88c.48 0 .95 0 1.42-.03a37.4 37.4 0 0 0 9.6-1.62 15.08 15.08 0 0 0 5.34 5.87 31.98 31.98 0 0 0 41.19-5.68c3.41.9
276 6.92 1.45 10.44 1.45a38.76 38.76 0 0 0 38.72-38.72 38.53 38.53 0 0 0-11.06-27.22Z" style="fill:#F9FAFB"/>
28    </svg>`;
29		return wrapper;
30	}
31
32	function positionEllipse(ellipseWrapper, ellipse, targetRect) {
33		const { height, position } = ellipse;
34		const width = height * widthFactor;
35		const style = ellipseWrapper.style;
36
37		if (position.top !== undefined) {
38			style.top = typeof position.top === "string" ? position.top : `${position.top - height}px`;
39		}
40		if (position.bottom !== undefined) {
41			style.bottom = typeof position.bottom === "string" ? position.bottom : `${position.bottom - height}px`;
42		}
43		if (position.left !== undefined) {
44			style.left = typeof position.left === "string" ? position.left : `${position.left - width}px`;
45		}
46		if (position.right !== undefined) {
47			style.right = typeof position.right === "string" ? position.right : `${position.right - width}px`;
48		}
49	}
50
51	function updateEllipses() {
52		const targetRect = targetElement.getBoundingClientRect();
53		ellipses.forEach((ellipse, index) => {
54			const ellipseWrapper = container.children[index];
55			positionEllipse(ellipseWrapper, ellipse, targetRect);
56		});
57	}
58
59	ellipses.forEach((ellipse) => {
60		const ellipseWrapper = createEllipse(ellipse);
61		container.appendChild(ellipseWrapper);
62	});
63
64	updateEllipses();
65
66	window.addEventListener("resize", updateEllipses);
67
68    let runCount = 0;
69	function animateEllipsesOnScroll(scrollY) {
70        // So initial scroll can be set on load
71        if (scrollY == undefined) {
72            scrollY = window.scrollY;
73        }
74
75        // No transition on first run (init position), 
76        // then slow transition for page load, then fast transition for scrolling
77        let currentTransition = '';
78        if (runCount === 1) {
79            currentTransition = 'transform 2.3s cubic-bezier(0.34, 1.56, 0.64, 1)';
80        } else if (runCount > 1) {
81            currentTransition = 'transform 1s cubic-bezier(0.22, 0.61, 0.36, 1)';
82        }
83
84		ellipses.forEach((ellipse, index) => {
85            const ellipseWrapper = container.children[index];
86            const scrollAccelerationFactor = 600;
87            const translateY = -scrollY * (ellipse.height / scrollAccelerationFactor);
88            const rotateValue = parseFloat(ellipseWrapper.getAttribute('data-rotate'));
89            const adjustedRotate = -scrollY * 0.01 * (rotateValue + (rotateValue < 0 ? 1 : -1));
90
91            ellipseWrapper.style.transform = `translateY(${translateY}px) rotate(${adjustedRotate}deg)`;
92            ellipseWrapper.style.transition = currentTransition;
93        });
94        
95		title.style.transform = `translateY(${-scrollY * 0.3}px)`;
96        title.style.transition = currentTransition;
97
98        runCount++;
99	}
100
101    // Animate up into position on page load
102    animateEllipsesOnScroll(-50);
103    setTimeout(() => animateEllipsesOnScroll(0), 100);
104
105	window.addEventListener("scroll", () => animateEllipsesOnScroll(undefined));
106});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.