Pure CSS drawer animations

8c384a03bbdf262cd21920466f06238db7388abf

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +24 -98Showing whitespace changes
public/script.js+8 -96
@@ -10317,68 +10317,19 @@ function doDrawerOpenClick() {
10317 doNavbarIconClick.call(drawerToggle);10317 doNavbarIconClick.call(drawerToggle);
10318}10318}
1031910319
10320
10321// Helper for animating open/close (opacity only)
10322async function animateDrawer($el, open, displayStyle = 'block', onEnd) {
10323 //const slideOptions = getSlideToggleOptions();
10324 const duration = 250;
10325 const easing = 'swing';
10326 $el.stop(true, true);
10327
10328 if (open) {
10329 $el.css({ display: displayStyle, opacity: 0 });
10330 $el.animate(
10331 { opacity: 1 },
10332 {
10333 duration,
10334 easing,
10335 complete: function () {
10336 $el.css({ opacity: '', display: displayStyle });
10337 if (typeof onEnd === 'function') onEnd(this);
10338 },
10339 },
10340 );
10341 } else {
10342 $el.animate(
10343 { opacity: 0 },
10344 {
10345 duration,
10346 easing,
10347 complete: function () {
10348 $el.css({ display: 'none', opacity: '0' });
10349 if (typeof onEnd === 'function') onEnd(this);
10350 },
10351 },
10352 );
10353 }
10354}
10355
10356/**10320/**
10357 * Event handler to open or close a navbar drawer when a navbar icon is clicked.10321 * Event handler to open or close a navbar drawer when a navbar icon is clicked.
10358 * Handles click events on .drawer-toggle elements.10322 * Handles click events on .drawer-toggle elements.
10359 * @returns {void}10323 * @returns {Promise<void>}
10360 */10324 */
10361// ...existing code...
10362export async function doNavbarIconClick() {10325export async function doNavbarIconClick() {
10363 //console.warn('called for, ', $(this));
10364 const icon = $(this).find('.drawer-icon');10326 const icon = $(this).find('.drawer-icon');
10365 const drawer = $(this).parent().find('.drawer-content');10327 const drawer = $(this).parent().find('.drawer-content');
10366 if (drawer.hasClass('resizing')) { return; }
10367 const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');10328 const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
10368 const targetDrawerID = $(this).parent().find('.drawer-content').attr('id');10329 const targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
10369 const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
1037010330
10371 if (!drawerWasOpenAlready) { // to open the drawer10331 if (!drawerWasOpenAlready) {
10372 // Close all open drawers except pinned ones
10373 const $openDrawers = $('.openDrawer:not(.pinnedOpen)');10332 const $openDrawers = $('.openDrawer:not(.pinnedOpen)');
10374 for (const el of $openDrawers) {
10375 $(el).addClass('resizing');
10376 await animateDrawer($(el), false, undefined, function (el) {
10377 $(el).closest('.drawer-content').removeClass('resizing');
10378 });
10379 }
10380
10381 // Toggle icon and drawer classes
10382 const $openIcons = $('.openIcon:not(.drawerPinnedOpen)');10333 const $openIcons = $('.openIcon:not(.drawerPinnedOpen)');
10383 for (const iconEl of $openIcons) {10334 for (const iconEl of $openIcons) {
10384 $(iconEl).toggleClass('closedIcon openIcon');10335 $(iconEl).toggleClass('closedIcon openIcon');
@@ -10389,21 +10340,9 @@ export async function doNavbarIconClick() {
10389 icon.toggleClass('openIcon closedIcon');10340 icon.toggleClass('openIcon closedIcon');
10390 drawer.toggleClass('openDrawer closedDrawer');10341 drawer.toggleClass('openDrawer closedDrawer');
1039110342
10392 // Open the target drawer
10393 const $drawerContents = $(this).closest('.drawer').find('.drawer-content');
10394 for (const el of $drawerContents) {
10395 $(el).addClass('resizing');
10396 if (targetDrawerID === 'right-nav-panel') {10343 if (targetDrawerID === 'right-nav-panel') {
10397 await animateDrawer($(el), true, 'flex', function (el) {
10398 $(el).closest('.drawer-content').removeClass('resizing');
10399 favsToHotswap();10344 favsToHotswap();
10400 $('#rm_print_characters_block').trigger('scroll');10345 $('#rm_print_characters_block').trigger('scroll');
10401 });
10402 } else {
10403 await animateDrawer($(el), true, undefined, function (el) {
10404 $(el).closest('.drawer-content').removeClass('resizing');
10405 });
10406 }
10407 }10346 }
1040810347
10409 // Set the height of "autoSetHeight" textareas within the drawer to their scroll height10348 // Set the height of "autoSetHeight" textareas within the drawer to their scroll height
@@ -10414,31 +10353,12 @@ export async function doNavbarIconClick() {
10414 return;10353 return;
10415 }10354 }
10416 }10355 }
1041710356 } else if (drawerWasOpenAlready) {
10418 } else if (drawerWasOpenAlready) { // to close manually
10419 console.warn('saw drawer was already open');
10420 icon.toggleClass('closedIcon openIcon');10357 icon.toggleClass('closedIcon openIcon');
10421
10422 if (pinnedDrawerClicked) {
10423 $(drawer).addClass('resizing').each((_, el) => {
10424 animateDrawer($(el), false, undefined, function (el) {
10425 el.classList.remove('resizing');
10426 });
10427 });
10428 }
10429 else {
10430 console.warn('not pinned drawer');
10431 $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => {
10432 animateDrawer($(el), false, undefined, function (el) {
10433 el.closest('.drawer-content').classList.remove('resizing');
10434 });
10435 });
10436 }
10437
10438 drawer.toggleClass('closedDrawer openDrawer');10358 drawer.toggleClass('closedDrawer openDrawer');
10439 }10359 }
10440}10360}
10441// ...existing code...10361
10442function addDebugFunctions() {10362function addDebugFunctions() {
10443 const doBackfill = async () => {10363 const doBackfill = async () => {
10444 for (const message of chat) {10364 for (const message of chat) {
@@ -12064,7 +11984,7 @@ jQuery(async function () {
12064 $('.drawer-toggle').on('click', doNavbarIconClick);11984 $('.drawer-toggle').on('click', doNavbarIconClick);
1206511985
12066 $('html').on('touchstart mousedown', async function (e) {11986 $('html').on('touchstart mousedown', async function (e) {
12067 var clickTarget = $(e.target);11987 const clickTarget = $(e.target);
1206811988
12069 if (isExportPopupOpen11989 if (isExportPopupOpen
12070 && clickTarget.closest('#export_button').length == 011990 && clickTarget.closest('#export_button').length == 0
@@ -12085,27 +12005,19 @@ jQuery(async function () {
12085 '#toast-container',12005 '#toast-container',
12086 '.select2-results',12006 '.select2-results',
12087 ];12007 ];
12008
12088 for (const id of forbiddenTargets) {12009 for (const id of forbiddenTargets) {
12089 if (clickTarget.closest(id).length > 0) {12010 if (clickTarget.closest(id).length > 0) {
12090 return;12011 return;
12091 }12012 }
12092 }12013 }
1209312014
12094
12095 // This autocloses open drawers that are not pinned if a click happens inside the app which does not target them.12015 // This autocloses open drawers that are not pinned if a click happens inside the app which does not target them.
12096 var targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length;12016 const targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length;
12097 if (!clickTarget.hasClass('drawer-icon') && !clickTarget.hasClass('openDrawer')) {12017 if (!clickTarget.hasClass('drawer-icon') && !clickTarget.hasClass('openDrawer')) {
12098 const $openDrawers = $('.openDrawer').not('.pinnedOpen');12018 const $openDrawers = $('.openDrawer').not('.pinnedOpen');
12099 if ($openDrawers.length && targetParentHasOpenDrawer === 0) {12019 if ($openDrawers.length && targetParentHasOpenDrawer === 0) {
12100 // Animate close for each open drawer12020 // Toggle icon and drawer classes
12101 for (const el of $openDrawers) {
12102 $(el).addClass('resizing');
12103 // Use the same animateDrawer helper as in doNavbarIconClick
12104 await animateDrawer($(el), false, undefined, function (el) {
12105 $(el).closest('.drawer-content').removeClass('resizing');
12106 });
12107 }
12108 // Toggle icon and drawer classes after animation
12109 $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');12021 $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');
12110 $openDrawers.toggleClass('closedDrawer openDrawer');12022 $openDrawers.toggleClass('closedDrawer openDrawer');
12111 }12023 }
public/style.css+16 -2
@@ -14,6 +14,7 @@
14@import url(css/data-maid.css);14@import url(css/data-maid.css);
1515
16:root {16:root {
17 interpolate-size: allow-keywords;
17 --doc-height: 100%;18 --doc-height: 100%;
18 --transparent: rgba(0, 0, 0, 0);19 --transparent: rgba(0, 0, 0, 0);
1920
@@ -2805,7 +2806,6 @@ input[type="file"] {
2805}2806}
28062807
2807#rm_extensions_block {2808#rm_extensions_block {
2808 display: none;
2809 overflow-y: auto;2809 overflow-y: auto;
2810}2810}
28112811
@@ -2934,7 +2934,6 @@ select option:not(:checked) {
2934/*#######################################################################*/2934/*#######################################################################*/
29352935
2936#rm_api_block {2936#rm_api_block {
2937 display: none;
2938 overflow-y: auto;2937 overflow-y: auto;
2939}2938}
29402939
@@ -5402,6 +5401,21 @@ body:has(#character_popup.open) #top-settings-holder:has(.drawer-content.openDra
5402 backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));5401 backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
5403 -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));5402 -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
5404 /* z-index: 1000 !important; */5403 /* z-index: 1000 !important; */
5404 height: 0;
5405 transition-property: height, display;
5406 transition-duration: var(--animation-duration);
5407 transition-timing-function: ease-in-out;
5408 transition-behavior: allow-discrete;
5409}
5410
5411.drawer-content.openDrawer {
5412 display: block;
5413 height: auto;
5414 height: calc-size(auto, size);
5415
5416 @starting-style {
5417 height: 0;
5418 }
5405}5419}
54065420
5407body.movingUI .inline-drawer-maximize {5421body.movingUI .inline-drawer-maximize {