120 lines
4.0 KiB
JavaScript
120 lines
4.0 KiB
JavaScript
/**
|
|
* demo1.js
|
|
* http://www.codrops.com
|
|
*
|
|
* Licensed under the MIT license.
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
* Copyright 2018, Codrops
|
|
* http://www.codrops.com
|
|
*/
|
|
{
|
|
const passwordInput = document.querySelector('#password');
|
|
const passwordFeedback = document.querySelector('#strength-output');
|
|
const strengthStr = {
|
|
0: 'Worst',
|
|
1: 'Bad',
|
|
2: 'Weak',
|
|
3: 'Good',
|
|
4: 'Strong'
|
|
}
|
|
const canvasWrapper = document.querySelector('.canvas-wrap');
|
|
const canvas = canvasWrapper.querySelector('canvas');
|
|
const poster = document.querySelector('.poster');
|
|
const posterImg = poster.style.backgroundImage.match(/\((.*?)\)/)[1].replace(/('|")/g,'');
|
|
imagesLoaded(poster, { background: true }, () => {
|
|
document.body.classList.remove('loading');
|
|
});
|
|
|
|
// The following code was taken and modified from http://jsfiddle.net/u6apxgfk/390/
|
|
// (C) Ken Fyrstenberg, Epistemex, License: CC3.0-attr
|
|
|
|
// and merged with https://codepen.io/bassta/pen/OPVzyB?editors=1010
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
const img = new Image();
|
|
let imgRatio;
|
|
let wrapperRatio;
|
|
let newWidth;
|
|
let newHeight;
|
|
let newX;
|
|
let newY;
|
|
|
|
let pxFactor = 1;
|
|
|
|
img.src = posterImg;
|
|
img.onload = () => {
|
|
const imgWidth = img.width;
|
|
const imgHeight = img.height;
|
|
imgRatio = imgWidth / imgHeight;
|
|
setCanvasSize();
|
|
render();
|
|
};
|
|
|
|
const setCanvasSize = () => {
|
|
canvas.width = canvasWrapper.offsetWidth;
|
|
canvas.height = canvasWrapper.offsetHeight;
|
|
};
|
|
|
|
const render = () => {
|
|
const w = canvasWrapper.offsetWidth;
|
|
const h = canvasWrapper.offsetHeight;
|
|
|
|
newWidth = w;
|
|
newHeight = h;
|
|
newX = 0;
|
|
newY = 0;
|
|
wrapperRatio = newWidth / newHeight;
|
|
|
|
if ( wrapperRatio > imgRatio ) {
|
|
newHeight = Math.round(w / imgRatio);
|
|
newY = (h - newHeight) / 2;
|
|
}
|
|
else {
|
|
newWidth = Math.round(h * imgRatio);
|
|
newX = (w - newWidth) / 2;
|
|
}
|
|
|
|
// pxFactor will depend on the current typed password.
|
|
// values will be in the range [1,100].
|
|
const size = pxFactor * 0.01;
|
|
|
|
// turn off image smoothing - this will give the pixelated effect
|
|
ctx.mozImageSmoothingEnabled = size === 1 ? true : false;
|
|
ctx.webkitImageSmoothingEnabled = size === 1 ? true : false;
|
|
ctx.imageSmoothingEnabled = size === 1 ? true : false;
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
// draw original image to the scaled size
|
|
ctx.drawImage(img, 0, 0, w*size, h*size);
|
|
// then draw that scaled image thumb back to fill canvas
|
|
// As smoothing is off the result will be pixelated
|
|
ctx.drawImage(canvas, 0, 0, w*size, h*size, newX, newY, newWidth+.05*w, newHeight+.05*h);
|
|
};
|
|
|
|
window.addEventListener('resize', () => {
|
|
setCanvasSize();
|
|
render();
|
|
});
|
|
|
|
passwordInput.addEventListener('input', () => {
|
|
const val = passwordInput.value;
|
|
const result = zxcvbn(val);
|
|
// We want to reveal the image as the password gets stronger. Since the zxcvbn.score has
|
|
// only 5 different values (0-4) we will use the zxcvbn.guesses_log10 output.
|
|
// The guesses_log10 will be >= 11 when the password is considered strong,
|
|
// so we want to map a factor of 1 (all pixelated) to 100 (clear image) to
|
|
// a value of 0 to 11 of guesses_log10.
|
|
// This result will be used in the render function.
|
|
pxFactor = 99/11*Math.min(11,Math.round(result.guesses_log10)) + 1;
|
|
|
|
// so we see most of the time pixels rather than approaching a clear image sooner..
|
|
if ( pxFactor != 1 && pxFactor != 100 ) {
|
|
pxFactor -= pxFactor/100*50;
|
|
}
|
|
|
|
passwordFeedback.innerHTML = val !== '' ? `Password strength: ${strengthStr[result.score]}` : '';
|
|
render();
|
|
});
|
|
}
|