Improved the animation behavior by merging transitions
authorAlexander Ebert <ebert@woltlab.com>
Thu, 6 Aug 2020 20:48:57 +0000 (22:48 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 6 Aug 2020 20:48:57 +0000 (22:48 +0200)
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Action.js
wcfsetup/install/files/style/ui/pageAction.scss

index d85fa3c275e722eb6bbee5f62ffba3a59c79c313..429a28f2121584a6fa5eaf4c108724a912b19a36 100644 (file)
@@ -73,7 +73,7 @@ define(['Dictionary', 'Language'], function (Dictionary, Language) {
                 */
                _onScroll: function (event) {
                        var offset = window.pageYOffset;
-                       console.log(offset, _lastPosition);
+                       
                        if (offset >= 300) {
                                if (_toTopButton.classList.contains('initiallyHidden')) {
                                        _toTopButton.classList.remove('initiallyHidden');
@@ -120,7 +120,7 @@ define(['Dictionary', 'Language'], function (Dictionary, Language) {
                        var wrapper = elCreate('div');
                        wrapper.className = 'pageActionButton';
                        wrapper.name = buttonName;
-                       elAttr(wrapper, 'aria-hidden', 'false');
+                       elAttr(wrapper, 'aria-hidden', 'true');
                        
                        button.classList.add('button');
                        button.classList.add('buttonPrimary');
@@ -145,6 +145,14 @@ define(['Dictionary', 'Language'], function (Dictionary, Language) {
                        _wrapper.classList.remove('scrolledDown');
                        
                        _buttons.set(buttonName, button);
+                       
+                       // Query a layout related property to force a reflow, otherwise the transition is optimized away.
+                       // noinspection BadExpressionStatementJS
+                       wrapper.offsetParent;
+                       
+                       // Toggle the visibility to force the transition to be applied.
+                       elAttr(wrapper, 'aria-hidden', 'false');
+                       
                        this._renderContainer();
                },
                
@@ -184,14 +192,14 @@ define(['Dictionary', 'Language'], function (Dictionary, Language) {
                                                        _buttons.delete(buttonName);
                                                }
                                                
-                                               listItem.removeEventListener('animationend', callback);
+                                               listItem.removeEventListener('transitionend', callback);
                                        }
                                        catch (e) {
                                                // ignore errors if the element has already been removed
                                        }
                                };
                                
-                               listItem.addEventListener('animationend', callback);
+                               listItem.addEventListener('transitionend', callback);
                                
                                this.hide(buttonName);
                        }
index 5f0410432c563b7e33f0af984927005546914896..72d4c58a7b1c25d2dedefbc2104a1178801878d0 100644 (file)
@@ -1,19 +1,3 @@
-@keyframes wcfPageAction {
-       0%   { visibility: visible; opacity: 0; }
-       100% { visibility: visible; opacity: 1; }
-}
-
-@keyframes wcfPageActionOut {
-       0%   { visibility: visible; opacity: 1; }
-       100% { visibility: hidden;  opacity: 0; }
-}
-
-@keyframes wcfPageActionRemove {
-       0%   { visibility: visible; opacity: 1; }
-       60%  { visibility: hidden;  opacity: 0; }
-       100% { visibility: hidden;  opacity: 0; max-width: 0; }
-}
-
 .pageAction {
        bottom: 10px;
        display: flex;
@@ -38,9 +22,6 @@
        .pageActionButton {
                display: flex;
                flex: 0 0 auto;
-               
-               // required to animate 'max-width' properly when removing items
-               max-width: 400px;
                white-space: nowrap;
                
                &:not(:first-child) {
                }
                
                &.remove {
-                       animation: wcfPageActionRemove .48s;
+                       opacity: 0 !important;
+                       visibility: hidden !important;
                }
        }
        
        .pageActionButton,
        .pageActionButtonToTop {
-               animation: wcfPageActionOut .24s forwards;
+               opacity: 0;
+               transition: visibility .12s linear, opacity .12s linear;
+               visibility: hidden;
                
                &[aria-hidden="false"] {
-                       animation: wcfPageAction .24s;
-               }
-               
-               &.initiallyHidden {
-                       animation: 0;
-                       visibility: hidden;
+                       opacity: 1;
+                       visibility: visible;
                }
        }
        
                   menu instead of registering any touch on a button. */
                bottom: 44px;
                
-               opacity: 1;
-               transition: opacity .12s linear;
-               
-               &.scrolledDown {
+               &.scrolledDown .pageActionButton,
+               &.scrolledDown .pageActionButtonToTop {
                        opacity: 0;
+                       visibility: hidden;
                        transition-delay: .4s;
                }
        }