Smooth held card transition and scale font with card size
Remove scale(1.15) size jump on held card, keep gold border/glow highlight. Set animation card font-size proportionally to card width so text matches across deck, hand, and opponent card sizes. Animate font-size during swaps so text scales smoothly as cards travel between different-sized positions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bfa94830a7
commit
c59c1e28e2
@ -3107,10 +3107,8 @@ class GolfGame {
|
|||||||
this.heldCardFloating.style.height = `${cardHeight}px`;
|
this.heldCardFloating.style.height = `${cardHeight}px`;
|
||||||
|
|
||||||
// Position discard button attached to right side of held card
|
// Position discard button attached to right side of held card
|
||||||
const scaledWidth = cardWidth * 1.15; // Account for scale transform
|
const buttonLeft = cardLeft + cardWidth; // Right edge of card (no gap)
|
||||||
const scaledHeight = cardHeight * 1.15;
|
const buttonTop = cardTop + cardHeight * 0.3; // Vertically centered on card
|
||||||
const buttonLeft = cardLeft + scaledWidth / 2 + cardWidth / 2; // Right edge of scaled card (no gap)
|
|
||||||
const buttonTop = cardTop + (scaledHeight - cardHeight) / 2 + cardHeight * 0.3; // Vertically centered on card
|
|
||||||
this.discardBtn.style.left = `${buttonLeft}px`;
|
this.discardBtn.style.left = `${buttonLeft}px`;
|
||||||
this.discardBtn.style.top = `${buttonTop}px`;
|
this.discardBtn.style.top = `${buttonTop}px`;
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,9 @@ class CardAnimations {
|
|||||||
card.style.top = rect.top + 'px';
|
card.style.top = rect.top + 'px';
|
||||||
card.style.width = rect.width + 'px';
|
card.style.width = rect.width + 'px';
|
||||||
card.style.height = rect.height + 'px';
|
card.style.height = rect.height + 'px';
|
||||||
|
// Scale font-size proportionally to card width
|
||||||
|
const front = card.querySelector('.draw-anim-front');
|
||||||
|
if (front) front.style.fontSize = (rect.width * 0.5) + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply deck color to back
|
// Apply deck color to back
|
||||||
@ -448,10 +451,6 @@ class CardAnimations {
|
|||||||
const deckColor = this.getDeckColor();
|
const deckColor = this.getDeckColor();
|
||||||
|
|
||||||
const animCard = this.createAnimCard(rect, true, deckColor);
|
const animCard = this.createAnimCard(rect, true, deckColor);
|
||||||
// Match source card's font-size (opponent cards are smaller than default)
|
|
||||||
const srcFontSize = getComputedStyle(cardElement).fontSize;
|
|
||||||
const front = animCard.querySelector('.draw-anim-front');
|
|
||||||
if (front) front.style.fontSize = srcFontSize;
|
|
||||||
this.setCardContent(animCard, cardData);
|
this.setCardContent(animCard, cardData);
|
||||||
|
|
||||||
// Apply rotation to match arch layout
|
// Apply rotation to match arch layout
|
||||||
@ -607,10 +606,6 @@ class CardAnimations {
|
|||||||
const deckColor = this.getDeckColor();
|
const deckColor = this.getDeckColor();
|
||||||
|
|
||||||
const animCard = this.createAnimCard(rect, true, deckColor);
|
const animCard = this.createAnimCard(rect, true, deckColor);
|
||||||
// Match source card's font-size (opponent cards are smaller than default)
|
|
||||||
const srcFontSize = getComputedStyle(sourceCardElement).fontSize;
|
|
||||||
const front = animCard.querySelector('.draw-anim-front');
|
|
||||||
if (front) front.style.fontSize = srcFontSize;
|
|
||||||
this.setCardContent(animCard, discardCard);
|
this.setCardContent(animCard, discardCard);
|
||||||
|
|
||||||
if (rotation) {
|
if (rotation) {
|
||||||
@ -1164,6 +1159,9 @@ class CardAnimations {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Hand card arcs to discard (apply counter-rotation to land flat)
|
// Hand card arcs to discard (apply counter-rotation to land flat)
|
||||||
|
const handFront = travelingHand.querySelector('.draw-anim-front');
|
||||||
|
const heldFront = travelingHeld.querySelector('.draw-anim-front');
|
||||||
|
|
||||||
timeline.add({
|
timeline.add({
|
||||||
targets: travelingHand,
|
targets: travelingHand,
|
||||||
left: discardRect.left,
|
left: discardRect.left,
|
||||||
@ -1178,6 +1176,16 @@ class CardAnimations {
|
|||||||
easing: this.getEasing('arc'),
|
easing: this.getEasing('arc'),
|
||||||
}, `-=${T.lift / 2}`);
|
}, `-=${T.lift / 2}`);
|
||||||
|
|
||||||
|
// Scale hand card font to match discard size
|
||||||
|
if (handFront) {
|
||||||
|
timeline.add({
|
||||||
|
targets: handFront,
|
||||||
|
fontSize: (discardRect.width * 0.5) + 'px',
|
||||||
|
duration: T.arc,
|
||||||
|
easing: this.getEasing('arc'),
|
||||||
|
}, `-=${T.arc}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Held card arcs to hand slot (apply rotation to match hand position)
|
// Held card arcs to hand slot (apply rotation to match hand position)
|
||||||
timeline.add({
|
timeline.add({
|
||||||
targets: travelingHeld,
|
targets: travelingHeld,
|
||||||
@ -1193,6 +1201,16 @@ class CardAnimations {
|
|||||||
easing: this.getEasing('arc'),
|
easing: this.getEasing('arc'),
|
||||||
}, `-=${T.arc + T.lift / 2}`);
|
}, `-=${T.arc + T.lift / 2}`);
|
||||||
|
|
||||||
|
// Scale held card font to match hand size
|
||||||
|
if (heldFront) {
|
||||||
|
timeline.add({
|
||||||
|
targets: heldFront,
|
||||||
|
fontSize: (handRect.width * 0.5) + 'px',
|
||||||
|
duration: T.arc,
|
||||||
|
easing: this.getEasing('arc'),
|
||||||
|
}, `-=${T.arc}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Settle with gentle overshoot
|
// Settle with gentle overshoot
|
||||||
timeline.add({
|
timeline.add({
|
||||||
targets: [travelingHand, travelingHeld],
|
targets: [travelingHand, travelingHeld],
|
||||||
@ -1404,6 +1422,9 @@ class CardAnimations {
|
|||||||
card.style.top = rect.top + 'px';
|
card.style.top = rect.top + 'px';
|
||||||
card.style.width = rect.width + 'px';
|
card.style.width = rect.width + 'px';
|
||||||
card.style.height = rect.height + 'px';
|
card.style.height = rect.height + 'px';
|
||||||
|
// Scale font-size proportionally to card width
|
||||||
|
const front = card.querySelector('.draw-anim-front');
|
||||||
|
if (front) front.style.fontSize = (rect.width * 0.5) + 'px';
|
||||||
|
|
||||||
if (rotation) {
|
if (rotation) {
|
||||||
card.style.transform = `rotate(${rotation}deg)`;
|
card.style.transform = `rotate(${rotation}deg)`;
|
||||||
@ -1444,9 +1465,8 @@ class CardAnimations {
|
|||||||
try {
|
try {
|
||||||
anime({
|
anime({
|
||||||
targets: element,
|
targets: element,
|
||||||
scale: [0.5, 1.25, 1.15],
|
opacity: [0, 1],
|
||||||
opacity: [0, 1, 1],
|
duration: 200,
|
||||||
duration: 300,
|
|
||||||
easing: 'easeOutQuad'
|
easing: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@ -1156,10 +1156,8 @@ input::placeholder {
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
transform: scale(1.15);
|
|
||||||
transform-origin: center bottom;
|
|
||||||
border: 3px solid #f4a460 !important;
|
border: 3px solid #f4a460 !important;
|
||||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5), 0 0 25px rgba(244, 164, 96, 0.7) !important;
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 20px rgba(244, 164, 96, 0.6) !important;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
/* No transition - anime.js handles animations */
|
/* No transition - anime.js handles animations */
|
||||||
}
|
}
|
||||||
@ -1523,11 +1521,11 @@ input::placeholder {
|
|||||||
|
|
||||||
@keyframes heldCardPulse {
|
@keyframes heldCardPulse {
|
||||||
0%, 100% {
|
0%, 100% {
|
||||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5), 0 0 25px rgba(244, 164, 96, 0.7);
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 20px rgba(244, 164, 96, 0.6);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5), 0 0 35px rgba(244, 164, 96, 1),
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 30px rgba(244, 164, 96, 0.9),
|
||||||
0 0 50px rgba(244, 164, 96, 0.5);
|
0 0 45px rgba(244, 164, 96, 0.4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user