mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Add new skill for creating performant CSS animations: - Native @keyframes animations with GPU acceleration - Angular animate.enter/leave for modern view transitions - Performance guidelines and best practices - Reference guide for common animation patterns
279 lines
4.9 KiB
CSS
279 lines
4.9 KiB
CSS
/**
|
|
* Reusable CSS @keyframes Animations
|
|
*
|
|
* Common animation patterns for Angular applications.
|
|
* Import this file in your component styles or global styles.
|
|
*/
|
|
|
|
/* ============================================
|
|
FADE ANIMATIONS
|
|
============================================ */
|
|
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
@keyframes fadeOut {
|
|
from { opacity: 1; }
|
|
to { opacity: 0; }
|
|
}
|
|
|
|
.fade-in {
|
|
animation: fadeIn 0.3s ease-out;
|
|
}
|
|
|
|
.fade-out {
|
|
animation: fadeOut 0.3s ease-in;
|
|
}
|
|
|
|
/* ============================================
|
|
SLIDE ANIMATIONS
|
|
============================================ */
|
|
|
|
@keyframes slideInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes slideOutDown {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
}
|
|
|
|
@keyframes slideInDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes slideOutUp {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
}
|
|
|
|
@keyframes slideInLeft {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@keyframes slideOutLeft {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateX(-20px);
|
|
}
|
|
}
|
|
|
|
@keyframes slideInRight {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@keyframes slideOutRight {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateX(20px);
|
|
}
|
|
}
|
|
|
|
.slide-in-up { animation: slideInUp 0.3s ease-out; }
|
|
.slide-out-down { animation: slideOutDown 0.3s ease-in; }
|
|
.slide-in-down { animation: slideInDown 0.3s ease-out; }
|
|
.slide-out-up { animation: slideOutUp 0.3s ease-in; }
|
|
.slide-in-left { animation: slideInLeft 0.3s ease-out; }
|
|
.slide-out-left { animation: slideOutLeft 0.3s ease-in; }
|
|
.slide-in-right { animation: slideInRight 0.3s ease-out; }
|
|
.slide-out-right { animation: slideOutRight 0.3s ease-in; }
|
|
|
|
/* ============================================
|
|
SCALE ANIMATIONS
|
|
============================================ */
|
|
|
|
@keyframes scaleIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes scaleOut {
|
|
from {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
}
|
|
|
|
.scale-in { animation: scaleIn 0.2s ease-out; }
|
|
.scale-out { animation: scaleOut 0.2s ease-in; }
|
|
|
|
/* ============================================
|
|
UTILITY ANIMATIONS
|
|
============================================ */
|
|
|
|
/* Loading Spinner */
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
.spin {
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
/* Skeleton Loading */
|
|
@keyframes shimmer {
|
|
0% { background-position: -200% 0; }
|
|
100% { background-position: 200% 0; }
|
|
}
|
|
|
|
.shimmer {
|
|
background: linear-gradient(
|
|
90deg,
|
|
#f0f0f0 25%,
|
|
#e0e0e0 50%,
|
|
#f0f0f0 75%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: shimmer 1.5s infinite;
|
|
}
|
|
|
|
/* Attention Pulse */
|
|
@keyframes attention-pulse {
|
|
0%, 100% {
|
|
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5);
|
|
}
|
|
50% {
|
|
box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
|
|
}
|
|
}
|
|
|
|
.attention-pulse {
|
|
animation: attention-pulse 2s ease-in-out infinite;
|
|
}
|
|
|
|
/* Shake (Error Feedback) */
|
|
@keyframes shake {
|
|
0%, 100% { transform: translateX(0); }
|
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
|
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
|
}
|
|
|
|
.shake {
|
|
animation: shake 0.5s ease-in-out;
|
|
}
|
|
|
|
/* Breathing/Pulsing */
|
|
@keyframes breathe {
|
|
0%, 100% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 0.7;
|
|
transform: scale(1.05);
|
|
}
|
|
}
|
|
|
|
.breathe {
|
|
animation: breathe 2s ease-in-out infinite;
|
|
}
|
|
|
|
/* ============================================
|
|
TOAST/NOTIFICATION ANIMATIONS
|
|
============================================ */
|
|
|
|
@keyframes toastIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(100%) scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes toastOut {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(100%) scale(0.9);
|
|
}
|
|
}
|
|
|
|
.toast-in {
|
|
animation: toastIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
}
|
|
|
|
.toast-out {
|
|
animation: toastOut 0.2s ease-in forwards;
|
|
}
|
|
|
|
/* ============================================
|
|
ACCESSIBILITY
|
|
============================================ */
|
|
|
|
/* Respect user's motion preferences */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
}
|
|
}
|