Browse Source

Add floating header

Riccardo Balbo 4 years ago
parent
commit
e224e9fff6
4 changed files with 131 additions and 61 deletions
  1. 3 2
      layouts/_default/default.html
  2. 0 1
      layouts/partials/header.html
  3. 54 34
      static/css/style.less
  4. 74 24
      static/js/utils.js

+ 3 - 2
layouts/_default/default.html

@@ -4,11 +4,12 @@
     {{ range first 1 (shuffle  (where   .Site.Pages  "Params.tags"  "intersect" $filter    ) ) }}
     {{ partial "showcaseBanner.html" . }}
 {{ end }}
+<a id="content"></a>
 
 <section class="full responsiveWidth">
-   
+
 <article>
-        <h1 id="content">
+        <h1 >
             {{ partial "postIcon.html" . }}
            
             {{ .Title }}</h1>

+ 0 - 1
layouts/partials/header.html

@@ -14,7 +14,6 @@
             <a rel='noopener nofollow noreferrer' target="_blank"
                 href="https://opencollective.com/jmonkeyengine#section-contributors"> and more...</a>
         </div>
-        <br />
         <div>
             <i class="fab fa-github-alt"></i>
             Contributed by:

+ 54 - 34
static/css/style.less

@@ -851,7 +851,7 @@ body {
         width: 100%;
         margin: 0;
         padding: 0;
-
+     
         #siteTitle {
             color: var(--highlightFg);
             display: flex;
@@ -862,48 +862,65 @@ body {
             align-items: center;
             margin: 0;
             padding: 0;
-            padding-top: 1rem;
-            padding-bottom: 1rem;
+            padding-top: 0.4rem;
+            padding-bottom: 0.5rem;
         }
 
-
-
-
-    }
-}
-
-@media @portrait {
-    header {
-        #logo {
-            display: flex;
-            flex-direction: row;
-            width: 100%;
-            align-items: center;
-
-            .toggleNavOnPortraitButton {
-                margin-right: 1rem;
-                margin-left: auto;
-
+        .smaller {
+            #logo {
+                display: flex;
+                flex-direction: row;
+                width: 100%;
+                align-items: center;
+    
+                .toggleNavOnPortraitButton {
+                    margin-right: 1rem;
+                    margin-left: auto;
+    
+                }
             }
-        }
-
-        flex-direction: column;
-
-        >#siteTitle {
-            flex-direction: column !important;
-            text-align: left !important;
-            align-items: flex-start !important;
-
-            >#contributionsBanner {
+    
+            flex-direction: column;
+    
+            >#siteTitle {
+                flex-direction: column !important;
                 text-align: left !important;
-                margin-left: 1rem !important;
-                margin-top: 1rem !important;
+                align-items: flex-start !important;
+    
+                >#contributionsBanner {
+                    
+                    text-align: left!important;
+                    margin-left:0;
+                    padding-left:0.6rem;
+                        
+                }
             }
+    
+        }
+        @media @portrait {
+            .smaller ()
         }
+        &.floating{
+            position:fixed;
+            top:0;
+            left:0;
+            .smaller();
+           
+            #topmenu{
+                display:none;
+            }
+            #contributionsBanner {
+                display:none;
+            }
+            .toggleNavOnPortraitButton {
+                display:block;
 
+            }
+        }
     }
 }
 
+
 // Something that links to more something
 .more {
     text-align: right;
@@ -957,8 +974,11 @@ body {
 }
 
 #contributionsBanner {
-    text-align: right !important;
+    text-align: left ;
     margin-left: auto;
+    >div{
+        margin-top:0.4rem;
+    }
 }
 
 

+ 74 - 24
static/js/utils.js

