Skip to content

Instantly share code, notes, and snippets.

@CodeMyUI CodeMyUI/index.html
Created Feb 7, 2020

Embed
What would you like to do?
Neuomorphic Fingerprint Scanner
<button class="button" type="button">
<span class="print print--under">
<svg viewBox="0 0 98 109" xmlns="http://www.w3.org/2000/svg">
<path d="m95.42 60.221c0.33333-4.6667 0.33333-10.667 0-18-0.5-11-8.5-26.5-24-34.5-15.5-8-38-9.5-55.5 8-11.667 11.667-16 25.5-13 41.5l0.65525 4.3683c0.38693 2.5791 2.7914 4.3563 5.3705 3.9695 2.5664-0.38496 4.3413-2.7687 3.9742-5.3378-1-7-6-22 10-38 14.554-14.554 38.15-14.554 52.704 0 4.5444 4.5444 7.8364 10.187 9.5562 16.379 0.5744 2.0681 0.98766 3.9417 1.2398 5.6209 2.4899 16.582-2.9979 37.051-6 53" pathLength="1"/>
<path d="m15.42 76.221c5.3333-3.6667 7.3333-10.167 6-19.5-0.23862-1.551-0.44877-3.0902-0.63044-4.6174-1.8313-15.395 9.1641-29.359 24.559-31.191 1.268-0.15084 2.5448-0.21497 3.8216-0.19197 15.616 0.28138 28.07 13.129 27.864 28.747-0.089675 6.8105-0.29443 11.895-0.61426 15.253-1.2042 12.644-2.9364 21.532-7 37" pathLength="1"/>
<path d="m19.92 85.221c7-5.3333 10.5-13.333 10.5-24v-12.5c0-10.217 8.2827-18.5 18.5-18.5 10.287 0 18.636 8.3235 18.666 18.611 0.019372 6.5699-0.035925 10.7-0.16589 12.389-1.5 19.5-3.5 31.5-12 45" pathLength="1"/>
<path d="m26.92 92.221c8.6667-9.3333 13-17.333 13-24 0-4.1832-0.18166-10.365-0.54497-18.544-0.2219-4.9954 3.6478-9.2249 8.6432-9.4467 0.13383-0.0059444 0.26778-0.0089177 0.40175-0.0089177 5.5235 0 10.044 4.395 10.2 9.9163 0.16256 5.764-0.070756 11.792-0.69994 18.084-1.5 15-5.5 25.5-16.5 38" pathLength="1"/>
<path d="m32.92 99.221c10.667-12.333 16-23.333 16-33v-17" pathLength="1"/>
</svg>
</span>
<span class="print print--over">
<svg viewBox="0 0 98 109" xmlns="http://www.w3.org/2000/svg">
<path d="m95.42 60.221c0.33333-4.6667 0.33333-10.667 0-18-0.5-11-8.5-26.5-24-34.5-15.5-8-38-9.5-55.5 8-11.667 11.667-16 25.5-13 41.5l0.65525 4.3683c0.38693 2.5791 2.7914 4.3563 5.3705 3.9695 2.5664-0.38496 4.3413-2.7687 3.9742-5.3378-1-7-6-22 10-38 14.554-14.554 38.15-14.554 52.704 0 4.5444 4.5444 7.8364 10.187 9.5562 16.379 0.5744 2.0681 0.98766 3.9417 1.2398 5.6209 2.4899 16.582-2.9979 37.051-6 53" pathLength="1"/>
<path d="m15.42 76.221c5.3333-3.6667 7.3333-10.167 6-19.5-0.23862-1.551-0.44877-3.0902-0.63044-4.6174-1.8313-15.395 9.1641-29.359 24.559-31.191 1.268-0.15084 2.5448-0.21497 3.8216-0.19197 15.616 0.28138 28.07 13.129 27.864 28.747-0.089675 6.8105-0.29443 11.895-0.61426 15.253-1.2042 12.644-2.9364 21.532-7 37" pathLength="1"/>
<path d="m19.92 85.221c7-5.3333 10.5-13.333 10.5-24v-12.5c0-10.217 8.2827-18.5 18.5-18.5 10.287 0 18.636 8.3235 18.666 18.611 0.019372 6.5699-0.035925 10.7-0.16589 12.389-1.5 19.5-3.5 31.5-12 45" pathLength="1"/>
<path d="m26.92 92.221c8.6667-9.3333 13-17.333 13-24 0-4.1832-0.18166-10.365-0.54497-18.544-0.2219-4.9954 3.6478-9.2249 8.6432-9.4467 0.13383-0.0059444 0.26778-0.0089177 0.40175-0.0089177 5.5235 0 10.044 4.395 10.2 9.9163 0.16256 5.764-0.070756 11.792-0.69994 18.084-1.5 15-5.5 25.5-16.5 38" pathLength="1"/>
<path d="m32.92 99.221c10.667-12.333 16-23.333 16-33v-17" pathLength="1"/>
</svg>
</span>
</button>
// Thanks to Voicu Apostol for the beaut inspo: https://dribbble.com/shots/9552931-3D-Fingerprint-Scanner 🔥❤️🙏
$size: 30vmin;
$baseColor: #d8dee8;
$accent: blue;
$ease: cubic-bezier(.33,.45,.3,1);
@mixin full($unit) {
position: absolute;
top: $unit;
right: $unit;
bottom: $unit;
left: $unit;
}
@function accent-from($i) {
@return adjust-hue(lighten($accent, 10), -35deg + (2deg * (5 - $i)));
}
@function accent-to($i) {
@return adjust-hue($accent, 10deg + (4deg * ($i - 1)));
}
$accentTo: rgba(accent-to(5), .66);
$baseColor:
if(
lightness($baseColor) > 80,
$baseColor,
lighten($baseColor, 80 - lightness($baseColor))
);
body {
position: absolute;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background: $baseColor;
&:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(150% 150% at 0% 20%, lighten($baseColor, 0) 20%, darken($baseColor, 30));
}
}
.button {
appearance: none;
border: none;
outline: none;
padding: 0;
border: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
position: relative;
font-size: $size;
width: 1em;
height: 1em;
opacity: 0;
animation: buttonIn 2s $ease forwards 2s;
@keyframes buttonIn {
from {
opacity: 0;
transform: scale3d(1.1,1.15,1);
}
to {
opacity: 1;
transform: none;
}
}
background: none;
border-radius: 50%;
&:before,
&:after {
content: '';
border-radius: inherit;
}
&:before {
filter: blur(.025em);
@include full(0);
// $baseColor: red;
background:
radial-gradient(160% 160% at 57.5% 60%, rgba(lighten($baseColor, 6), 0) 30%, lighten($baseColor, 6) 45%), // light top left
radial-gradient(180% 200% at 40% 17.5%, rgba(darken($baseColor, 20), 0) 35%, darken($baseColor,20) 50%), // dark bottom right
radial-gradient(120% 120% at 45% 45%, rgba(darken($baseColor, 10), 0) 42%, rgba(darken($baseColor,20),.75) 50%), // darker small bottom right
;
background-color: darken($baseColor,8.66);
box-shadow:
inset -.05em -.05em .025em -.025em darken($baseColor,15),
.115em .15em .1em -.033em darken(adjust-hue($baseColor,-2.5deg), 20), // dark close
.15em .2em .25em darken($baseColor, 15), // dark far
.5em .33em .5em .1em darken($baseColor, 15), // dark furthest
-.1em -.1em .05em -.075em lighten($baseColor, 2), // light close
-.2em -.2em .33em -.075em lighten($baseColor, .5), // light far
;
}
&:after {
@include full(.025em);
background:
radial-gradient(150% 150% at 75% 75%, rgba(darken($baseColor, 30),0) 30%, darken($baseColor, 30)), // dark top left
radial-gradient(150% 150% at -10% -10%, rgba(lighten($baseColor, 3),0) 50%, lighten($baseColor, 3)) // light bottom left
;
background-color: darken($baseColor, 10);
transition: .75s $ease;
transition-delay: .25s;
opacity: 0;
filter: blur(.03em);
transform: scale3d(.925,.94,1);
}
}
.print {
$size: 40%;
position: relative;
width: $size;
height: 0;
padding-bottom: $size * 1.1122;
display: inline-block;
z-index: 1;
transform: scale3d(1.05, 1.05, 1);
backface-visiblity: hidden;
color: rgba(accent-from(5), .5);
svg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
path {
stroke-width: 4;
fill: none;
stroke-linecap: round;
stroke-dasharray: 1;
transition: 2s $ease;
will-change: stroke-dashoffset, stroke, color, opacity;
}
$glow: lighten($accent, 85 - lightness($accent));
&--under {
margin-right: -40%;
mix-blend-mode: lighten;
filter: drop-shadow(0 0 .033em currentColor);
// opacity: 0;
stroke-dashoffset: .5;
transition: 2s $ease;
animation: printPulse 2s linear infinite 6.25s;
@keyframes printPulse {
0% { opacity: 1 }
50% { opacity: .33 }
100% { opacity: 1 }
}
path {
opacity: 0;
animation: printIn 2s $ease forwards 3.2s;
@keyframes printIn {
from {
opacity: 0;
stroke-dashoffset: .5;
}
to {
opacity: 1;
stroke-dashoffset: 0;
}
}
@for $i from 1 through 5 {
&:nth-of-type(#{$i}) {
stroke: lighten(accent-from($i), 22.5);
}
}
}
}
&--over {
filter:
drop-shadow(-0.0075em -0.0075em 0.005em rgba(0, 0, 51, 0.1)) // dark bevel
drop-shadow(0.0075em 0.0075em 0.005em rgba(255, 255, 255,.25)) // light bevel
drop-shadow(0 0 0.04em currentColor) // glow
;
opacity: 0;
transition:
transform 2s $ease,
color 0s .4s,
opacity .5s $ease,
;
&:after {
content: '';
position: absolute;
top: -40%;
right: -60%;
bottom: -40%;
left: -60%;
border-radius: 50%;
opacity: 0;
background:
// radial-gradient(32.5% 32.5% at 52.5% 52.5%, rgba(darken($accentTo, 45), .05), rgba(darken($accentTo, 15), 0)),
radial-gradient(32.5% 32.5% at 42.5% 42.5%, rgba(white, .55), rgba(white, 0)),
;
mix-blend-mode: color-dodge;
transition: opacity .3s $ease;
animation:
glowPulse 3s linear infinite,
glowTwist 3s linear infinite
;
@keyframes glowPulse {
0% { transform: scale3d(.9,.9,1) }
50% { transform: scale3d(1,1,1) }
100% { transform: scale3d(.9,.9,1) }
}
@keyframes glowTwist {
0% { rotate: 0deg }
50% { rotate: 180deg }
100% { rotate: 360deg }
}
}
path {
opacity: 0;
stroke-dashoffset: 1;
transition:
stroke .5s $ease,
opacity 0s .5s,
stroke-dashoffset 0s .5s
;
@for $i from 1 through 5 {
&:nth-of-type(#{$i}) {
stroke: accent-from($i);
}
}
}
}
}
.button:hover,
.button.test {
&.test {
animation: none;
opacity: 1;
transform: none;
font-size: 60vmin;
}
&:after {
opacity: 1;
transform: none;
transition-delay: 0s;
}
.print {
transform: scale3d(1,1,1) translateZ(0);
&--over {
color: $accentTo;
opacity: .66;
transition:
1.5s $ease 4.5s,
opacity .25s $ease,
transform 2s $ease,
;
&:after {
// opacity: 1;
transition: opacity 2s $ease 5.25s;
}
path {
opacity: 1;
stroke-dashoffset: 0;
@for $i from 1 through 5 {
&:nth-of-type(#{$i}) {
$delay: .25s + (.1s * $i);
stroke: accent-to($i);
transition:
opacity .25s $ease $delay,
stroke-dashoffset 4s + (.2s * $i) $ease $delay,
stroke 1s + (.2s * $i) $ease 1.75s + (.1s * (5 - $i)) + 2.5,
color 1s + (.2s * $i) $ease 1.75s + (.1s * (5 - $i)) + 2.5
;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.