feat: add smooth slide-out animation for mobile panel closing

Added matching slide-out animation when closing the mobile panel to
match the smooth slide-in animation on opening:

CSS changes (style.css):
- Add .rpg-mobile-closing class with rpgSlideOutToRight animation
- Create @keyframes rpgSlideOutToRight (0.3s ease-in-out)
- Panel slides smoothly off-screen to right before hiding

JavaScript changes (index.js):
- Add closeMobilePanelWithAnimation() helper function
- Use animationend event to wait for animation before hiding
- Replace all instant removeClass() calls with helper function
- Maintains smooth 0.3s animation timing matching slide-in

Implementation details:
- Helper function adds .rpg-mobile-closing class
- Waits for CSS animation to complete via animationend event
- Then removes closing class and overlay
- All close operations now use this helper for consistency

Result: Panel now smoothly slides in AND out with matching 0.3s
animations. No more jarring instant disappearance on close.
This commit is contained in:
Lucas 'Paperboy' Rose-Winters
2025-10-16 12:33:07 +11:00
parent a6bc021148
commit 3d32a04d57
2 changed files with 46 additions and 24 deletions
+29 -24
View File
@@ -985,6 +985,24 @@ function setupSettingsPopup() {
}); });
} }
/**
* Helper function to close the mobile panel with animation.
*/
function closeMobilePanelWithAnimation() {
const $panel = $('#rpg-companion-panel');
const $mobileToggle = $('#rpg-mobile-toggle');
// Add closing class to trigger slide-out animation
$panel.removeClass('rpg-mobile-open').addClass('rpg-mobile-closing');
$mobileToggle.removeClass('active');
// Wait for animation to complete before hiding
$panel.one('animationend', function() {
$panel.removeClass('rpg-mobile-closing');
$('.rpg-mobile-overlay').remove();
});
}
/** /**
* Sets up the mobile toggle button (FAB). * Sets up the mobile toggle button (FAB).
*/ */
@@ -1246,10 +1264,8 @@ function setupMobileToggle() {
console.log('[RPG Mobile] Quick tap detected - toggling panel'); console.log('[RPG Mobile] Quick tap detected - toggling panel');
if ($panel.hasClass('rpg-mobile-open')) { if ($panel.hasClass('rpg-mobile-open')) {
// Close panel // Close panel with animation
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$overlay.remove();
$mobileToggle.removeClass('active');
} else { } else {
// Open panel // Open panel
$panel.addClass('rpg-mobile-open'); $panel.addClass('rpg-mobile-open');
@@ -1258,9 +1274,7 @@ function setupMobileToggle() {
// Close when clicking overlay // Close when clicking overlay
$overlay.on('click', function() { $overlay.on('click', function() {
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$overlay.remove();
$mobileToggle.removeClass('active');
}); });
} }
} }
@@ -1283,9 +1297,7 @@ function setupMobileToggle() {
// Work on both mobile and desktop (removed viewport check) // Work on both mobile and desktop (removed viewport check)
if ($panel.hasClass('rpg-mobile-open')) { if ($panel.hasClass('rpg-mobile-open')) {
console.log('[RPG Mobile] Click: Closing panel'); console.log('[RPG Mobile] Click: Closing panel');
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$overlay.remove();
$mobileToggle.removeClass('active');
} else { } else {
console.log('[RPG Mobile] Click: Opening panel'); console.log('[RPG Mobile] Click: Opening panel');
$panel.addClass('rpg-mobile-open'); $panel.addClass('rpg-mobile-open');
@@ -1294,9 +1306,7 @@ function setupMobileToggle() {
$overlay.on('click', function() { $overlay.on('click', function() {
console.log('[RPG Mobile] Overlay clicked - closing panel'); console.log('[RPG Mobile] Overlay clicked - closing panel');
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$overlay.remove();
$mobileToggle.removeClass('active');
}); });
} }
}); });
@@ -1322,10 +1332,8 @@ function setupMobileToggle() {
// Clear collapsed state - mobile doesn't use collapse // Clear collapsed state - mobile doesn't use collapse
$panel.removeClass('rpg-collapsed'); $panel.removeClass('rpg-collapsed');
// Close panel on mobile - CSS handles smooth transition // Close panel on mobile with animation
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$mobileToggle.removeClass('active');
$('.rpg-mobile-overlay').remove();
// Clear any inline styles that might be overriding CSS // Clear any inline styles that might be overriding CSS
$panel.attr('style', ''); $panel.attr('style', '');
@@ -1360,7 +1368,7 @@ function setupMobileToggle() {
// Disable transitions to prevent left→right slide animation // Disable transitions to prevent left→right slide animation
$panel.css('transition', 'none'); $panel.css('transition', 'none');
$panel.removeClass('rpg-mobile-open'); $panel.removeClass('rpg-mobile-open rpg-mobile-closing');
$mobileToggle.removeClass('active'); $mobileToggle.removeClass('active');
$('.rpg-mobile-overlay').remove(); $('.rpg-mobile-overlay').remove();
@@ -1646,11 +1654,9 @@ function setupCollapseToggle() {
}); });
if (isOpen) { if (isOpen) {
// Close panel // Close panel with animation
console.log('[RPG Mobile] Closing panel'); console.log('[RPG Mobile] Closing panel');
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$('.rpg-mobile-overlay').remove();
$('#rpg-mobile-toggle').removeClass('active');
} else { } else {
// Open panel // Open panel
console.log('[RPG Mobile] Opening panel'); console.log('[RPG Mobile] Opening panel');
@@ -1673,8 +1679,7 @@ function setupCollapseToggle() {
// Close when clicking overlay // Close when clicking overlay
$overlay.on('click', function() { $overlay.on('click', function() {
console.log('[RPG Mobile] Overlay clicked - closing panel'); console.log('[RPG Mobile] Overlay clicked - closing panel');
$panel.removeClass('rpg-mobile-open'); closeMobilePanelWithAnimation();
$overlay.remove();
updateCollapseToggleIcon(); updateCollapseToggleIcon();
}); });
} }
+17
View File
@@ -3057,6 +3057,13 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
animation: rpgSlideInFromRight 0.3s ease-in-out; animation: rpgSlideInFromRight 0.3s ease-in-out;
} }
/* Closing animation - slide out to right */
.rpg-panel.rpg-mobile-closing {
display: block !important;
z-index: 50;
animation: rpgSlideOutToRight 0.3s ease-in-out;
}
/* Slide-in animation from right */ /* Slide-in animation from right */
@keyframes rpgSlideInFromRight { @keyframes rpgSlideInFromRight {
from { from {
@@ -3067,6 +3074,16 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
} }
/* Slide-out animation to right */
@keyframes rpgSlideOutToRight {
from {
transform: translateX(0);
}
to {
transform: translateX(100%);
}
}
/* Disable collapsed state on mobile */ /* Disable collapsed state on mobile */
.rpg-panel.rpg-collapsed { .rpg-panel.rpg-collapsed {
max-width: 100dvw !important; max-width: 100dvw !important;