@@ -40,26 +40,24 @@ window.shuffleArray = function (array) {
 
 
 
-function isInViewport (el) {
+function isInViewport(el) {
 
     var rect = el.getBoundingClientRect();
 
     return (
         rect.top >= 0 &&
-        rect.left >= 0 &&
-        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
-        rect.right <= (window.innerWidth || document.documentElement.clientWidth) 
+        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
     );
 }
 
-function isVisible(el){
+function isVisible(el) {
     return !!el.offsetParent;
 }
 
 function lazyLoad(parent) {
     parent.querySelectorAll('[lazy]').forEach(el => {
         if (isVisible(el)) {
-            console.log("Lazy load", el,isVisible(el));
+            console.log("Lazy load", el, isVisible(el));
 
             const attributeKeys = el.getAttributeNames();
             attributeKeys.forEach(akey => {
@@ -81,26 +79,78 @@ function lazyLoad(parent) {
 
 
 
-window.addEventListener("DOMContentLoaded", function () {
-    const scrollTo=(contentAnchor)=>{
-        contentAnchor.scrollIntoView({
-            behavior:"smooth",
-            block:"start",
-            inline:"nearest"
-        });
-        console.log("Scroll content into view");
+let floatingHeader = null;
+let visibleDisplay = null;
+const updateFloatingHeader = () => {
+    const header = document.querySelector("body > header");
+    const siteTitle = document.querySelector("#siteTitle");
+    if (!floatingHeader) {
+        console.info("Create floating header!");
+        floatingHeader = header.cloneNode(true);
+        floatingHeader.classList.add("floating");
+        const toTopBtn = floatingHeader.querySelector(".toggleNavOnPortraitButton");
+        if (toTopBtn) {
+            toTopBtn.setAttribute("class", "toggleNavOnPortraitButton fas fa-angle-up");
+            toTopBtn.setAttribute("title", "To top");
+            toTopBtn.onclick = () => {
+                window.scrollTo({
+                    top: 0,
+                    left: 0,
+                    behavior: 'smooth'
+                });
+            }
+        }
+        visibleDisplay = floatingHeader.style.display;
+        document.body.append(floatingHeader);
     }
-    if (!location.hash) {
-        const contentAnchor=document.querySelector("#content");
-        if(contentAnchor)scrollTo(contentAnchor);
-    }else{
-        setTimeout(()=> {
-            window.scrollTo(0, 0);
-            const contentAnchor=document.querySelector(location.hash);
-            scrollTo(contentAnchor);   
-        }, 1);
-        
+    if (!isInViewport(siteTitle)) {
+        // if (floatingHeader.style.display != visibleDisplay) {
+            // console.log("Show floating header");
+        floatingHeader.style.visibility = "visible";
+        // }
+    } else {
+        // if (floatingHeader && floatingHeader.style.display == visibleDisplay) {
+        //     console.log("Hide floating header");
+         floatingHeader.style.visibility = "hidden";
+        // }
     }
+};
+
+document.addEventListener("scroll", updateFloatingHeader);
+
+const scrollTo = (contentAnchor) => {
+    const anchorBound = contentAnchor.getBoundingClientRect();
+    const floatingHBound = floatingHeader.getBoundingClientRect();
+    // contentAnchor.scrollIntoView({
+    //     behavior:"smooth",
+    //     block:"start",
+    //     inline:"nearest"
+    // });
+    window.scrollTo({
+        top: anchorBound.top + window.scrollY - floatingHBound.bottom ,
+        left: 0,
+        behavior: 'smooth'
+    });
+    console.log("Scroll content into view");
+}
+window.addEventListener("DOMContentLoaded", function () {
+    updateFloatingHeader();
+
+
+    setTimeout(() => {
+        window.scrollTo(0, 0);
+        if (location.hash) {
+            const contentAnchor = document.querySelector(location.hash);
+            scrollTo(contentAnchor);
+        } else {
+            const contentAnchor = document.querySelector("#content");
+            if (contentAnchor) scrollTo(contentAnchor);
+        }
+    }, 1);
+
+
+
+
 
     document.querySelectorAll("[toggle]").forEach(el => {
         const toggleId = el.getAttribute("toggle");