#app
View Compiled
@use "sass:math";
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700");
$background-color: #2f2f2f;
$button-size: 4rem;
$transition-time: 96ms;
@mixin button() {
font-family: inherit;
width: 100%;
height: 100%;
border: 0;
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
box-sizing: border-box;
user-select: none;
}
#app {
font-family: "Open Sans", sans-serif;
background-color: $background-color;
width: 100vw;
height: 100vh;
padding: 2rem;
display: flex;
flex-wrap: nowrap;
overflow: auto;
box-sizing: border-box;
& > div {
margin: auto;
flex-shrink: 0;
}
}
.main-button {
width: $button-size;
height: $button-size;
position: relative;
}
.main-button-icon {
@include button();
background-color: #ff406f;
box-shadow: 0 0.3rem 1rem rgba(#000000, 0.4);
transition: background-color $transition-time ease-out;
&:before, &:after {
$width: $button-size * 0.55;
$height: $button-size * 0.1;
content: "";
background-color: #ffffff;
width: $width;
height: $height;
position: absolute;
top: ($button-size / 2) - ($height / 2);
left: ($button-size / 2) - ($width / 2);
border-radius: 10% / 50%;
transition:
background-color $transition-time ease-out,
border-radius $transition-time ease-out,
transform $transition-time ease-out;
}
&:after {
transform: rotate(90deg);
}
}
.main-button-active > .main-button-icon {
background-color: #dadada;
&:before, &:after {
background-color: $background-color;
border-radius: 0;
}
&:before {
transform: rotate(45deg);
}
&:after {
transform: rotate(135deg);
}
}
.sub-button {
--background-color: #000000;
@include button();
color: #ffffff;
background-color: var(--background-color);
display: flex;
justify-content: center;
align-items: center;
}
@for $i from 0 to 6 {
$distance: 150%;
$angle: (360 / 6) * $i;
$distance-x: $distance * math.cos($angle * math.$pi / 180);
$distance-y: $distance * math.sin($angle * math.$pi / 180);
.main-button-active > .sub-button:nth-child(#{$i + 1}):not(.sub-button-fading) {
$animation-time: 192ms;
animation:
show-sub-buttons-#{$i}
$animation-time
ease-out
(($animation-time / 6) * $i)
forwards;
@keyframes show-sub-buttons-#{$i} {
0% {
opacity: 0;
transform: translateX(0%) translateY(0%);
filter: blur(2px);
}
100% {
opacity: 1;
box-shadow: 0 0.3rem 1rem rgba(#000000, 0.4);
transform: translateX($distance-x) translateY($distance-y);
filter: blur(0);
}
}
}
.main-button-active > .sub-button.sub-button-fading:nth-child(#{$i + 1}) {
$animation-time: 192ms;
transform: translateX($distance-x) translateY($distance-y);
animation: fade-sub-buttons $animation-time ease-out forwards;
@keyframes fade-sub-buttons {
0% {
opacity: 1;
filter: blur(0);
}
100% {
opacity: 0;
filter: blur(2px);
}
}
}
}
.sub-button-text {
font-family: inherit;
font-size: 0.8rem;
position: absolute;
bottom: 0;
transform: translateY(125%);
}
.sub-button-icon {
color: $background-color;
}
View Compiled
import React, { useState, useEffect } from "https://cdn.skypack.dev/react@17.0.1";
import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
function MultiPurposeButton() {
const [activeState, setActiveState] = useState(false);
const [fadingState, setFadingState] = useState(false);
let SubButton = props => {
let icon = props.icon;
let text = props.text;
let backgroundColor = props.backgroundColor;
if (!activeState) {
return null;
}
let subButtonClassName = "sub-button";
if (fadingState) {
subButtonClassName += " sub-button-fading";
}
icon = "sub-button-icon " + icon;
return (
<button
className={subButtonClassName}
style={{"--background-color": backgroundColor}}
onAnimationEnd={evt => {
if (evt.animationName === "fade-sub-buttons") {
setActiveState(false);
setFadingState(false);
}
}}
>
<i className={icon}></i>
<span className="sub-button-text">{text}</span>
</button>
);
};
let buttonClassName = "main-button";
if (activeState) {
buttonClassName += " main-button-active";
}
return (
<div className={buttonClassName}>
<SubButton icon="far fa-file-audio fa-2x" text="AUDIO" backgroundColor="#b211c1" />
<SubButton icon="far fa-file-image fa-2x" text="IMAGE" backgroundColor="#ece82f" />
<SubButton icon="far fa-file-video fa-2x" text="VIDEO" backgroundColor="#1ccc3a" />
<SubButton icon="far fa-file-archive fa-2x" text="ARCHIVE" backgroundColor="#f87131" />
<SubButton icon="far fa-file-code fa-2x" text="CODE" backgroundColor="#e11117" />
<SubButton icon="far fa-file-alt fa-2x" text="FILE" backgroundColor="#045ee4" />
<div
className="main-button-icon"
onClick={evt => {
if (activeState) {
setFadingState(true);
} else {
setActiveState(true);
}
}}></div>
</div>
);
}
ReactDOM.render(
<MultiPurposeButton />,
document.querySelector("#app")
);
View Compiled
This Pen doesn't use any external JavaScript resources.