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" %}
</div>
{% include navbar.html id="BlogHero" %}
<section class="hero is-warning">
<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 %}">
{% if include.has_container %}
<div class="container">
{% endif %}
<nav id="navbar" class="navbar is-fixed-top {% if include.transparent %}is-transparent{% endif %}">
<div id="specialShadow" class="bd-special-shadow"></div>
<div class="container">
<div class="navbar-brand">
<a class="navbar-item" href="{{ site.url }}">
@ -20,7 +20,7 @@
</span>
</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>
@ -187,7 +187,5 @@
</div>
</div>
{% if include.has_container %}
</div>
{% endif %}
</div>
</nav>

View File

@ -57,7 +57,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Modals
const $html = document.documentElement;
const rootEl = document.documentElement;
const $modals = getAll('.modal');
const $modalButtons = getAll('.modal-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', () => {
const target = $el.dataset.target;
const $target = document.getElementById(target);
$html.classList.add('is-clipped');
rootEl.classList.add('is-clipped');
$target.classList.add('is-active');
});
});
@ -90,7 +90,7 @@ document.addEventListener('DOMContentLoaded', () => {
});
function closeModals() {
$html.classList.remove('is-clipped');
rootEl.classList.remove('is-clipped');
$modals.forEach($el => {
$el.classList.remove('is-active');
});
@ -164,27 +164,96 @@ document.addEventListener('DOMContentLoaded', () => {
return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
}
let latestKnownScrollY = 0;
let ticking = false;
// Scrolling
function scrollUpdate() {
ticking = false;
// do stuff
}
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;
function onScroll() {
latestKnownScrollY = window.scrollY;
scrollRequestTick();
}
function scrollRequestTick() {
if(!ticking) {
requestAnimationFrame(scrollUpdate);
if (navbarOpen) {
rootEl.classList.add('bd-is-clipped-touch');
} else {
rootEl.classList.remove('bd-is-clipped-touch');
}
ticking = true;
});
function upOrDown(lastY, currentY) {
if (currentY >= lastY) {
return goingDown(currentY);
}
return goingUp(currentY);
}
window.addEventListener('scroll', onScroll, false);
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 lastY = 0;
window.addEventListener('scroll', function() {
const currentY = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
upOrDown(lastY, currentY);
ticking = false;
lastY = currentY;
});
}
ticking = true;
});
});

View File

@ -1,5 +1,5 @@
<!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 %}
<body class="layout-{{ page.layout }}{% if page.doc-tab %} page-{{ page.doc-tab}}{% endif %}">
{% 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
tr
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
---
<div class="container">
{% include navbar.html id="BulmaStartHero" %}
</div>
{% include navbar.html id="BulmaStartHero" %}
<section class="hero is-success">
<div class="hero-body">

View File

@ -6655,6 +6655,11 @@ a.navbar-link.is-active {
.navbar.is-fixed-top-touch {
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 {
padding-top: 3.25rem;
}
@ -10349,6 +10354,24 @@ svg {
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) {
width: 320px;
}

View File

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

View File

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

View File

@ -4,7 +4,7 @@ route: index
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 %}

View File

@ -59,7 +59,7 @@ document.addEventListener('DOMContentLoaded', function () {
// Modals
var $html = document.documentElement;
var rootEl = document.documentElement;
var $modals = getAll('.modal');
var $modalButtons = getAll('.modal-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 () {
var target = $el.dataset.target;
var $target = document.getElementById(target);
$html.classList.add('is-clipped');
rootEl.classList.add('is-clipped');
$target.classList.add('is-active');
});
});
@ -92,7 +92,7 @@ document.addEventListener('DOMContentLoaded', function () {
});
function closeModals() {
$html.classList.remove('is-clipped');
rootEl.classList.remove('is-clipped');
$modals.forEach(function ($el) {
$el.classList.remove('is-active');
});
@ -166,25 +166,93 @@ document.addEventListener('DOMContentLoaded', function () {
return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
}
var latestKnownScrollY = 0;
var ticking = false;
// Scrolling
function scrollUpdate() {
ticking = false;
// do stuff
}
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;
function onScroll() {
latestKnownScrollY = window.scrollY;
scrollRequestTick();
}
navbarBurger.addEventListener('click', function (el) {
navbarOpen = !navbarOpen;
function scrollRequestTick() {
if (!ticking) {
requestAnimationFrame(scrollUpdate);
if (navbarOpen) {
rootEl.classList.add('bd-is-clipped-touch');
} else {
rootEl.classList.remove('bd-is-clipped-touch');
}
ticking = true;
});
function upOrDown(lastY, currentY) {
if (currentY >= lastY) {
return goingDown(currentY);
}
return goingUp(currentY);
}
window.addEventListener('scroll', onScroll, false);
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 lastY = 0;
window.addEventListener('scroll', function () {
var currentY = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function () {
upOrDown(lastY, currentY);
ticking = false;
lastY = currentY;
});
}
ticking = true;
});
});

View File

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

View File

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

View File

@ -222,6 +222,12 @@ a.navbar-link
box-shadow: 0 -2px 3px rgba($black, 0.1)
&.is-fixed-top-touch
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
padding-top: $navbar-height
html.has-navbar-fixed-bottom-touch