Skip to content

Instantly share code, notes, and snippets.

@BlakePetersen
Last active October 21, 2018 13:53
Show Gist options
  • Save BlakePetersen/c4e4536d2a39a1de70dc6ce416a190a5 to your computer and use it in GitHub Desktop.
Save BlakePetersen/c4e4536d2a39a1de70dc6ce416a190a5 to your computer and use it in GitHub Desktop.
Page progress indicator bar for fixed navigation elements
import throttle from 'lodash/throttle';
const ProgressBar = () => {
let _canvas,
_canvasHeight,
_canvasWidth,
_ctx,
_fillColor,
_raf,
_scrollDepth,
_target;
const init = (target, fillColor) => {
// Kick tires
_fillColor = fillColor || '#708fb3';
_target = target;
// Light fires
_createCanvas();
_drawCanvas();
_attachEventListeners();
};
const _attachEventListeners = () => {
window.addEventListener('resize', throttle(() => {
_createCanvas();
_drawCanvas();
}, 50));
};
const _createCanvas = () => {
// Reset
_destroyCanvas(_canvas);
_canvasHeight = _target.offsetHeight;
_canvasWidth = _target.clientWidth;
// Create Canvas
_canvas = document.createElement('canvas');
_canvas.setAttribute('height', _canvasHeight);
_canvas.setAttribute('width', _canvasWidth);
// Set Context
_ctx = _canvas.getContext('2d');
// Add Canvas to DOM
_target.appendChild(_canvas);
};
const _destroyCanvas = canvas => {
if (canvas) { canvas.parentNode.removeChild(canvas); }
};
const _drawCanvas = () => {
_raf = _requestAnimationFrame(_drawCanvas);
// Reassess scroll position relative to when target is at top of viewport
_scrollDepth = window.pageYOffset;
// Reset Canvas
_ctx.clearRect(0, 0, _canvasWidth, _canvasHeight);
_ctx.save();
// Draw element
_ctx.beginPath();
_ctx.fillStyle = _fillColor;
_ctx.rect(0, 0, _canvasWidth * (_scrollDepth / (document.body.scrollHeight - window.innerHeight)), _canvasHeight);
_ctx.fill();
_ctx.restore();
};
const _requestAnimationFrame = window.requestAnimationFrame;
return {
init: init
};
};
export default ProgressBar;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment