input activity
by phloe
HTML
<label>
<span>URL</span>
<input name="url" autocomplete="off" />
<svg viewBox="0 0 400 400">
<path d="M0,0 v2 h198 l2,0 l2,0 h198 v-2" />
</svg>
</label>
CSS
label {
display: block;
position: relative;
max-width: 400px;
margin: 40px auto;
}
label input {
width: 100%;
text-align: center;
padding: 0;
border: 0;
font-size: 1rem;
line-height: 2rem;
outline: none;
}
label svg {
position: absolute;
top: 100%;
left: 0;
fill: #ccc;
transition: fill .5s ease-in-out;
}
label svg.valid {
fill: #55b3ea;
}
label svg.visited {
fill: #732dd2;
}
label svg path {
fill: inherit;
transition: d 1s ease-out;
}
svg.valid path,
svg.visited path {
d: path("M0,0 v2 h192 l8,8 l8,-8 h192 v-2");
d: "M0,0 v2 h192 l8,8 l8,-8 h192 v-2";
transition: d .2s ease-out;
}
svg.active path {
d: path("M0,0 v2 h190 l10,10 l10,-10 h190 v-2");
d: "M0,0 v2 h190 l10,10 l10,-10 h190 v-2";
transition: d .001s;
}
JavaScript
var input = document.querySelector("input");
var svg = document.querySelector("svg");
var state;
var VALID = "valid";
var VISITED = "visited";
var activeTimeout;
input.addEventListener("input", function () {
var newstate = getState();
if (newstate !== state) {
switchState(newstate);
}
svg.classList.add("active");
resetActiveTimeout();
activeTimeout = setTimeout(resetActive, 100);
});
function resetActive() {
svg.classList.remove("active");
resetActiveTimeout();
}
function resetActiveTimeout() {
if (activeTimeout) {
activeTimeout = clearTimeout(activeTimeout);
}
}
function getState() {
var l = input.value.length;
var newstate;
if (l < 5) {
}
else if (l < 10) {
newstate = VALID;
}
else {
newstate = VISITED;
}
return newstate;
}
function switchState(newstate) {
if (state) {
svg.classList.remove(state);
}
state = newstate;
if (state) {
svg.classList.add(state);
}
}