Анимированный «бумажный» самолетик для кнопки SEND (отправить)

by Denis Tverdokhlebov

HTML

<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<div class="send-button">
 <span class="text">send</span>
  <span class="icon-wrapper">
  	<span class="icon-1 ion-paper-airplane"></span>
		<span class="icon-2 ion-checkmark"></span>
  </span>
</div>

CSS

html {
  box-sizing: border-box;
  font-size: 62.5%;
  overflow: hidden;
}

* {
  padding: 0;
  margin: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  box-sizing: inherit;
}
*::after, *::before {
  box-sizing: inherit;
}

body .send-button {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

@keyframes icon-animation {
  0% {
    transform: rotate(0deg) scale(1);
  }
  33% {
    transform: rotate(-120deg) scale(4);
  }
  66% {
    transform: rotate(-240deg) scale(4);
  }
  100% {
    transform: rotate(-360deg) scale(1);
  }
}
@keyframes input-shadow {
  0% {
    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2);
  }
  40% {
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  }
  50% {
    box-shadow: none;
  }
  70% {
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  }
  100% {
    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2);
  }
}
.icon-wrapper-animation {
  animation: icon-animation 1.5s linear;
  transition: color 0.6s ease;
  color: #66bb6a;
}

.clicked {
  transform: translate(-50%, calc(-50% + 1px)) !important;
  transition: transform 0.15s ease;
  animation: input-shadow 0.15s ease;
  box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2);
}
.clicked > .text {
  transform: translateY(1px);
  transition: transform 0.15s ease-out;
}

body {
  background-color: #d81b60;
}
body .send-button {
  background-color: #c51162;
  width: 250px;
  height: 45px;
  border-radius: 2px;
  box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
  cursor: pointer;
  user-select: none;
  transition: transform 0.15s;
  text-shadow:...

JavaScript

$(() => {
	var $sendBtn = $('.send-button'),
			$iWrapper = $('.icon-wrapper'),
			$i1 = $('.icon-1'),
			$i2 = $('.icon-2');
	
	function animationEvent() {
		var t,
				el = document.createElement('fakeelement');

		var animations = {
			animation: 'animationend',
			OAnimation: 'oAnimationEnd',
			MozAnimation: 'animationend',
			WebkitAnimation: 'webkitAnimationEnd'
		};

		for (t in animations) {
			if (el.style[t] !== undefined) {
				return animations[t];
			}
		}
	}

	$sendBtn.on('click', e => {
		$iWrapper.css('color', '#66bb6a');
		$iWrapper.addClass('icon-wrapper-animation');
		$sendBtn.addClass('clicked');
		$i1.delay(900);
		$i1.fadeTo(300, 0);
		$i2.delay(900);
		$i2.fadeTo(300, 1);		
	});

	$sendBtn.on(animationEvent(), e => {
		if (e.originalEvent.animationName == 'input-shadow') {
			$sendBtn.removeClass('clicked');
		}
	});

	$iWrapper.on(animationEvent(), e => {
		if (e.originalEvent.animationName == 'icon-animation') {
			$iWrapper.removeClass('icon-wrapper-animation');
			setTimeout(reset, 1200);
		}
	});

	function reset() {
		$i1.fadeTo(250, 1);
		$i2.fadeTo(250, 0);
		$iWrapper.css('color', '#f8bbd0');
	}
}); // end of document ready