Add scroll reveal

This commit is contained in:
Jeremy Thomas 2017-10-26 19:47:48 +01:00
parent befa6b68b0
commit 74c413c378
14 changed files with 232 additions and 65 deletions

View File

@ -1,6 +1,4 @@
<div class="container"> {% include navbar.html id="BlogHero" %}
{% include navbar.html id="BlogHero" %}
</div>
<section class="hero is-warning"> <section class="hero is-warning">
<div class="hero-body"> <div class="hero-body">

View File

@ -1,7 +1,7 @@
<nav id="navbar" class="navbar {% if include.fixed %}is-fixed-top has-shadow{% endif %} {% if include.transparent %}is-transparent{% endif %}"> <nav id="navbar" class="navbar is-fixed-top {% if include.transparent %}is-transparent{% endif %}">
{% if include.has_container %} <div id="specialShadow" class="bd-special-shadow"></div>
<div class="container"> <div class="container">
{% endif %}
<div class="navbar-brand"> <div class="navbar-brand">
<a class="navbar-item" href="{{ site.url }}"> <a class="navbar-item" href="{{ site.url }}">
@ -20,7 +20,7 @@
</span> </span>
</a> </a>
<div class="navbar-burger burger" data-target="navMenu{{ include.id }}"> <div id="navbarBurger" class="navbar-burger burger" data-target="navMenu{{ include.id }}">
<span></span> <span></span>
<span></span> <span></span>
<span></span> <span></span>
@ -187,7 +187,5 @@
</div> </div>
</div> </div>
{% if include.has_container %}
</div> </div>
{% endif %}
</nav> </nav>

View File

@ -57,7 +57,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Modals // Modals
const $html = document.documentElement; const rootEl = document.documentElement;
const $modals = getAll('.modal'); const $modals = getAll('.modal');
const $modalButtons = getAll('.modal-button'); const $modalButtons = getAll('.modal-button');
const $modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button'); const $modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button');
@ -67,7 +67,7 @@ document.addEventListener('DOMContentLoaded', () => {
$el.addEventListener('click', () => { $el.addEventListener('click', () => {
const target = $el.dataset.target; const target = $el.dataset.target;
const $target = document.getElementById(target); const $target = document.getElementById(target);
$html.classList.add('is-clipped'); rootEl.classList.add('is-clipped');
$target.classList.add('is-active'); $target.classList.add('is-active');
}); });
}); });
@ -90,7 +90,7 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
function closeModals() { function closeModals() {
$html.classList.remove('is-clipped'); rootEl.classList.remove('is-clipped');
$modals.forEach($el => { $modals.forEach($el => {
$el.classList.remove('is-active'); $el.classList.remove('is-active');
}); });
@ -164,27 +164,96 @@ document.addEventListener('DOMContentLoaded', () => {
return Array.prototype.slice.call(document.querySelectorAll(selector), 0); return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
} }
let latestKnownScrollY = 0; // Scrolling
const navbarEl = document.getElementById('navbar');
const navbarBurger = document.getElementById('navbarBurger');
const specialShadow = document.getElementById('specialShadow');
const navbarHeight = 52;
let navbarOpen = false;
let pinned = false;
let horizon = navbarHeight;
let whereYouStoppedScrolling = 0;
let threshold = 200;
let scrollFactor = 0;
navbarBurger.addEventListener('click', el => {
navbarOpen = !navbarOpen;
if (navbarOpen) {
rootEl.classList.add('bd-is-clipped-touch');
} else {
rootEl.classList.remove('bd-is-clipped-touch');
}
});
function upOrDown(lastY, currentY) {
if (currentY >= lastY) {
return goingDown(currentY);
}
return goingUp(currentY);
}
function goingDown(currentY) {
const trigger = navbarHeight;
whereYouStoppedScrolling = currentY;
if (currentY > horizon) {
horizon = currentY;
}
translateHeader(currentY);
}
function goingUp(currentY) {
const trigger = 0;
if (currentY < (whereYouStoppedScrolling - navbarHeight)) {
horizon = currentY + navbarHeight;
}
translateHeader(currentY);
}
function constrainDelta(delta) {
return Math.max(0, Math.min(delta, navbarHeight));
}
function translateHeader(currentY) {
const delta = constrainDelta(Math.abs(currentY - horizon));
const translateValue = delta - navbarHeight;
const translateFactor = 1 + translateValue / navbarHeight;
let navbarStyle = `
transform: translateY(${translateValue}px);
`;
if (currentY > threshold) {
scrollFactor = 1;
} else {
scrollFactor = currentY / threshold;
}
specialShadow.style.opacity = scrollFactor;
specialShadow.style.transform = 'scaleY(' + translateFactor + ')';
navbarEl.setAttribute('style', navbarStyle);
}
translateHeader(window.scrollY);
let ticking = false; let ticking = false;
let lastY = 0;
window.addEventListener('scroll', function() {
const currentY = window.scrollY;
function scrollUpdate() { if (!ticking) {
window.requestAnimationFrame(function() {
upOrDown(lastY, currentY);
ticking = false; ticking = false;
// do stuff lastY = currentY;
});
} }
function onScroll() {
latestKnownScrollY = window.scrollY;
scrollRequestTick();
}
function scrollRequestTick() {
if(!ticking) {
requestAnimationFrame(scrollUpdate);
}
ticking = true; ticking = true;
} });
window.addEventListener('scroll', onScroll, false);
}); });

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="{% if page.fixed_navbar %}has-navbar-fixed-top{% endif %} {% if page.route %}route-{{page.route}}{% elsif page.layout %}route-{{page.layout}}{% endif %}"> <html lang="en" class="has-navbar-fixed-top {% if page.route %}route-{{page.route}}{% elsif page.layout %}route-{{page.layout}}{% endif %}">
{% include head.html %} {% include head.html %}
<body class="layout-{{ page.layout }}{% if page.doc-tab %} page-{{ page.doc-tab}}{% endif %}"> <body class="layout-{{ page.layout }}{% if page.doc-tab %} page-{{ page.doc-tab}}{% endif %}">
{% include deprecated.html %} {% include deprecated.html %}

View File

@ -1,3 +1,18 @@
.bd-special-shadow
background-image: linear-gradient(rgba(#000, 0.1), rgba(#000, 0))
height: 10px
left: 0
opacity: 0
position: absolute
right: 0
top: 100%
transform: scaleY(0)
transform-origin: center top
+touch
.bd-is-clipped-touch
overflow: hidden !important
#images #images
tr tr
td:nth-child(2) td:nth-child(2)

View File

@ -7,9 +7,7 @@ github_url: https://github.com/jgthms/bulma-start
npm_url: https://www.npmjs.com/package/bulma-start npm_url: https://www.npmjs.com/package/bulma-start
--- ---
<div class="container"> {% include navbar.html id="BulmaStartHero" %}
{% include navbar.html id="BulmaStartHero" %}
</div>
<section class="hero is-success"> <section class="hero is-success">
<div class="hero-body"> <div class="hero-body">

View File

@ -6655,6 +6655,11 @@ a.navbar-link.is-active {
.navbar.is-fixed-top-touch { .navbar.is-fixed-top-touch {
top: 0; top: 0;
} }
.navbar.is-fixed-top .navbar-menu, .navbar.is-fixed-top-touch .navbar-menu {
-webkit-overflow-scrolling: touch;
max-height: calc(100vh - 3.25rem);
overflow: auto;
}
html.has-navbar-fixed-top-touch { html.has-navbar-fixed-top-touch {
padding-top: 3.25rem; padding-top: 3.25rem;
} }
@ -10349,6 +10354,24 @@ svg {
text-decoration: underline; text-decoration: underline;
} }
.bd-special-shadow {
background-image: linear-gradient(rgba(0, 0, 0, 0.1), transparent);
height: 10px;
left: 0;
opacity: 0;
position: absolute;
right: 0;
top: 100%;
transform: scaleY(0);
transform-origin: center top;
}
@media screen and (max-width: 1023px) {
.bd-is-clipped-touch {
overflow: hidden !important;
}
}
#images tr td:nth-child(2) { #images tr td:nth-child(2) {
width: 320px; width: 320px;
} }

View File

@ -96,9 +96,7 @@ websites:
</div> </div>
{% endcapture %} {% endcapture %}
<div class="container"> {% include navbar.html id="ExpoHero" %}
{% include navbar.html id="ExpoHero" %}
</div>
<section class="hero is-success"> <section class="hero is-success">
<div class="hero-body"> <div class="hero-body">

View File

@ -85,9 +85,7 @@ extensions:
height: 352 height: 352
--- ---
<div class="container"> {% include navbar.html id="Extensions" %}
{% include navbar.html id="Extensions" %}
</div>
<section class="hero is-primary"> <section class="hero is-primary">
<div class="hero-body"> <div class="hero-body">

View File

@ -4,7 +4,7 @@ route: index
fixed_navbar: true fixed_navbar: true
--- ---
{% include navbar.html id="Index" fixed=true has_container=true %} {% include navbar.html id="Index" fixed=true has_container=true boxed=true transparent=true %}
{% include index/intro.html %} {% include index/intro.html %}

View File

@ -59,7 +59,7 @@ document.addEventListener('DOMContentLoaded', function () {
// Modals // Modals
var $html = document.documentElement; var rootEl = document.documentElement;
var $modals = getAll('.modal'); var $modals = getAll('.modal');
var $modalButtons = getAll('.modal-button'); var $modalButtons = getAll('.modal-button');
var $modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button'); var $modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button');
@ -69,7 +69,7 @@ document.addEventListener('DOMContentLoaded', function () {
$el.addEventListener('click', function () { $el.addEventListener('click', function () {
var target = $el.dataset.target; var target = $el.dataset.target;
var $target = document.getElementById(target); var $target = document.getElementById(target);
$html.classList.add('is-clipped'); rootEl.classList.add('is-clipped');
$target.classList.add('is-active'); $target.classList.add('is-active');
}); });
}); });
@ -92,7 +92,7 @@ document.addEventListener('DOMContentLoaded', function () {
}); });
function closeModals() { function closeModals() {
$html.classList.remove('is-clipped'); rootEl.classList.remove('is-clipped');
$modals.forEach(function ($el) { $modals.forEach(function ($el) {
$el.classList.remove('is-active'); $el.classList.remove('is-active');
}); });
@ -166,25 +166,93 @@ document.addEventListener('DOMContentLoaded', function () {
return Array.prototype.slice.call(document.querySelectorAll(selector), 0); return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
} }
var latestKnownScrollY = 0; // Scrolling
var navbarEl = document.getElementById('navbar');
var navbarBurger = document.getElementById('navbarBurger');
var specialShadow = document.getElementById('specialShadow');
var navbarHeight = 52;
var navbarOpen = false;
var pinned = false;
var horizon = navbarHeight;
var whereYouStoppedScrolling = 0;
var threshold = 200;
var scrollFactor = 0;
navbarBurger.addEventListener('click', function (el) {
navbarOpen = !navbarOpen;
if (navbarOpen) {
rootEl.classList.add('bd-is-clipped-touch');
} else {
rootEl.classList.remove('bd-is-clipped-touch');
}
});
function upOrDown(lastY, currentY) {
if (currentY >= lastY) {
return goingDown(currentY);
}
return goingUp(currentY);
}
function goingDown(currentY) {
var trigger = navbarHeight;
whereYouStoppedScrolling = currentY;
if (currentY > horizon) {
horizon = currentY;
}
translateHeader(currentY);
}
function goingUp(currentY) {
var trigger = 0;
if (currentY < whereYouStoppedScrolling - navbarHeight) {
horizon = currentY + navbarHeight;
}
translateHeader(currentY);
}
function constrainDelta(delta) {
return Math.max(0, Math.min(delta, navbarHeight));
}
function translateHeader(currentY) {
var delta = constrainDelta(Math.abs(currentY - horizon));
var translateValue = delta - navbarHeight;
var translateFactor = 1 + translateValue / navbarHeight;
var navbarStyle = '\n transform: translateY(' + translateValue + 'px);\n ';
if (currentY > threshold) {
scrollFactor = 1;
} else {
scrollFactor = currentY / threshold;
}
specialShadow.style.opacity = scrollFactor;
specialShadow.style.transform = 'scaleY(' + translateFactor + ')';
navbarEl.setAttribute('style', navbarStyle);
}
translateHeader(window.scrollY);
var ticking = false; var ticking = false;
var lastY = 0;
window.addEventListener('scroll', function () {
var currentY = window.scrollY;
function scrollUpdate() {
ticking = false;
// do stuff
}
function onScroll() {
latestKnownScrollY = window.scrollY;
scrollRequestTick();
}
function scrollRequestTick() {
if (!ticking) { if (!ticking) {
requestAnimationFrame(scrollUpdate); window.requestAnimationFrame(function () {
} upOrDown(lastY, currentY);
ticking = true; ticking = false;
lastY = currentY;
});
} }
window.addEventListener('scroll', onScroll, false); ticking = true;
});
}); });

View File

@ -13,9 +13,7 @@ tweets:
retweets: "0" retweets: "0"
--- ---
<div class="container"> {% include navbar.html id="LoveHero" %}
{% include navbar.html id="LoveHero" %}
</div>
<section class="hero bd-is-love bd-rainbow"> <section class="hero bd-is-love bd-rainbow">
<div class="hero-body"> <div class="hero-body">

View File

@ -41,9 +41,7 @@ images:
</a> </a>
{% endcapture %} {% endcapture %}
<div class="container"> {% include navbar.html id="MadeWithBulmaHero" %}
{% include navbar.html id="MadeWithBulmaHero" %}
</div>
<section class="hero is-primary"> <section class="hero is-primary">
<div class="hero-body"> <div class="hero-body">

View File

@ -222,6 +222,12 @@ a.navbar-link
box-shadow: 0 -2px 3px rgba($black, 0.1) box-shadow: 0 -2px 3px rgba($black, 0.1)
&.is-fixed-top-touch &.is-fixed-top-touch
top: 0 top: 0
&.is-fixed-top,
&.is-fixed-top-touch
.navbar-menu
+overflow-touch
max-height: calc(100vh - #{$navbar-height})
overflow: auto
html.has-navbar-fixed-top-touch html.has-navbar-fixed-top-touch
padding-top: $navbar-height padding-top: $navbar-height
html.has-navbar-fixed-bottom-touch html.has-navbar-fixed-bottom-touch