feat(ui): animate navigation and operation icons

This commit is contained in:
2026-09-12 21:31:57 +03:00
parent d3ac8c242d
commit 8e58c016d2
8 changed files with 764 additions and 54 deletions
+164 -28
View File
@@ -18,56 +18,192 @@
flex-shrink: 0;
}
.portfolioIcon {
color: var(--mantine-color-blue-7);
}
.cardsIcon {
color: var(--mantine-color-grape-7);
& svg {
overflow: visible;
}
}
.rubles {
pointer-events: none;
color: var(--mantine-color-green-8);
stroke: currentColor;
& path {
opacity: 0;
--flight-x: -7px;
--flight-rotation: -20deg;
--flight-delay: 0ms;
}
& path:nth-child(2) {
--flight-x: 0px;
--flight-rotation: 8deg;
--flight-delay: 120ms;
}
& path:nth-child(3) {
--flight-x: 7px;
--flight-rotation: 24deg;
--flight-delay: 240ms;
}
}
.stocksIcon {
color: var(--mantine-color-green-8);
}
.bondsIcon {
color: var(--mantine-color-orange-8);
}
.settingsIcon {
color: var(--mantine-color-gray-7);
}
.portfolioRuble {
stroke: var(--mantine-color-green-8);
opacity: 0;
}
.stockArrow {
transform-origin: 21px 5px;
}
.topSlider,
.bottomSlider {
fill: var(--mantine-color-body);
}
@media (prefers-reduced-motion: no-preference) {
.drawStroke {
.navLink {
transition: background-color 180ms ease-in-out;
}
.drawStroke,
.couponLines path {
stroke-dasharray: 1;
}
.topSlider {
--slider-offset: -3px;
--slider-offset: 3px;
--slider-delay: 0ms;
}
.bottomSlider {
--slider-offset: 3px;
--slider-offset: -3px;
--slider-delay: 160ms;
}
.navLink:focus-visible {
.portfolioIcon {
animation: portfolio-sway 650ms ease-in-out;
.couponLines path:nth-child(2) {
--line-delay: 140ms;
}
.couponLines path:nth-child(3) {
--line-delay: 280ms;
}
svg[data-icon-animating] {
.rubles path {
animation: ruble-fly 800ms ease-out var(--flight-delay) both;
}
.portfolioHandle {
animation: handle-lift 1200ms ease-in-out;
}
.portfolioLid {
animation: lid-open 1200ms ease-in-out;
}
.portfolioRuble {
animation: portfolio-ruble-reveal 1200ms ease-in-out;
}
.stockArrow {
animation: arrow-pop 300ms ease-out 400ms both;
}
.couponLines path {
animation: stroke-draw 300ms ease-out var(--line-delay, 0ms) both;
}
.drawStroke {
animation: stroke-draw 650ms ease-in-out;
animation: stroke-draw 450ms ease-out;
}
:is(.topSlider, .bottomSlider) {
animation: slider-slide 650ms ease-in-out;
}
}
@media (hover: hover) {
.navLink:hover {
.portfolioIcon {
animation: portfolio-sway 650ms ease-in-out;
}
.drawStroke {
animation: stroke-draw 650ms ease-in-out;
}
:is(.topSlider, .bottomSlider) {
animation: slider-slide 650ms ease-in-out;
}
animation: slider-slide 650ms ease-in-out var(--slider-delay) both;
}
}
}
@keyframes portfolio-sway {
@keyframes ruble-fly {
0% {
opacity: 0;
transform: translate(0, 4px);
}
20%,
50% {
opacity: 1;
}
100% {
opacity: 0;
transform: translate(var(--flight-x), -10px) rotate(var(--flight-rotation));
}
}
@keyframes handle-lift {
0%,
100% {
transform: rotate(0);
transform: translateY(0);
}
30% {
transform: translateY(-1px) rotate(-10deg);
20% {
transform: translateY(-3px);
}
65% {
transform: rotate(7deg);
40%,
75% {
transform: translateY(-3px);
}
}
@keyframes lid-open {
0%,
15%,
100% {
transform: translateY(0);
}
40%,
75% {
transform: translateY(-3px);
}
}
@keyframes portfolio-ruble-reveal {
0%,
25%,
100% {
opacity: 0;
transform: translateY(2px);
}
40%,
75% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes arrow-pop {
0% {
opacity: 0;
transform: scale(0.7);
}
60% {
opacity: 1;
transform: scale(1.2);
}
100% {
opacity: 1;
transform: scale(1);
}
}