feat: add puzzle clear template runtime

This commit is contained in:
2026-06-03 22:11:46 +08:00
parent 6e74cf5add
commit 1b5e098225
148 changed files with 19588 additions and 241 deletions

View File

@@ -161,6 +161,345 @@ body {
animation: puzzle-clear-flash-sweep 0.9s ease-out forwards;
}
@keyframes puzzle-clear-card-opening-flip {
0% {
opacity: 0;
transform: perspective(760px) rotateY(180deg) translateY(-8%);
}
56% {
opacity: 1;
transform: perspective(760px) rotateY(-10deg) translateY(0);
}
100% {
opacity: 1;
transform: perspective(760px) rotateY(0deg) translateY(0);
}
}
@keyframes puzzle-clear-ready-drop {
0% {
opacity: 0;
transform: translateY(-42%) scale(0.94);
}
72% {
opacity: 1;
transform: translateY(4%) scale(1);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes puzzle-clear-card-clear-pop {
0% {
opacity: 1;
transform: scale(1);
filter: saturate(1);
}
48% {
opacity: 1;
transform: scale(1.05);
filter: saturate(1.24) brightness(1.05);
}
100% {
opacity: 0.72;
transform: scale(0.92);
filter: saturate(0.82);
}
}
@keyframes puzzle-clear-transition-clear-pop {
0% {
opacity: 0;
transform: scale(0.68);
filter: saturate(1.06) brightness(1.04);
}
32% {
opacity: 1;
transform: scale(1.06);
filter: saturate(1.14) brightness(1.06);
}
100% {
opacity: 0;
transform: scale(0.84);
filter: saturate(0.92) brightness(1);
}
}
@keyframes puzzle-clear-transition-drop {
0% {
opacity: 0;
transform: translateY(var(--puzzle-clear-drop-start-y, -120%)) scale(0.96);
filter: saturate(1.08) brightness(1.03);
}
55% {
opacity: 1;
transform: translateY(10%) scale(1.02);
filter: saturate(1.03) brightness(1.01);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
filter: saturate(1) brightness(1);
}
}
.puzzle-clear-card {
touch-action: none;
transform-style: preserve-3d;
user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
}
.puzzle-clear-card img,
.puzzle-clear-ready-card {
user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
}
.puzzle-clear-card--opening {
animation: puzzle-clear-card-opening-flip 520ms
calc(var(--puzzle-clear-card-index, 0) * 24ms) cubic-bezier(0.2, 0.72, 0.2, 1)
both;
}
.puzzle-clear-card--locked-group-cell {
background: rgba(255, 255, 255, 0.34);
border-color: rgba(255, 255, 255, 0.28);
box-shadow: none;
}
.puzzle-clear-card--locked-group-cell > span:first-child {
opacity: 0.18;
}
.puzzle-clear-card--cleared {
animation: puzzle-clear-card-clear-pop 460ms ease-out both;
}
.puzzle-clear-card--transition-hidden {
opacity: 0;
}
.puzzle-clear-card--ghost-origin {
opacity: 0.42;
filter: saturate(0.82);
}
.puzzle-clear-card--drag-group-empty {
background: transparent;
border-color: rgba(255, 255, 255, 0.18);
box-shadow: none;
}
.puzzle-clear-card--drag-group-empty > span:first-child {
opacity: 0;
}
.puzzle-clear-card--drag-origin-empty {
background: transparent;
border-color: rgba(255, 255, 255, 0.26);
box-shadow: none;
}
.puzzle-clear-card--drag-origin-empty > span:first-child {
opacity: 0;
}
.puzzle-clear-card--swap-feedback {
animation: puzzle-clear-card-swap-feedback 240ms ease-out both;
}
.puzzle-clear-ready-card {
animation: puzzle-clear-ready-drop 430ms cubic-bezier(0.2, 0.72, 0.2, 1) both;
}
.puzzle-clear-drag-ghost {
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.88);
border-radius: 0.6rem;
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.18);
background: white;
}
.puzzle-clear-swap-flight {
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.88);
border-radius: 0.6rem;
background: white;
box-shadow: 0 14px 34px rgba(15, 23, 42, 0.18);
}
.puzzle-clear-swap-flight--incoming {
animation: puzzle-clear-swap-flight-incoming 220ms
cubic-bezier(0.2, 0.82, 0.22, 1) both;
}
.puzzle-clear-locked-group-visual {
animation: puzzle-clear-locked-group-settle 180ms ease-out both;
}
.puzzle-clear-locked-group-visual--merge {
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.5),
0 14px 26px rgba(15, 23, 42, 0.12);
}
.puzzle-clear-locked-group-visual img {
user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
}
.puzzle-clear-drag-ghost--dragging {
cursor: grabbing;
}
.puzzle-clear-drag-ghost--dropping {
animation: puzzle-clear-drag-ghost-drop 180ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.puzzle-clear-drag-ghost--returning {
animation: puzzle-clear-drag-ghost-return 140ms ease-out both;
}
.puzzle-clear-drag-group {
background: rgba(255, 255, 255, 0.04);
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.28),
0 16px 32px rgba(15, 23, 42, 0.12);
user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
pointer-events: none;
}
.puzzle-clear-transition-piece {
pointer-events: none;
overflow: hidden;
}
.puzzle-clear-transition-piece--clear {
animation: puzzle-clear-transition-clear-pop 340ms ease-out both;
}
.puzzle-clear-transition-piece--drop {
animation: puzzle-clear-transition-drop 420ms cubic-bezier(0.18, 0.82, 0.24, 1)
both;
animation-delay: var(--puzzle-clear-drop-delay, 0ms);
}
@keyframes puzzle-clear-card-swap-feedback {
0% {
transform: scale(0.98);
opacity: 0.92;
}
50% {
transform: scale(1.02);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes puzzle-clear-swap-flight-incoming {
0% {
transform: translate3d(0, 0, 0) scale(1.02);
opacity: 0.98;
filter: saturate(1.03);
}
60% {
transform: translate3d(
calc(var(--puzzle-clear-flight-delta-x, 0) * 0.82),
calc(var(--puzzle-clear-flight-delta-y, 0) * 0.82),
0
)
scale(1.005);
opacity: 0.98;
filter: saturate(1.01);
}
100% {
transform: translate3d(
var(--puzzle-clear-flight-delta-x, 0),
var(--puzzle-clear-flight-delta-y, 0),
0
)
scale(1);
opacity: 0.92;
filter: saturate(1);
}
}
@keyframes puzzle-clear-locked-group-settle {
0% {
transform: scale(0.992);
opacity: 0.88;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes puzzle-clear-drag-ghost-drop {
0% {
opacity: 0.98;
filter: saturate(1.02);
}
100% {
opacity: 0.8;
filter: saturate(0.94);
}
}
@keyframes puzzle-clear-drag-ghost-return {
0% {
opacity: 0.9;
filter: saturate(1.02);
}
100% {
opacity: 0;
filter: saturate(0.9);
}
}
@media (prefers-reduced-motion: reduce) {
.puzzle-clear-card--opening,
.puzzle-clear-card--cleared,
.puzzle-clear-ready-card,
.puzzle-clear-card--swap-feedback,
.puzzle-clear-swap-flight--incoming,
.puzzle-clear-locked-group-visual,
.puzzle-clear-drag-ghost--dropping,
.puzzle-clear-drag-ghost--returning,
.puzzle-clear-transition-piece--clear,
.puzzle-clear-transition-piece--drop {
animation: none;
}
}
@keyframes puzzle-merge-center-flash {
0% {
transform: translate(-50%, -50%) scale(0.34) rotate(0deg);