"Animated Input Labels"
Bootstrap 4.1.1 Snippet by koshikojha

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script> <script src="https://unpkg.com/splitting/dist/splitting.min.js"></script> <div id="contain"> <div class="inputContainer"> <label id="inputOneLabel" for="inputOne">Input</label> <input id="inputOne"/> </div> <div class="inputContainer"> <label id="inputTwoLabel" for="inputTwo">Input</label> <input id="inputTwo"/> </div> <div class="inputContainer"> <label id="inputThreeLabel" for="inputThree">Input</label> <input id="inputThree"/> </div> </div>
@import url("https://fonts.googleapis.com/css?family=Quicksand&display=swap"); html, body { font-family: 'Quicksand', sans-serif; height: 100%; } #contain { height: 100%; display: flex; flex-flow: column; align-items: center; justify-content: center; } .inputContainer { position: relative; margin: 24px; } .inputContainer label { font-size: 0.9em; display: block; margin-bottom: 6px; line-height: 0px; } .inputContainer input { margin-top: 6px; height: 30px; width: 300px; }
const inputOne = document.querySelector("#inputOne"); const inputOneLabel = document.querySelector("#inputOneLabel"); const splitLabelOne = Splitting({ target: inputOneLabel, by: "chars" })[0] .chars; const inputTwo = document.querySelector("#inputTwo"); const inputTwoLabel = document.querySelector("#inputTwoLabel"); const splitLabelTwo = Splitting({ target: inputTwoLabel, by: "chars" })[0] .chars; const inputThree = document.querySelector("#inputThree"); const inputThreeLabel = document.querySelector("#inputThreeLabel"); const splitLabelThree = Splitting({ target: inputThreeLabel, by: "chars" })[0] .chars; let sineMeUp = false; const sineCharacters = []; inputOne.addEventListener("focus", animateInputOne); inputOne.addEventListener("blur", deanimateInputOne); inputTwo.addEventListener("focus", animateInputTwo); inputTwo.addEventListener("blur", deanimateInputTwo); inputThree.addEventListener("focus", () => { sineMeUp = true; animateInputThree([...sineCharacters]); }); inputThree.addEventListener("blur", () => { sineMeUp = false; deanimateInputThree(); }); function animateInputOne() { const charDistance = inputOne.clientWidth / 4; let count = 0; let charStart = 0; //Using fromTo because absolute positioning //makes all the chars start at 0 on first execution for (let char of splitLabelOne) { TweenMax.fromTo( char, 0.5, { x: charStart }, { x: charDistance * count, ease: Elastic.easeInOut, position: "absolute" } ); charStart += determineCharDistance(count); count++; } } function deanimateInputOne() { let charDistance = 0; let count = 0; for (let char of splitLabelOne) { TweenMax.to(char, 0.5, { x: charDistance, position: "absolute", ease: Elastic.easeInOut }); charDistance += determineCharDistance(count); count++; } } function animateInputTwo() { const inputWidth = inputTwo.clientWidth; const inputHeight = inputTwo.clientHeight; let distanceFromInput = inputWidth - 28; let count = 0; let delay = 0.5; let charStart = 0; for (const char of splitLabelTwo) { char.style.zIndex = "-1"; TweenMax.fromTo( char, 0.25, { x: charStart }, { y: inputHeight + 24, x: distanceFromInput, rotation: 360, delay, position: "absolute", ease: Power3.easeInOut } ); distanceFromInput += determineCharDistance(count); charStart += determineCharDistance(count); delay -= 0.1; count++; } } function deanimateInputTwo() { let charDistance = 0; let count = 0; let delay = 0.0; for (let char of splitLabelTwo) { char.style.zIndex = "-1"; TweenMax.to(char, 0.25, { y: 0, x: charDistance, rotation: -360, position: "absolute", delay, ease: Power3.easeInOut }); charDistance += determineCharDistance(count); count++; delay += 0.1; } } function animateInputThree(chars) { if (sineMeUp) { let count = 0; for (const char of splitLabelThree) { TweenMax.to(char, 0.01, { position: "absolute", y: chars[count].y, x: chars[count].x, ease: Power2.easeInOut }); chars[count].angle += 0.12; chars[count].y = Math.sin(chars[count].angle) * -5 - 5; count++; } requestAnimationFrame(() => { animateInputThree(chars); }); } } function deanimateInputThree() { for (const char of splitLabelThree) { TweenMax.to(char, 0.25, { y: 0, ease: Power2.easeInOut }); } } function determineCharDistance(count) { return count === 0 ? 3 : 8; } //To configure the sine wave input properly window.onload = () => { const offset = Math.PI / 5; let count = 0; let charDistance = 0; for (let i = 0; i < 5; i++) { const angle = offset * count; sineCharacters.push({ angle, y: Math.sin(angle) * -5 - 5, x: charDistance }); charDistance += determineCharDistance(count); count++; } };

Related: See More


Questions / Comments: