From fcb9805074e0ea99b5063f7dea6f2507338bb2b1 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 10:02:32 +0200 Subject: [PATCH 1/7] fix: AnimateCSS merge hide() and show() animated css class when we do multiple call * rewrite animateCSS fonctionality * don't use promise and use timer (like default) * use addAnimateCSS / removeAnimateCSS * use hasAnimateIn / hasAnimateOut for set actual animation (internal using) * check if animation is used (hasAnimateXXX) and reset it if needed before display new animation --- js/animateCSS.js | 53 ++++++++++++++++++++++--------------------- js/main.js | 58 +++++++++++++++++++++++++++++++++++------------- js/module.js | 2 ++ 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index ae6e7bec7b..cf3f26bcb7 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -130,36 +130,35 @@ const AnimateCSSOut = [ /** * Create an animation with Animate CSS - * resolved as Promise when done * @param {string} [element] div element to animate. * @param {string} [animation] animation name. * @param {number} [animationTime] animation duration. */ -function AnimateCSS(element, animation, animationTime) { - /* We create a Promise and return it */ - return new Promise((resolve) => { - const animationName = `animate__${animation}`; - const node = document.getElementById(element); - if (!node) { - // don't execute animate and resolve - Log.warn(`AnimateCSS: node not found for`, element); - resolve(); - return; - } - node.style.setProperty("--animate-duration", `${animationTime}s`); - node.classList.add("animate__animated", animationName); - - /** - * When the animation ends, we clean the classes and resolve the Promise - * @param {object} event object - */ - function handleAnimationEnd(event) { - node.classList.remove("animate__animated", animationName); - node.style.removeProperty("--animate-duration", `${animationTime}s`); - event.stopPropagation(); - resolve(); - } +function addAnimateCSS(element, animation, animationTime) { + const animationName = `animate__${animation}`; + const node = document.getElementById(element); + if (!node) { + // don't execute animate: we don't find div + Log.warn(`addAnimateCSS: node not found for`, element); + return; + } + node.style.setProperty("--animate-duration", `${animationTime}s`); + node.classList.add("animate__animated", animationName); +} - node.addEventListener("animationend", handleAnimationEnd, { once: true }); - }); +/** + * Remove an animation with Animate CSS + * @param {string} [element] div element to animate. + * @param {string} [animation] animation name. + */ +function removeAnimateCSS(element, animation) { + const animationName = `animate__${animation}`; + const node = document.getElementById(element); + if (!node) { + // don't execute animate: we don't find div + Log.warn(`removeAnimateCSS: node not found for`, element); + return; + } + node.classList.remove("animate__animated", animationName); + node.style.removeProperty("--animate-duration"); } diff --git a/js/main.js b/js/main.js index 3c023af359..c6c61d08a1 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,4 @@ -/* global Loader, defaults, Translator, AnimateCSS, AnimateCSSIn, AnimateCSSOut */ +/* global Loader, defaults, Translator, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut */ /* MagicMirror² * Main System @@ -281,7 +281,14 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { clearTimeout(module.showHideTimer); - + if (module.hasAnimateOut) { + removeAnimateCSS(module.identifier, module.hasAnimateOut); + Log.debug(`${module.identifier} Force remove animateOut (in hide): ${module.hasAnimateOut}`); + } + if (module.hasAnimateIn) { + removeAnimateCSS(module.identifier, module.hasAnimateIn); + Log.debug(`${module.identifier} Force remove animateIn (in hide): ${module.hasAnimateIn}`); + } // haveAnimateName for verify if we are using AninateCSS library // we check AnimateCSSOut Array for validate it // and finaly return the animate name or `null` (for default MM² animation) @@ -294,16 +301,22 @@ const MM = (function () { if (haveAnimateName) { // with AnimateCSS Log.debug(`${module.identifier} Has animateOut: ${haveAnimateName}`); - await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); - // AnimateCSS is now done - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - moduleWrapper.style.position = "fixed"; + module.hasAnimateOut = haveAnimateName; + await addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + module.showHideTimer = setTimeout(function () { + removeAnimateCSS(module.identifier, haveAnimateName); + Log.debug(`${module.identifier} Remove animateOut: ${module.hasAnimateOut}`); + // AnimateCSS is now done + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + moduleWrapper.style.position = "fixed"; + module.hasAnimateOut = false; - updateWrapperStates(); - if (typeof callback === "function") { - callback(); - } + updateWrapperStates(); + if (typeof callback === "function") { + callback(); + } + }, speed); } else { // default MM² Animate moduleWrapper.style.transition = `opacity ${speed / 1000}s`; @@ -357,6 +370,15 @@ const MM = (function () { return; } + if (module.hasAnimateOut) { + removeAnimateCSS(module.identifier, module.hasAnimateOut); + Log.debug(`${module.identifier} Force remove animateOut (in show): ${module.hasAnimateOut}`); + } + if (module.hasAnimateIn) { + removeAnimateCSS(module.identifier, module.hasAnimateIn); + Log.debug(`${module.identifier} Force remove animateIn (in show): ${module.hasAnimateIn}`); + } + module.hidden = false; // If forced show, clean current lockstrings. @@ -392,10 +414,16 @@ const MM = (function () { if (haveAnimateName) { // with AnimateCSS Log.debug(`${module.identifier} Has animateIn: ${haveAnimateName}`); - await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); - if (typeof callback === "function") { - callback(); - } + module.hasAnimateIn = haveAnimateName; + await addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + module.showHideTimer = setTimeout(function () { + removeAnimateCSS(module.identifier, haveAnimateName); + Log.debug(`${module.identifier} Remove animateIn: ${haveAnimateName}`); + module.hasAnimateIn = false; + if (typeof callback === "function") { + callback(); + } + }, speed); } else { // default MM² Animate module.showHideTimer = setTimeout(function () { diff --git a/js/module.js b/js/module.js index 62534b0178..4ef3ab1d61 100644 --- a/js/module.js +++ b/js/module.js @@ -205,6 +205,8 @@ const Module = Class.extend({ this.name = data.name; this.identifier = data.identifier; this.hidden = false; + this.hasAnimateIn = false; + this.hasAnimateOut = false; this.setConfig(data.config, data.configDeepMerge); }, From ac8c4bcd62318d451bd7f99bb324a79377bb7c0d Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 10:05:36 +0200 Subject: [PATCH 2/7] add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8616abaa61..6f0fb15296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ _This release is scheduled to be released on 2023-10-01._ - Fix ipWhiteList test (#3179) - Fix newsfeed: Convert HTML entities, codes and tag in description (#3191) - Respect width/height (no fullscreen) if set in electronOptions (together with `fullscreen: false`) in `config.js` (#3174) +- Fix: AnimateCSS merge hide() and show() animated css class when we do multiple call ## [2.24.0] - 2023-07-01 From ed6bad5050a6127f543595c2699d66fbb0497d01 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 10:16:32 +0200 Subject: [PATCH 3/7] delete not needed async/await --- js/main.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/main.js b/js/main.js index c6c61d08a1..bee52a1e98 100644 --- a/js/main.js +++ b/js/main.js @@ -269,7 +269,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - const hideModule = async function (module, speed, callback, options = {}) { + const hideModule = function (module, speed, callback, options = {}) { // set lockString if set in options. if (options.lockString) { // Log.log("Has lockstring: " + options.lockString); @@ -302,7 +302,7 @@ const MM = (function () { // with AnimateCSS Log.debug(`${module.identifier} Has animateOut: ${haveAnimateName}`); module.hasAnimateOut = haveAnimateName; - await addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); module.showHideTimer = setTimeout(function () { removeAnimateCSS(module.identifier, haveAnimateName); Log.debug(`${module.identifier} Remove animateOut: ${module.hasAnimateOut}`); @@ -351,7 +351,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - const showModule = async function (module, speed, callback, options = {}) { + const showModule = function (module, speed, callback, options = {}) { // remove lockString if set in options. if (options.lockString) { const index = module.lockStrings.indexOf(options.lockString); @@ -415,7 +415,7 @@ const MM = (function () { // with AnimateCSS Log.debug(`${module.identifier} Has animateIn: ${haveAnimateName}`); module.hasAnimateIn = haveAnimateName; - await addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); module.showHideTimer = setTimeout(function () { removeAnimateCSS(module.identifier, haveAnimateName); Log.debug(`${module.identifier} Remove animateIn: ${haveAnimateName}`); From bc8d429c6453f2a28745493bda4286d247f63800 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 10:42:54 +0200 Subject: [PATCH 4/7] reset hasAnimateXXX value --- js/main.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/main.js b/js/main.js index bee52a1e98..2c1093cf5b 100644 --- a/js/main.js +++ b/js/main.js @@ -283,10 +283,12 @@ const MM = (function () { clearTimeout(module.showHideTimer); if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); + module.hasAnimateOut = false; Log.debug(`${module.identifier} Force remove animateOut (in hide): ${module.hasAnimateOut}`); } if (module.hasAnimateIn) { removeAnimateCSS(module.identifier, module.hasAnimateIn); + module.hasAnimateIn = false; Log.debug(`${module.identifier} Force remove animateIn (in hide): ${module.hasAnimateIn}`); } // haveAnimateName for verify if we are using AninateCSS library @@ -372,10 +374,12 @@ const MM = (function () { if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); + module.hasAnimateOut = false; Log.debug(`${module.identifier} Force remove animateOut (in show): ${module.hasAnimateOut}`); } if (module.hasAnimateIn) { removeAnimateCSS(module.identifier, module.hasAnimateIn); + module.hasAnimateIn = false; Log.debug(`${module.identifier} Force remove animateIn (in show): ${module.hasAnimateIn}`); } From 937cf9deb93cb5d55f1c812674f2bec224eaa240 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 11:56:41 +0200 Subject: [PATCH 5/7] fix: module.hasAnimateXXX and debug line --- js/main.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/main.js b/js/main.js index 2c1093cf5b..f7f5ba08cd 100644 --- a/js/main.js +++ b/js/main.js @@ -283,13 +283,13 @@ const MM = (function () { clearTimeout(module.showHideTimer); if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); - module.hasAnimateOut = false; Log.debug(`${module.identifier} Force remove animateOut (in hide): ${module.hasAnimateOut}`); + module.hasAnimateOut = false; } if (module.hasAnimateIn) { removeAnimateCSS(module.identifier, module.hasAnimateIn); - module.hasAnimateIn = false; Log.debug(`${module.identifier} Force remove animateIn (in hide): ${module.hasAnimateIn}`); + module.hasAnimateIn = false; } // haveAnimateName for verify if we are using AninateCSS library // we check AnimateCSSOut Array for validate it @@ -374,13 +374,13 @@ const MM = (function () { if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); - module.hasAnimateOut = false; Log.debug(`${module.identifier} Force remove animateOut (in show): ${module.hasAnimateOut}`); + module.hasAnimateOut = false; } if (module.hasAnimateIn) { removeAnimateCSS(module.identifier, module.hasAnimateIn); - module.hasAnimateIn = false; Log.debug(`${module.identifier} Force remove animateIn (in show): ${module.hasAnimateIn}`); + module.hasAnimateIn = false; } module.hidden = false; From 73e1d2287806a706e2e328f94c26e2a172069f32 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 12:59:26 +0200 Subject: [PATCH 6/7] Fix: fist start with new updateDom object --- js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index f7f5ba08cd..04021f79ad 100644 --- a/js/main.js +++ b/js/main.js @@ -57,7 +57,7 @@ const MM = (function () { // create the domCreationPromise with AnimateCSS (with animateIn of module definition) // or just display it var domCreationPromise; - if (haveAnimateIn) domCreationPromise = updateDom(module, 1000, null, haveAnimateIn, true); + if (haveAnimateIn) domCreationPromise = updateDom(module, { options: { speed: 1000, animate: { in: haveAnimateIn } } }, true); else domCreationPromise = updateDom(module, 0); domCreationPromises.push(domCreationPromise); From 4d36750afa1879f7f3c1e6ecfcfe2f72f6a819d6 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 17 Sep 2023 13:39:49 +0200 Subject: [PATCH 7/7] add little comment (maybe e2e will work...) --- js/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index 04021f79ad..c7d4d39f77 100644 --- a/js/main.js +++ b/js/main.js @@ -281,6 +281,7 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { clearTimeout(module.showHideTimer); + // reset all animations if needed if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); Log.debug(`${module.identifier} Force remove animateOut (in hide): ${module.hasAnimateOut}`); @@ -371,7 +372,7 @@ const MM = (function () { } return; } - + // reset all animations if needed if (module.hasAnimateOut) { removeAnimateCSS(module.identifier, module.hasAnimateOut); Log.debug(`${module.identifier} Force remove animateOut (in show): ${module.hasAnimateOut}`);