diff --git a/assets/css/src/tabs.css b/assets/css/src/tabs.css index ab7bdbf..b31c8ec 100644 --- a/assets/css/src/tabs.css +++ b/assets/css/src/tabs.css @@ -5,6 +5,13 @@ button.toggle.open:not(.see-more) { font-weight: bold; } +#tabs button.toggle { + transition: margin 0.4s var(--curve-sine); +} + +#tabs.minimized button.toggle.left { + margin-left: calc(-4px - var(--width)); +} button.toggle.left::after { margin-left: var(--unit--horizontal); } @@ -15,6 +22,9 @@ button.toggle.left.open::after { content: "-"; } +#tabs.minimized button.toggle.right { + margin-right: calc(-4px - var(--width)); +} button.toggle.right::before { margin-right: var(--unit--horizontal); } @@ -26,10 +36,12 @@ button.toggle.right.open::before { } #tabs { - position: absolute; width: 100%; z-index: 1; - bottom: calc(var(--unit--vertical-relative) * 4); + + position: sticky; + top: calc(var(--unit--vertical) * 8); + transform: translateY(calc(0rem - var(--unit--vertical-relative) * 4)); } .active-tab { diff --git a/assets/css/src/variables.css b/assets/css/src/variables.css index e75de7e..8fe0dd1 100644 --- a/assets/css/src/variables.css +++ b/assets/css/src/variables.css @@ -21,6 +21,8 @@ --font-weight-light: 200; --font-weight-bold: 400; --font-weight-extra-bold: 550; + + --curve-sine: cubic-bezier(0.445, 0.05, 0.55, 0.95); } @media screen and (min-width: 640px) { diff --git a/assets/js/script.js b/assets/js/script.js index 6d74db0..16927b5 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -1,5 +1,30 @@ -const remFactor = 16; -const verticalUnit = 1.3 * remFactor; +const verticalUnit = getUnit("--unit--vertical"); + +function getUnit(id) { + const remFactor = 16; + const rawUnit = getComputedStyle(document.documentElement).getPropertyValue( + id + ); + if (rawUnit.length === 0) { + throw new Error(`getUnit() error : css variable ${id} doesn't exists.`); + } + const remUnit = parseFloat(rawUnit); + const pxUnit = remUnit * remFactor; + return pxUnit; +} + +function throttle(callback, limit) { + let waiting = false; + return function () { + if (!waiting) { + callback.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, limit); + } + }; +} function toggleTab(data, tab) { if (data.activeTab === tab) { @@ -48,24 +73,65 @@ function roundToNearestHalf(num) { return Math.max(round, 0); } -setWindowHeightFactor(); +function enableToggleTabsVisibility() { + const tabs = document.querySelector("#tabs"); + const toggleLeftBtn = tabs.querySelector("button.toggle.left"); + const toggleRightBtn = tabs.querySelector("button.toggle.right"); + const toggleLeftBtnWidth = toggleLeftBtn.offsetWidth; + const toggleRightBtnWidth = toggleRightBtn.offsetWidth; + + toggleLeftBtn.style = `--width: ${toggleLeftBtnWidth}px`; + toggleRightBtn.style = `--width: ${toggleRightBtnWidth}px`; + + const toggleVisibility = (entries) => { + entries.forEach((entry) => { + const isIntersecting = entry.isIntersecting; + if (isIntersecting) { + console.log("is intersecting"); + tabs.classList.remove("minimized"); + } else { + console.log("is not intersecting"); + tabs.classList.add("minimized"); + } + }); + }; + + const top = verticalUnit * 6; + + const observer = new IntersectionObserver(toggleVisibility, { + root: null, + rootMargin: `-${top}px 0px 0px 0px`, + threshold: 0, + }); + + observer.observe(tabs); +} + +function toggleLogoState() { + const scrollY = window.scrollY || window.pageYOffset; + + if (scrollY > 10) { + document.querySelector("#main-header").classList.add("minimized"); + } else { + document.querySelector("#main-header").classList.remove("minimized"); + } +} document.addEventListener("DOMContentLoaded", () => { - function toggleLogoState() { - const scrollY = window.scrollY || window.pageYOffset; - - if (scrollY > 10) { - document.querySelector("#main-header").classList.add("minimized"); - } else { - document.querySelector("#main-header").classList.remove("minimized"); - } - } - window.window.scrollTo({ top: 0, }); - window.addEventListener("scroll", () => { - toggleLogoState(); - }); + window.addEventListener( + "scroll", + throttle(() => { + toggleLogoState(); + }, 10) + ); + setWindowHeightFactor(); + + // Wait for fonts applied + setTimeout(() => { + enableToggleTabsVisibility(); + }, 100); }); diff --git a/site/snippets/cover.php b/site/snippets/cover.php index bc24a6f..08284f7 100644 --- a/site/snippets/cover.php +++ b/site/snippets/cover.php @@ -3,10 +3,6 @@ $isOpen = isset($isOpen) ? $isOpen : false; ?>
diff --git a/site/snippets/header.php b/site/snippets/header.php index 8bb19b5..191bf03 100644 --- a/site/snippets/header.php +++ b/site/snippets/header.php @@ -5,7 +5,7 @@ <?= $site->title() ?><?= e($page->url() !== $site->url(), '-' . $page->title()) ?> - + diff --git a/site/snippets/tabs.php b/site/snippets/tabs.php index f5a298d..157d1fc 100644 --- a/site/snippets/tabs.php +++ b/site/snippets/tabs.php @@ -8,7 +8,12 @@ $authorFilter = isset($authorFilter) ? $authorFilter : false; $activeTab = isset($activeTab) ? Str::slug($activeTab) : ''; ?> -