diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-21 21:56:55 +0300 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-21 21:56:55 +0300 |
| commit | c735556726e75428550a3d28a2cf58e2c8490b7d (patch) | |
| tree | fd0ae29d1636b825abeedff6b99d3376bb383135 /src/components/common/BasicScripts.astro | |
Initial template
Diffstat (limited to 'src/components/common/BasicScripts.astro')
| -rw-r--r-- | src/components/common/BasicScripts.astro | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/components/common/BasicScripts.astro b/src/components/common/BasicScripts.astro new file mode 100644 index 0000000..c7290b2 --- /dev/null +++ b/src/components/common/BasicScripts.astro @@ -0,0 +1,255 @@ +--- +import { UI } from 'astrowind:config'; +--- + +<script is:inline define:vars={{ defaultTheme: UI.theme }}> + if (window.basic_script) { + return; + } + + window.basic_script = true; + + function applyTheme(theme) { + if (theme === 'dark') { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + } + + const initTheme = function () { + if ((defaultTheme && defaultTheme.endsWith(':only')) || (!localStorage.theme && defaultTheme !== 'system')) { + applyTheme(defaultTheme.replace(':only', '')); + } else if ( + localStorage.theme === 'dark' || + (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches) + ) { + applyTheme('dark'); + } else { + applyTheme('light'); + } + }; + initTheme(); + + function attachEvent(selector, event, fn) { + const matches = typeof selector === 'string' ? document.querySelectorAll(selector) : selector; + if (matches && matches.length) { + matches.forEach((elem) => { + elem.addEventListener(event, (e) => fn(e, elem), false); + }); + } + } + + const onLoad = function () { + let lastKnownScrollPosition = window.scrollY; + let ticking = true; + + attachEvent('#header nav', 'click', function () { + document.querySelector('[data-aw-toggle-menu]')?.classList.remove('expanded'); + document.body.classList.remove('overflow-hidden'); + document.getElementById('header')?.classList.remove('h-screen'); + document.getElementById('header')?.classList.remove('expanded'); + document.getElementById('header')?.classList.remove('bg-page'); + document.querySelector('#header nav')?.classList.add('hidden'); + document.querySelector('#header > div > div:last-child')?.classList.add('hidden'); + }); + + attachEvent('[data-aw-toggle-menu]', 'click', function (_, elem) { + elem.classList.toggle('expanded'); + document.body.classList.toggle('overflow-hidden'); + document.getElementById('header')?.classList.toggle('h-screen'); + document.getElementById('header')?.classList.toggle('expanded'); + document.getElementById('header')?.classList.toggle('bg-page'); + document.querySelector('#header nav')?.classList.toggle('hidden'); + document.querySelector('#header > div > div:last-child')?.classList.toggle('hidden'); + }); + + attachEvent('[data-aw-toggle-color-scheme]', 'click', function () { + if (defaultTheme.endsWith(':only')) { + return; + } + document.documentElement.classList.toggle('dark'); + localStorage.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light'; + }); + + attachEvent('[data-aw-social-share]', 'click', function (_, elem) { + const network = elem.getAttribute('data-aw-social-share'); + const url = encodeURIComponent(elem.getAttribute('data-aw-url')); + const text = encodeURIComponent(elem.getAttribute('data-aw-text')); + + let href; + switch (network) { + case 'facebook': + href = `https://www.facebook.com/sharer.php?u=${url}`; + break; + case 'twitter': + href = `https://twitter.com/intent/tweet?url=${url}&text=${text}`; + break; + case 'linkedin': + href = `https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${text}`; + break; + case 'whatsapp': + href = `https://wa.me/?text=${text}%20${url}`; + break; + case 'mail': + href = `mailto:?subject=%22${text}%22&body=${text}%20${url}`; + break; + + default: + return; + } + + const newlink = document.createElement('a'); + newlink.target = '_blank'; + newlink.href = href; + newlink.click(); + }); + + const screenSize = window.matchMedia('(max-width: 767px)'); + screenSize.addEventListener('change', function () { + document.querySelector('[data-aw-toggle-menu]')?.classList.remove('expanded'); + document.body.classList.remove('overflow-hidden'); + document.getElementById('header')?.classList.remove('h-screen'); + document.getElementById('header')?.classList.remove('expanded'); + document.getElementById('header')?.classList.remove('bg-page'); + document.querySelector('#header nav')?.classList.add('hidden'); + document.querySelector('#header > div > div:last-child')?.classList.add('hidden'); + }); + + function applyHeaderStylesOnScroll() { + const header = document.querySelector('#header[data-aw-sticky-header]'); + if (!header) return; + if (lastKnownScrollPosition > 60 && !header.classList.contains('scroll')) { + header.classList.add('scroll'); + } else if (lastKnownScrollPosition <= 60 && header.classList.contains('scroll')) { + header.classList.remove('scroll'); + } + ticking = false; + } + applyHeaderStylesOnScroll(); + + attachEvent([document], 'scroll', function () { + lastKnownScrollPosition = window.scrollY; + + if (!ticking) { + window.requestAnimationFrame(() => { + applyHeaderStylesOnScroll(); + }); + ticking = true; + } + }); + }; + const onPageShow = function () { + document.documentElement.classList.add('motion-safe:scroll-smooth'); + const elem = document.querySelector('[data-aw-toggle-menu]'); + if (elem) { + elem.classList.remove('expanded'); + } + document.body.classList.remove('overflow-hidden'); + document.getElementById('header')?.classList.remove('h-screen'); + document.getElementById('header')?.classList.remove('expanded'); + document.querySelector('#header nav')?.classList.add('hidden'); + }; + + window.onload = onLoad; + window.onpageshow = onPageShow; + + document.addEventListener('astro:after-swap', () => { + initTheme(); + onLoad(); + onPageShow(); + }); +</script> + +<script is:inline> + /* Inspired by: https://github.com/heidkaemper/tailwindcss-intersect */ + const Observer = { + observer: null, + delayBetweenAnimations: 100, + animationCounter: 0, + + start() { + const selectors = [ + '[class*=" intersect:"]', + '[class*=":intersect:"]', + '[class^="intersect:"]', + '[class="intersect"]', + '[class*=" intersect "]', + '[class^="intersect "]', + '[class$=" intersect"]', + ]; + + const elements = Array.from(document.querySelectorAll(selectors.join(','))); + + const getThreshold = (element) => { + if (element.classList.contains('intersect-full')) return 0.99; + if (element.classList.contains('intersect-half')) return 0.5; + if (element.classList.contains('intersect-quarter')) return 0.25; + return 0; + }; + + elements.forEach((el) => { + el.setAttribute('no-intersect', ''); + el._intersectionThreshold = getThreshold(el); + }); + + const callback = (entries) => { + entries.forEach((entry) => { + requestAnimationFrame(() => { + const target = entry.target; + const intersectionRatio = entry.intersectionRatio; + const threshold = target._intersectionThreshold; + + if (target.classList.contains('intersect-no-queue')) { + if (entry.isIntersecting) { + target.removeAttribute('no-intersect'); + if (target.classList.contains('intersect-once')) { + this.observer.unobserve(target); + } + } else { + target.setAttribute('no-intersect', ''); + } + return; + } + + if (intersectionRatio >= threshold) { + if (!target.hasAttribute('data-animated')) { + target.removeAttribute('no-intersect'); + target.setAttribute('data-animated', 'true'); + + const delay = this.animationCounter * this.delayBetweenAnimations; + this.animationCounter++; + + target.style.transitionDelay = `${delay}ms`; + target.style.animationDelay = `${delay}ms`; + + if (target.classList.contains('intersect-once')) { + this.observer.unobserve(target); + } + } + } else { + target.setAttribute('no-intersect', ''); + target.removeAttribute('data-animated'); + target.style.transitionDelay = ''; + target.style.animationDelay = ''; + + this.animationCounter = 0; + } + }); + }); + }; + + this.observer = new IntersectionObserver(callback.bind(this), { threshold: [0, 0.25, 0.5, 0.99] }); + + elements.forEach((el) => { + this.observer.observe(el); + }); + }, + }; + + Observer.start(); + + document.addEventListener('astro:after-swap', () => { + Observer.start(); + }); +</script> |
