Pen based on "Password button" by @maxbestene at Dribbble https://dribbble.com/shots/4798172-Password-Button
A Pen by Jesús Castro on CodePen.
dEMO https://codemyui.com/correct-and-wrong-password-fill-color-in-text-field-microinteraction/
<div class="container"> | |
<form data-state="typing"> | |
<input type="password" placeholder="Password"> | |
<button type="submit"> | |
<div class="submit-bg"></div> | |
<svg class="icon-arrow" viewBox="0 0 31.49 31.49"> | |
<path d="M21.205 5.007c-.429-.444-1.143-.444-1.587 0-.429.429-.429 1.143 0 1.571l8.047 8.047H1.111C.492 14.626 0 15.118 0 15.737c0 .619.492 1.127 1.111 1.127h26.554l-8.047 8.032c-.429.444-.429 1.159 0 1.587.444.444 1.159.444 1.587 0l9.952-9.952c.444-.429.444-1.143 0-1.571l-9.952-9.953z"/> | |
</svg> | |
<svg class="icon-error" viewBox="0 0 100 100"> | |
<path d="M10 10 L90 90 M10 90 L90 10"/> | |
</svg> | |
<svg class="icon-success" viewBox="0 0 100 100"> | |
<path d="M0 60 L40 100 L100 0"/> | |
</svg> | |
</button> | |
<span class="message message--error">Oops!</span> | |
<span class="message message--success">Yes!</span> | |
</form> | |
<p>Try "<strong>pass</strong>"</p> | |
</div> |
let submitButton = document.querySelector('button'); | |
let input = document.querySelector('input'); | |
let form = document.querySelector('form'); | |
let arrow = document.querySelector('.icon-arrow'); | |
let close = document.querySelector('.icon-error'); | |
let check = document.querySelector('.icon-success'); | |
let checkPath = document.querySelector('.icon-success path'); | |
console.log(checkPath.getTotalLength()); | |
submitButton.addEventListener('click', (e)=>{ | |
e.preventDefault(); | |
if(form.dataset.state != "typing") { | |
TweenMax.to(close,0.5,{ | |
opacity:0, | |
rotation:0 | |
}); | |
TweenMax.fromTo(check,0.5,{ | |
rotation:360*3 | |
},{ | |
rotation:0 | |
}); | |
TweenMax.to(checkPath,0.5,{ | |
strokeDashoffset:175 | |
}); | |
form.dataset.state = "typing"; | |
TweenMax.fromTo(arrow,0.45,{ | |
rotation:0, | |
x:'-60px', | |
opacity:'0' | |
},{ | |
rotation:0, | |
x:'0', | |
opacity:'1' | |
}); | |
return; | |
} | |
TweenMax.to(arrow,1,{ | |
rotation: 360*5, | |
transformOrigin: "50% 50%", | |
opacity: 0 | |
}); | |
setTimeout(()=>{ | |
if(input.value != 'pass') { | |
form.dataset.state = "error"; | |
TweenMax.to(close,0.5,{ | |
rotation: 360*3, | |
opacity: 1 | |
}); | |
} else { | |
form.dataset.state = "success"; | |
TweenMax.to(checkPath,0.65,{ | |
strokeDashoffset: 0 | |
}); | |
} | |
},500); | |
}); |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.1/TweenMax.min.js"></script> |
.container { | |
display: flex; | |
height: 100vh; | |
justify-content: center; | |
align-items: center; | |
flex-direction: column; | |
} | |
p { | |
color: rgba(0,0,0,0.3); | |
} | |
form { | |
position: relative; | |
max-width: 250px; | |
width: 100%; | |
display: flex; | |
align-items: center; | |
font-size: 20px; | |
border-radius: 1.7em; | |
box-shadow:0 0 20px rgba(0,0,0,0.2); | |
overflow: hidden; | |
} | |
input[type="password"]{ | |
border: none; | |
line-height: 2.8em; | |
width: 100%; | |
padding-left: 1.5em; | |
transition: opacity 600ms, transform 300ms; | |
&:focus { | |
outline: none; | |
} | |
&::placeholder { | |
color: rgba(0,0,0,0.2); | |
} | |
} | |
button { | |
color: #fff; | |
background: none; | |
border: none; | |
width: 2.1em; | |
height: 2.1em; | |
flex-shrink: 0; | |
margin-right: 0.45em; | |
text-align: center; | |
border-radius: 50%; | |
position: relative; | |
z-index: 2; | |
padding: 0; | |
&:focus { | |
outline: none; | |
} | |
svg { | |
position: absolute; | |
display: block; | |
width: 50%; | |
height: 40%; | |
top: 30%; | |
left: 25%; | |
margin: 0; | |
fill: currentColor; | |
} | |
} | |
.icon-error { | |
opacity: 0; | |
} | |
.icon-success { | |
fill: transparent; | |
} | |
.icon-error path, | |
.icon-success path { | |
stroke: #fff; | |
stroke-width: 8; | |
} | |
.icon-success path { | |
stroke-dasharray: 175; | |
stroke-dashoffset: 175; | |
} | |
.submit-bg { | |
background: #65D9F9; | |
position: absolute; | |
border-radius: 50%; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
z-index: -1; | |
overflow: hidden; | |
transition: transform 300ms ease-in-out; | |
&::before , &::after { | |
content: ''; | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
opacity: 0; | |
transition: opacity 500ms; | |
} | |
&::before { | |
background: #68D38B; | |
} | |
&::after { | |
background: #E8426E; | |
} | |
} | |
.message { | |
position: absolute; | |
color: #fff; | |
left: 0; | |
right: 0; | |
text-align: center; | |
opacity: 0; | |
pointer-events: none; | |
transform: translateX(3em); | |
transition: transform 500ms, opacity 250ms; | |
z-index: 2; | |
} | |
form:not([data-state="typing"]) { | |
input { | |
transition: opacity 300ms, transform 1s; | |
transform: translateX(-2em); | |
opacity: 0; | |
} | |
.submit-bg { | |
transform: scale(11); | |
} | |
.message { | |
transform: none; | |
} | |
} | |
form[data-state="success"] { | |
.submit-bg::before, | |
.message--success { | |
opacity: 1; | |
} | |
} | |
form[data-state="error"] { | |
.submit-bg::after, | |
.message--error { | |
opacity: 1; | |
} | |
} |