From f93ca79e62ea9ff4b2a1ba82a7c1d9a9236dfa6e Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sat, 27 May 2023 18:57:27 +0200 Subject: [PATCH 01/19] begin coding with animateCSS install animate.css in vendor create animateCSS.js modify index.html --- index.html | 2 + js/animateCSS.js | 141 +++++++++++++++++++++++++++++++++++++++ vendor/package-lock.json | 11 +++ vendor/package.json | 1 + 4 files changed, 155 insertions(+) create mode 100644 js/animateCSS.js diff --git a/index.html b/index.html index 37fc2f6efb..022036b507 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,7 @@ + + diff --git a/js/animateCSS.js b/js/animateCSS.js new file mode 100644 index 0000000000..5c28e8f98e --- /dev/null +++ b/js/animateCSS.js @@ -0,0 +1,141 @@ +const _AnimateCSSIn = { + // Attention seekers + 1: "bounce", + 2: "flash", + 3: "pulse", + 4: "rubberBand", + 5: "shakeX", + 6: "shakeY", + 7: "headShake", + 8: "swing", + 9: "tada", + 10: "wobble", + 11: "jello", + 12: "heartBeat", + // Back entrances + 13: "backInDown", + 14: "backInLeft", + 15: "backInRight", + 16: "backInUp", + // Bouncing entrances + 17: "bounceIn", + 18: "bounceInDown", + 19: "bounceInLeft", + 20: "bounceInRight", + 21: "bounceInUp", + // Fading entrances + 22: "fadeIn", + 23: "fadeInDown", + 24: "fadeInDownBig", + 25: "fadeInLeft", + 26: "fadeInLeftBig", + 27: "fadeInRight", + 28: "fadeInRightBig", + 29: "fadeInUp", + 30: "fadeInUpBig", + 31: "fadeInTopLeft", + 32: "fadeInTopRight", + 33: "fadeInBottomLeft", + 34: "fadeInBottomRight", + // Flippers + 35: "flip", + 36: "flipInX", + 37: "flipInY", + // Lightspeed + 38: "lightSpeedInRight", + 39: "lightSpeedInLeft", + // Rotating entrances + 40: "rotateIn", + 41: "rotateInDownLeft", + 42: "rotateInDownRight", + 43: "rotateInUpLeft", + 44: "rotateInUpRight", + // Specials + 45: "jackInTheBox", + 46: "rollIn", + // Zooming entrances + 47: "zoomIn", + 48: "zoomInDown", + 49: "zoomInLeft", + 50: "zoomInRight", + 51: "zoomInUp", + // Sliding entrances + 52: "slideInDown", + 53: "slideInLeft", + 54: "slideInRight", + 55: "slideInUp" +}; + +const _AnimateCSSOut = { + // Back exits + 1: "backOutDown", + 2: "backOutLeft", + 3: "backOutRight", + 4: "backOutUp", + // Bouncing exits + 5: "bounceOut", + 6: "bounceOutDown", + 7: "bounceOutLeft", + 8: "bounceOutRight", + 9: "bounceOutUp", + // Fading exits + 10: "fadeOut", + 11: "fadeOutDown", + 12: "fadeOutDownBig", + 13: "fadeOutLeft", + 14: "fadeOutLeftBig", + 15: "fadeOutRight", + 16: "fadeOutRightBig", + 17: "fadeOutUp", + 18: "fadeOutUpBig", + 19: "fadeOutTopLeft", + 20: "fadeOutTopRight", + 21: "fadeOutBottomRight", + 22: "fadeOutBottomLeft", + // Flippers + 23: "flipOutX", + 24: "flipOutY", + // Lightspeed + 25: "lightSpeedOutRight", + 26: "lightSpeedOutLeft", + // Rotating exits + 27: "rotateOut", + 28: "rotateOutDownLeft", + 29: "rotateOutDownRight", + 30: "rotateOutUpLeft", + 31: "rotateOutUpRight", + // Specials + 32: "hinge", + 33: "rollOut", + // Zooming exits + 34: "zoomOut", + 35: "zoomOutDown", + 36: "zoomOutLeft", + 37: "zoomOutRight", + 38: "zoomOutUp", + // Sliding exits + 39: "slideOutDown", + 40: "slideOutLeft", + 41: "slideOutRight", + 42: "slideOutUp" +}; + +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) return Log.warn(`[Pages] node not found for`, element); + 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 + function handleAnimationEnd(event) { + node.classList.remove("animate__animated", animationName); + event.stopPropagation(); + resolve(); + } + + node.addEventListener("animationend", handleAnimationEnd, { once: true }); + }); +} diff --git a/vendor/package-lock.json b/vendor/package-lock.json index f8d0cadee0..0c0296b878 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -8,6 +8,7 @@ "license": "MIT", "dependencies": { "@fortawesome/fontawesome-free": "^6.4.0", + "animate.css": "^4.1.1", "moment": "^2.29.4", "moment-timezone": "^0.5.43", "nunjucks": "^3.2.4", @@ -29,6 +30,11 @@ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, + "node_modules/animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -107,6 +113,11 @@ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, + "animate.css": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", diff --git a/vendor/package.json b/vendor/package.json index 7e0de4115b..b76290cf0b 100644 --- a/vendor/package.json +++ b/vendor/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^6.4.0", + "animate.css": "^4.1.1", "moment": "^2.29.4", "moment-timezone": "^0.5.43", "nunjucks": "^3.2.4", From 5d554ea77fd004f49c089400dc897950c8e5d933 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 13:56:38 +0200 Subject: [PATCH 02/19] testing code for AnimateCSS --- js/animateCSS.js | 224 +++++++++++++++++++++++++---------------------- js/main.js | 113 +++++++++++++++--------- js/module.js | 6 +- 3 files changed, 198 insertions(+), 145 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index 5c28e8f98e..f980d147dd 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -1,131 +1,149 @@ -const _AnimateCSSIn = { +/* MagicMirror² + * AnimateCSS System + * + * by @bugsounet + * for Michael Teeuw https://michaelteeuw.nl + * MIT Licensed. + */ + +/* enumeration of animations in Array **/ +const _AnimateCSSIn = [ + null, // 0 not used (default MM animation) // Attention seekers - 1: "bounce", - 2: "flash", - 3: "pulse", - 4: "rubberBand", - 5: "shakeX", - 6: "shakeY", - 7: "headShake", - 8: "swing", - 9: "tada", - 10: "wobble", - 11: "jello", - 12: "heartBeat", + "bounce", // 1 + "flash", // 2 + "pulse", // 3 + "rubberBand", // 4 + "shakeX", // 5 + "shakeY", // 6 + "headShake", // 7 + "swing", // 8 + "tada", // 9 + "wobble", // 10 + "jello", // 11 + "heartBeat", // 12 // Back entrances - 13: "backInDown", - 14: "backInLeft", - 15: "backInRight", - 16: "backInUp", + "backInDown", // 13 + "backInLeft", // 14 + "backInRight", // 15 + "backInUp", // 16 // Bouncing entrances - 17: "bounceIn", - 18: "bounceInDown", - 19: "bounceInLeft", - 20: "bounceInRight", - 21: "bounceInUp", + "bounceIn", // 17 + "bounceInDown", // 18 + "bounceInLeft", // 19 + "bounceInRight", // 20 + "bounceInUp", // 21 // Fading entrances - 22: "fadeIn", - 23: "fadeInDown", - 24: "fadeInDownBig", - 25: "fadeInLeft", - 26: "fadeInLeftBig", - 27: "fadeInRight", - 28: "fadeInRightBig", - 29: "fadeInUp", - 30: "fadeInUpBig", - 31: "fadeInTopLeft", - 32: "fadeInTopRight", - 33: "fadeInBottomLeft", - 34: "fadeInBottomRight", + "fadeIn", // 22 + "fadeInDown", // 23 + "fadeInDownBig", // 24 + "fadeInLeft", // 25 + "fadeInLeftBig", // 26 + "fadeInRight", // 27 + "fadeInRightBig", // 28 + "fadeInUp", // 29 + "fadeInUpBig", // 30 + "fadeInTopLeft", // 31 + "fadeInTopRight", // 32 + "fadeInBottomLeft", // 33 + "fadeInBottomRight", // 34 // Flippers - 35: "flip", - 36: "flipInX", - 37: "flipInY", + "flip", // 35 + "flipInX", // 36 + "flipInY", // 37 // Lightspeed - 38: "lightSpeedInRight", - 39: "lightSpeedInLeft", + "lightSpeedInRight", // 38 + "lightSpeedInLeft", // 39 // Rotating entrances - 40: "rotateIn", - 41: "rotateInDownLeft", - 42: "rotateInDownRight", - 43: "rotateInUpLeft", - 44: "rotateInUpRight", + "rotateIn", // 40 + "rotateInDownLeft", // 41 + "rotateInDownRight", // 42 + "rotateInUpLeft", // 43 + "rotateInUpRight", // 44 // Specials - 45: "jackInTheBox", - 46: "rollIn", + "jackInTheBox", // 45 + "rollIn", // 46 // Zooming entrances - 47: "zoomIn", - 48: "zoomInDown", - 49: "zoomInLeft", - 50: "zoomInRight", - 51: "zoomInUp", + "zoomIn", // 47 + "zoomInDown", // 48 + "zoomInLeft", // 49 + "zoomInRight", // 50 + "zoomInUp", // 51 // Sliding entrances - 52: "slideInDown", - 53: "slideInLeft", - 54: "slideInRight", - 55: "slideInUp" -}; + "slideInDown", // 52 + "slideInLeft", // 53 + "slideInRight", // 54 + "slideInUp" // 55 +]; -const _AnimateCSSOut = { - // Back exits - 1: "backOutDown", - 2: "backOutLeft", - 3: "backOutRight", - 4: "backOutUp", +const _AnimateCSSOut = [ + null, // 0 not used (default MM animation) + "backOutDown", // 1 + "backOutLeft", // 2 + "backOutRight", // 3 + "backOutUp", // 4 // Bouncing exits - 5: "bounceOut", - 6: "bounceOutDown", - 7: "bounceOutLeft", - 8: "bounceOutRight", - 9: "bounceOutUp", + "bounceOut", // 5 + "bounceOutDown", // 6 + "bounceOutLeft", // 7 + "bounceOutRight", // 8 + "bounceOutUp", // 9 // Fading exits - 10: "fadeOut", - 11: "fadeOutDown", - 12: "fadeOutDownBig", - 13: "fadeOutLeft", - 14: "fadeOutLeftBig", - 15: "fadeOutRight", - 16: "fadeOutRightBig", - 17: "fadeOutUp", - 18: "fadeOutUpBig", - 19: "fadeOutTopLeft", - 20: "fadeOutTopRight", - 21: "fadeOutBottomRight", - 22: "fadeOutBottomLeft", + "fadeOut", // 10 + "fadeOutDown", // 11 + "fadeOutDownBig", // 12 + "fadeOutLeft", // 13 + "fadeOutLeftBig", // 14 + "fadeOutRight", // 15 + "fadeOutRightBig", // 16 + "fadeOutUp", // 17 + "fadeOutUpBig", // 18 + "fadeOutTopLeft", // 19 + "fadeOutTopRight", // 20 + "fadeOutBottomRight", // 21 + "fadeOutBottomLeft", // 22 // Flippers - 23: "flipOutX", - 24: "flipOutY", + "flipOutX", // 23 + "flipOutY", // 24 // Lightspeed - 25: "lightSpeedOutRight", - 26: "lightSpeedOutLeft", + "lightSpeedOutRight", // 25 + "lightSpeedOutLeft", // 26 // Rotating exits - 27: "rotateOut", - 28: "rotateOutDownLeft", - 29: "rotateOutDownRight", - 30: "rotateOutUpLeft", - 31: "rotateOutUpRight", + "rotateOut", // 27 + "rotateOutDownLeft", // 28 + "rotateOutDownRight", // 29 + "rotateOutUpLeft", // 30 + "rotateOutUpRight", // 31 // Specials - 32: "hinge", - 33: "rollOut", + "hinge", // 32 + "rollOut", // 33 // Zooming exits - 34: "zoomOut", - 35: "zoomOutDown", - 36: "zoomOutLeft", - 37: "zoomOutRight", - 38: "zoomOutUp", + "zoomOut", // 34 + "zoomOutDown", // 35 + "zoomOutLeft", // 36 + "zoomOutRight", // 37 + "zoomOutUp", // 38 // Sliding exits - 39: "slideOutDown", - 40: "slideOutLeft", - 41: "slideOutRight", - 42: "slideOutUp" -}; + "slideOutDown", // 39 + "slideOutLeft", // 40 + "slideOutRight", // 41 + "slideOutUp" // 42 +]; + +/** + * Create an animation with Animate CSS + * resolved as Promise when done + * @param {string} div element to animate. + * @param {string} animation name. + * @param {number} 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) return Log.warn(`[Pages] node not found for`, element); + if (!node) return Log.warn(`node not found for`, element); node.style.setProperty("--animate-duration", animationTime + "s"); node.classList.add("animate__animated", animationName); diff --git a/js/main.js b/js/main.js index 026410c777..1707735034 100644 --- a/js/main.js +++ b/js/main.js @@ -104,7 +104,7 @@ const MM = (function () { * @param {number} [speed] The (optional) number of microseconds for the animation. * @returns {Promise} Resolved when the dom is fully updated. */ - const updateDom = function (module, speed) { + const updateDom = function (module, speed, animateOut, animateIn) { return new Promise(function (resolve) { const newHeader = module.getHeader(); let newContentPromise = module.getDom(); @@ -116,7 +116,7 @@ const MM = (function () { newContentPromise .then(function (newContent) { - const updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + const updatePromise = updateDomWithContent(module, speed, newHeader, newContent, animateOut, animateIn); updatePromise.then(resolve).catch(Log.error); }) @@ -132,7 +132,7 @@ const MM = (function () { * @param {HTMLElement} newContent The new content that is generated. * @returns {Promise} Resolved when the module dom has been updated. */ - const updateDomWithContent = function (module, speed, newHeader, newContent) { + const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn) { return new Promise(function (resolve) { if (module.hidden || !speed) { updateModuleContent(module, newHeader, newContent); @@ -151,13 +151,18 @@ const MM = (function () { return; } - hideModule(module, speed / 2, function () { - updateModuleContent(module, newHeader, newContent); - if (!module.hidden) { - showModule(module, speed / 2); - } - resolve(); - }); + hideModule( + module, + speed / 2, + function () { + updateModuleContent(module, newHeader, newContent); + if (!module.hidden) { + showModule(module, speed / 2, null, { animate: animateIn }); + } + resolve(); + }, + { animate: animateOut } + ); }); }; @@ -223,7 +228,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - const hideModule = function (module, speed, callback, options = {}) { + const hideModule = async function (module, speed, callback, options = {}) { // set lockString if set in options. if (options.lockString) { // Log.log("Has lockstring: " + options.lockString); @@ -234,24 +239,38 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = `opacity ${speed / 1000}s`; - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - - clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function () { - // To not take up any space, we just make the position absolute. - // since it's fade out anyway, we can see it lay above or - // below other modules. This works way better than adjusting - // the .display property. + if (options.animate) { + // for testing @todo better + clearTimeout(module.showHideTimer); + await AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000); + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); moduleWrapper.style.position = "fixed"; updateWrapperStates(); - if (typeof callback === "function") { callback(); } - }, speed); + } else { + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + + clearTimeout(module.showHideTimer); + module.showHideTimer = setTimeout(function () { + // To not take up any space, we just make the position absolute. + // since it's fade out anyway, we can see it lay above or + // below other modules. This works way better than adjusting + // the .display property. + moduleWrapper.style.position = "fixed"; + + updateWrapperStates(); + + if (typeof callback === "function") { + callback(); + } + }, speed); + } } else { // invoke callback even if no content, issue 1308 if (typeof callback === "function") { @@ -267,7 +286,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - const showModule = function (module, speed, callback, options = {}) { + const showModule = async function (module, speed, callback, options = {}) { // remove lockString if set in options. if (options.lockString) { const index = module.lockStrings.indexOf(options.lockString); @@ -296,23 +315,37 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = `opacity ${speed / 1000}s`; - // Restore the position. See hideModule() for more info. - moduleWrapper.style.position = "static"; - moduleWrapper.classList.remove("hidden"); - - updateWrapperStates(); - - // Waiting for DOM-changes done in updateWrapperStates before we can start the animation. - const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; - moduleWrapper.style.opacity = 1; - - clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function () { + if (options.animate) { + // for testing @todo better + clearTimeout(module.showHideTimer); + moduleWrapper.style.position = "static"; + moduleWrapper.classList.remove("hidden"); + updateWrapperStates(); + moduleWrapper.style.opacity = 1; + await AnimateCSS(module.identifier, _AnimateCSSIn[options.animate], speed / 1000); if (typeof callback === "function") { callback(); } - }, speed); + } else { + // don't use animateCSS (original) + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + // Restore the position. See hideModule() for more info. + moduleWrapper.style.position = "static"; + moduleWrapper.classList.remove("hidden"); + + updateWrapperStates(); + + // Waiting for DOM-changes done in updateWrapperStates before we can start the animation. + const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; + moduleWrapper.style.opacity = 1; + + clearTimeout(module.showHideTimer); + module.showHideTimer = setTimeout(function () { + if (typeof callback === "function") { + callback(); + } + }, speed); + } } else { // invoke callback if (typeof callback === "function") { @@ -516,7 +549,7 @@ const MM = (function () { * @param {Module} module The module that needs an update. * @param {number} [speed] The number of microseconds for the animation. */ - updateDom: function (module, speed) { + updateDom: function (module, speed, animateOut, animateIn) { if (!(module instanceof Module)) { Log.error("updateDom: Sender should be a module."); return; @@ -528,7 +561,7 @@ const MM = (function () { } // Further implementation is done in the private method. - updateDom(module, speed); + updateDom(module, speed, animateOut, animateIn); }, /** diff --git a/js/module.js b/js/module.js index 110ccc5595..d3497ccf80 100644 --- a/js/module.js +++ b/js/module.js @@ -328,9 +328,11 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. * @param {number} [speed] The speed of the animation. + * @param (bumber) [animateOut] AnimateCss animation number before hidden + * @param (bumber) [animateIn] AnimateCss animation number on show */ - updateDom: function (speed) { - MM.updateDom(this, speed); + updateDom: function (speed, animateOut, animateIn) { + MM.updateDom(this, speed, animateOut, animateIn); }, /** From 0c6525abdc43195acc6572cff46e09dd555d2d0f Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 13:58:57 +0200 Subject: [PATCH 03/19] test AnimateCSS with compliments and newsfeed default modules --- modules/default/compliments/compliments.js | 2 +- modules/default/newsfeed/newsfeed.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index a905581bd0..c58d380857 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -46,7 +46,7 @@ Module.register("compliments", { // Schedule update timer. setInterval(() => { - this.updateDom(this.config.fadeSpeed); + this.updateDom(this.config.fadeSpeed, 23, 36); }, this.config.updateInterval); }, diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index eee0b44a7b..9c0d28865a 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -301,7 +301,7 @@ Module.register("newsfeed", { * Schedule visual update. */ scheduleUpdateInterval: function () { - this.updateDom(this.config.animationSpeed); + this.updateDom(this.config.animationSpeed, 3, 14); // Broadcast NewsFeed if needed if (this.config.broadcastNewsFeeds) { @@ -313,7 +313,7 @@ Module.register("newsfeed", { this.timer = setInterval(() => { this.activeItem++; - this.updateDom(this.config.animationSpeed); + this.updateDom(this.config.animationSpeed, 3, 14); // Broadcast NewsFeed if needed if (this.config.broadcastNewsFeeds) { From 7a506055824d45bb4ca1dc94525be78445644360 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 14:02:17 +0200 Subject: [PATCH 04/19] decrease default animation time for testing --- modules/default/compliments/compliments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index c58d380857..5248f0e486 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -16,7 +16,7 @@ Module.register("compliments", { }, updateInterval: 30000, remoteFile: null, - fadeSpeed: 4000, + fadeSpeed: 2000, morningStartTime: 3, morningEndTime: 12, afternoonStartTime: 12, From bfcd079a069e1b005fc09742d734c5b55f43f374 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 14:04:01 +0200 Subject: [PATCH 05/19] missing AnimateCSS credit --- js/animateCSS.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index f980d147dd..7ec73dd6da 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -1,6 +1,5 @@ /* MagicMirror² - * AnimateCSS System - * + * AnimateCSS System from https://animate.style/ * by @bugsounet * for Michael Teeuw https://michaelteeuw.nl * MIT Licensed. From 7fc20b288be5c4e3166549cb62840131d2077f7d Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 14:11:42 +0200 Subject: [PATCH 06/19] update ChangeLog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be163e0b83..f9a5f2499e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ _This release is scheduled to be released on 2023-07-01._ - Added tests for serveronly - Set Timezone `Europe/Berlin` in unit tests (needed for new formatTime tests) - Added no-param-reassign eslint rule and fix warnings +- Added optional AnimateCSS animate for `hide()`, `show()`, `updateDom()` + +### Develop Testing (can be removed for release) + +- Testing AnimateCSS with `newsfeed` and `compliments` ### Removed From aabc2d5e66ec6227fc6009d3a139798948fc08fd Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 14:55:28 +0200 Subject: [PATCH 07/19] delete some warnings... --- js/animateCSS.js | 5 ++--- js/main.js | 2 ++ js/module.js | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index 7ec73dd6da..10b442a8cc 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -136,9 +136,8 @@ const _AnimateCSSOut = [ * @param {string} animation name. * @param {number} animation duration. */ - function AnimateCSS(element, animation, animationTime) { - // We create a Promise and return it + /* We create a Promise and return it */ return new Promise((resolve) => { const animationName = "animate__" + animation; const node = document.getElementById(element); @@ -146,7 +145,7 @@ function AnimateCSS(element, animation, animationTime) { 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 + /* When the animation ends, we clean the classes and resolve the Promise */ function handleAnimationEnd(event) { node.classList.remove("animate__animated", animationName); event.stopPropagation(); diff --git a/js/main.js b/js/main.js index 1707735034..a4bcd13a07 100644 --- a/js/main.js +++ b/js/main.js @@ -102,6 +102,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The (optional) number of microseconds for the animation. + * @param (number) [animateOut] AnimateCss animation number before hidden + * @param (number) [animateIn] AnimateCss animation number on show * @returns {Promise} Resolved when the dom is fully updated. */ const updateDom = function (module, speed, animateOut, animateIn) { diff --git a/js/module.js b/js/module.js index d3497ccf80..cf108b8b28 100644 --- a/js/module.js +++ b/js/module.js @@ -1,4 +1,4 @@ -/* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator */ +/* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator, animateCSS */ /* MagicMirror² * Module Blueprint. @@ -328,8 +328,8 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. * @param {number} [speed] The speed of the animation. - * @param (bumber) [animateOut] AnimateCss animation number before hidden - * @param (bumber) [animateIn] AnimateCss animation number on show + * @param (number) [animateOut] AnimateCss animation number before hidden + * @param (number) [animateIn] AnimateCss animation number on show */ updateDom: function (speed, animateOut, animateIn) { MM.updateDom(this, speed, animateOut, animateIn); From ab2a28b2c65e769b70914cb37de7e0753c357d4d Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 15:05:42 +0200 Subject: [PATCH 08/19] typo --- js/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/main.js b/js/main.js index a4bcd13a07..3ac6c9f5de 100644 --- a/js/main.js +++ b/js/main.js @@ -102,8 +102,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The (optional) number of microseconds for the animation. - * @param (number) [animateOut] AnimateCss animation number before hidden - * @param (number) [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation number before hidden + * @param {number} [animateIn] AnimateCss animation number on show * @returns {Promise} Resolved when the dom is fully updated. */ const updateDom = function (module, speed, animateOut, animateIn) { From 064cb01bf01e7754aabf52de079366a253b2e2b1 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 15:31:54 +0200 Subject: [PATCH 09/19] correct all errors / warn --- js/animateCSS.js | 15 +++++++++------ js/main.js | 6 +++++- js/module.js | 6 +++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index 10b442a8cc..dd50f50250 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -132,20 +132,23 @@ const _AnimateCSSOut = [ /** * Create an animation with Animate CSS * resolved as Promise when done - * @param {string} div element to animate. - * @param {string} animation name. - * @param {number} animation duration. + * @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 animationName = `animate__${animation}`; const node = document.getElementById(element); if (!node) return Log.warn(`node not found for`, element); - node.style.setProperty("--animate-duration", animationTime + "s"); + 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 */ + /** + * 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); event.stopPropagation(); diff --git a/js/main.js b/js/main.js index 3ac6c9f5de..804f9d242d 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,4 @@ -/* global Loader, defaults, Translator */ +/* global Loader, defaults, Translator, AnimateCSS, _AnimateCSSIn, _AnimateCSSOut */ /* MagicMirror² * Main System @@ -132,6 +132,8 @@ const MM = (function () { * @param {number} [speed] The (optional) number of microseconds for the animation. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. + * @param {number} [animateOut] AnimateCss animation number before hidden + * @param {number} [animateIn] AnimateCss animation number on show * @returns {Promise} Resolved when the module dom has been updated. */ const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn) { @@ -550,6 +552,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The number of microseconds for the animation. + * @param {number} [animateOut] AnimateCss animation number before hidden + * @param {number} [animateIn] AnimateCss animation number on show */ updateDom: function (module, speed, animateOut, animateIn) { if (!(module instanceof Module)) { diff --git a/js/module.js b/js/module.js index cf108b8b28..2a23dee4eb 100644 --- a/js/module.js +++ b/js/module.js @@ -1,4 +1,4 @@ -/* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator, animateCSS */ +/* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator */ /* MagicMirror² * Module Blueprint. @@ -328,8 +328,8 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. * @param {number} [speed] The speed of the animation. - * @param (number) [animateOut] AnimateCss animation number before hidden - * @param (number) [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation number before hidden + * @param {number} [animateIn] AnimateCss animation number on show */ updateDom: function (speed, animateOut, animateIn) { MM.updateDom(this, speed, animateOut, animateIn); From 80deac1bd86f33620cf7ca88a29f2182cfa7f5dc Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 28 May 2023 23:10:29 +0200 Subject: [PATCH 10/19] testing code purpose --- CHANGELOG.md | 4 -- js/animateCSS.js | 8 ++- js/main.js | 68 ++++++++++++---------- js/module.js | 2 +- modules/default/compliments/compliments.js | 4 +- modules/default/newsfeed/newsfeed.js | 4 +- 6 files changed, 50 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9a5f2499e..fb2fec4416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,10 +17,6 @@ _This release is scheduled to be released on 2023-07-01._ - Added no-param-reassign eslint rule and fix warnings - Added optional AnimateCSS animate for `hide()`, `show()`, `updateDom()` -### Develop Testing (can be removed for release) - -- Testing AnimateCSS with `newsfeed` and `compliments` - ### Removed - Removed unneeded (and unwanted) '.' after the year in calendar repeatingCountTitle (#2896, second attempt ...) diff --git a/js/animateCSS.js b/js/animateCSS.js index dd50f50250..c53ca4ebea 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -141,7 +141,12 @@ function AnimateCSS(element, animation, animationTime) { return new Promise((resolve) => { const animationName = `animate__${animation}`; const node = document.getElementById(element); - if (!node) return Log.warn(`node not found for`, 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); @@ -151,6 +156,7 @@ function AnimateCSS(element, animation, animationTime) { */ function handleAnimationEnd(event) { node.classList.remove("animate__animated", animationName); + node.style.removeProperty("--animate-duration", `${animationTime}s`); event.stopPropagation(); resolve(); } diff --git a/js/main.js b/js/main.js index 804f9d242d..c4827d130b 100644 --- a/js/main.js +++ b/js/main.js @@ -232,7 +232,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); @@ -243,24 +243,14 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - if (options.animate) { - // for testing @todo better - clearTimeout(module.showHideTimer); - await AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000); - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - moduleWrapper.style.position = "fixed"; - - updateWrapperStates(); - if (typeof callback === "function") { - callback(); - } - } else { + if (!options.animate) { + // clearTimeout(module.showHideTimer); <-- better there no ? + // default MM hide moduleWrapper.style.transition = `opacity ${speed / 1000}s`; moduleWrapper.style.opacity = 0; moduleWrapper.classList.add("hidden"); - clearTimeout(module.showHideTimer); + clearTimeout(module.showHideTimer); // <-- not sure it's the better position module.showHideTimer = setTimeout(function () { // To not take up any space, we just make the position absolute. // since it's fade out anyway, we can see it lay above or @@ -274,6 +264,20 @@ const MM = (function () { callback(); } }, speed); + } else { + Log.log(`${module.identifier} Has animateOut: ${options.animate}`); + // AnimateCSS for testing @todo better + clearTimeout(module.showHideTimer); + AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000).then(() => { + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + moduleWrapper.style.position = "fixed"; + + updateWrapperStates(); + if (typeof callback === "function") { + callback(); + } + }); } } else { // invoke callback even if no content, issue 1308 @@ -290,7 +294,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); @@ -319,19 +323,9 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - if (options.animate) { - // for testing @todo better - clearTimeout(module.showHideTimer); - moduleWrapper.style.position = "static"; - moduleWrapper.classList.remove("hidden"); - updateWrapperStates(); - moduleWrapper.style.opacity = 1; - await AnimateCSS(module.identifier, _AnimateCSSIn[options.animate], speed / 1000); - if (typeof callback === "function") { - callback(); - } - } else { - // don't use animateCSS (original) + if (!options.animate) { + // clearTimeout(module.showHideTimer); <-- better there no ? + // default MM show moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. moduleWrapper.style.position = "static"; @@ -343,12 +337,26 @@ const MM = (function () { const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; moduleWrapper.style.opacity = 1; - clearTimeout(module.showHideTimer); + clearTimeout(module.showHideTimer); // <-- not sure it's the better position module.showHideTimer = setTimeout(function () { if (typeof callback === "function") { callback(); } }, speed); + } else { + Log.log(`${module.identifier} Has animateIn: ${options.animate}`); + // AnimateCSS for testing @todo better + clearTimeout(module.showHideTimer); + moduleWrapper.style.position = "static"; + moduleWrapper.classList.remove("hidden"); + updateWrapperStates(); + const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; + moduleWrapper.style.opacity = 1; + AnimateCSS(module.identifier, _AnimateCSSIn[options.animate], speed / 1000).then(() => { + if (typeof callback === "function") { + callback(); + } + }); } } else { // invoke callback diff --git a/js/module.js b/js/module.js index 2a23dee4eb..aaf8bc9bdd 100644 --- a/js/module.js +++ b/js/module.js @@ -331,7 +331,7 @@ const Module = Class.extend({ * @param {number} [animateOut] AnimateCss animation number before hidden * @param {number} [animateIn] AnimateCss animation number on show */ - updateDom: function (speed, animateOut, animateIn) { + updateDom: function (speed, animateOut = 0, animateIn = 0) { MM.updateDom(this, speed, animateOut, animateIn); }, diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 5248f0e486..a905581bd0 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -16,7 +16,7 @@ Module.register("compliments", { }, updateInterval: 30000, remoteFile: null, - fadeSpeed: 2000, + fadeSpeed: 4000, morningStartTime: 3, morningEndTime: 12, afternoonStartTime: 12, @@ -46,7 +46,7 @@ Module.register("compliments", { // Schedule update timer. setInterval(() => { - this.updateDom(this.config.fadeSpeed, 23, 36); + this.updateDom(this.config.fadeSpeed); }, this.config.updateInterval); }, diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index 9c0d28865a..eee0b44a7b 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -301,7 +301,7 @@ Module.register("newsfeed", { * Schedule visual update. */ scheduleUpdateInterval: function () { - this.updateDom(this.config.animationSpeed, 3, 14); + this.updateDom(this.config.animationSpeed); // Broadcast NewsFeed if needed if (this.config.broadcastNewsFeeds) { @@ -313,7 +313,7 @@ Module.register("newsfeed", { this.timer = setInterval(() => { this.activeItem++; - this.updateDom(this.config.animationSpeed, 3, 14); + this.updateDom(this.config.animationSpeed); // Broadcast NewsFeed if needed if (this.config.broadcastNewsFeeds) { From 7ca8d70fdfbd5626d2585d5be8e541db36ef0e4f Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sat, 10 Jun 2023 14:09:04 +0200 Subject: [PATCH 11/19] testing with new code --- js/main.js | 80 ++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/js/main.js b/js/main.js index c4827d130b..c428a8dd37 100644 --- a/js/main.js +++ b/js/main.js @@ -232,7 +232,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - const hideModule = function (module, speed, callback, options = {}) { + const hideModule = async function (module, speed, callback, options = {}) { // set lockString if set in options. if (options.lockString) { // Log.log("Has lockstring: " + options.lockString); @@ -243,14 +243,22 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - if (!options.animate) { - // clearTimeout(module.showHideTimer); <-- better there no ? - // default MM hide - moduleWrapper.style.transition = `opacity ${speed / 1000}s`; - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - - clearTimeout(module.showHideTimer); // <-- not sure it's the better position + clearTimeout(module.showHideTimer); + + // haveAnimate for verify if we are using AninateCSS + // we check AnimateCSS Array for validate it too + let haveAnimate = options.animate && _AnimateCSSOut[options.animate]; + + if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + else { + Log.log(`${module.identifier} Has animateOut: ${haveAnimate}`); + await AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000); + } + + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + + if (!haveAnimate) { module.showHideTimer = setTimeout(function () { // To not take up any space, we just make the position absolute. // since it's fade out anyway, we can see it lay above or @@ -265,19 +273,13 @@ const MM = (function () { } }, speed); } else { - Log.log(`${module.identifier} Has animateOut: ${options.animate}`); - // AnimateCSS for testing @todo better - clearTimeout(module.showHideTimer); - AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000).then(() => { - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - moduleWrapper.style.position = "fixed"; + // AnimateCSS is now done + moduleWrapper.style.position = "fixed"; - updateWrapperStates(); - if (typeof callback === "function") { - callback(); - } - }); + updateWrapperStates(); + if (typeof callback === "function") { + callback(); + } } } else { // invoke callback even if no content, issue 1308 @@ -323,35 +325,31 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - if (!options.animate) { - // clearTimeout(module.showHideTimer); <-- better there no ? - // default MM show - moduleWrapper.style.transition = `opacity ${speed / 1000}s`; - // Restore the position. See hideModule() for more info. - moduleWrapper.style.position = "static"; - moduleWrapper.classList.remove("hidden"); + clearTimeout(module.showHideTimer); - updateWrapperStates(); + // haveAnimate for verify if we are using AninateCSS + // we check AnimateCSS Array for validate it too + let haveAnimate = options.animate && _AnimateCSSIn[options.animate]; + + if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + // Restore the position. See hideModule() for more info. + moduleWrapper.style.position = "static"; + moduleWrapper.classList.remove("hidden"); - // Waiting for DOM-changes done in updateWrapperStates before we can start the animation. - const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; - moduleWrapper.style.opacity = 1; + updateWrapperStates(); - clearTimeout(module.showHideTimer); // <-- not sure it's the better position + // Waiting for DOM-changes done in updateWrapperStates before we can start the animation. + const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; + moduleWrapper.style.opacity = 1; + + if (!haveAnimate) { module.showHideTimer = setTimeout(function () { if (typeof callback === "function") { callback(); } }, speed); } else { - Log.log(`${module.identifier} Has animateIn: ${options.animate}`); - // AnimateCSS for testing @todo better - clearTimeout(module.showHideTimer); - moduleWrapper.style.position = "static"; - moduleWrapper.classList.remove("hidden"); - updateWrapperStates(); - const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; - moduleWrapper.style.opacity = 1; + Log.log(`${module.identifier} Has animateIn: ${haveAnimate}`); AnimateCSS(module.identifier, _AnimateCSSIn[options.animate], speed / 1000).then(() => { if (typeof callback === "function") { callback(); From d0b083c00769d3bc1b4898ce54e89ccfbf99c996 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sat, 10 Jun 2023 14:25:00 +0200 Subject: [PATCH 12/19] in accord with test:e2e --- js/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/main.js b/js/main.js index c428a8dd37..962ec8700b 100644 --- a/js/main.js +++ b/js/main.js @@ -247,7 +247,7 @@ const MM = (function () { // haveAnimate for verify if we are using AninateCSS // we check AnimateCSS Array for validate it too - let haveAnimate = options.animate && _AnimateCSSOut[options.animate]; + const haveAnimate = options.animate && _AnimateCSSOut[options.animate]; if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; else { @@ -329,7 +329,7 @@ const MM = (function () { // haveAnimate for verify if we are using AninateCSS // we check AnimateCSS Array for validate it too - let haveAnimate = options.animate && _AnimateCSSIn[options.animate]; + const haveAnimate = options.animate && _AnimateCSSIn[options.animate]; if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. From a6a8ce87576e4c4760174c992d34ff1a1251455d Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 11 Jun 2023 18:07:20 +0200 Subject: [PATCH 13/19] add possibity to use animateIn and animateOut in module definition config * add animateIn and animateOut in module definition * use directly the name of the animation * option.animate use the name of animation * can't be override with option.animate if animateIn / animateOut are defined in module definition --- js/animateCSS.js | 197 +++++++++++++++++++++++------------------------ js/loader.js | 2 + js/main.js | 44 +++++++---- js/module.js | 7 +- 4 files changed, 132 insertions(+), 118 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index c53ca4ebea..49f36ad41d 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -7,126 +7,125 @@ /* enumeration of animations in Array **/ const _AnimateCSSIn = [ - null, // 0 not used (default MM animation) // Attention seekers - "bounce", // 1 - "flash", // 2 - "pulse", // 3 - "rubberBand", // 4 - "shakeX", // 5 - "shakeY", // 6 - "headShake", // 7 - "swing", // 8 - "tada", // 9 - "wobble", // 10 - "jello", // 11 - "heartBeat", // 12 + "bounce", + "flash", + "pulse", + "rubberBand", + "shakeX", + "shakeY", + "headShake", + "swing", + "tada", + "wobble", + "jello", + "heartBeat", // Back entrances - "backInDown", // 13 - "backInLeft", // 14 - "backInRight", // 15 - "backInUp", // 16 + "backInDown", + "backInLeft", + "backInRight", + "backInUp", // Bouncing entrances - "bounceIn", // 17 - "bounceInDown", // 18 - "bounceInLeft", // 19 - "bounceInRight", // 20 - "bounceInUp", // 21 + "bounceIn", + "bounceInDown", + "bounceInLeft", + "bounceInRight", + "bounceInUp", // Fading entrances - "fadeIn", // 22 - "fadeInDown", // 23 - "fadeInDownBig", // 24 - "fadeInLeft", // 25 - "fadeInLeftBig", // 26 - "fadeInRight", // 27 - "fadeInRightBig", // 28 - "fadeInUp", // 29 - "fadeInUpBig", // 30 - "fadeInTopLeft", // 31 - "fadeInTopRight", // 32 - "fadeInBottomLeft", // 33 - "fadeInBottomRight", // 34 + "fadeIn", + "fadeInDown", + "fadeInDownBig", + "fadeInLeft", + "fadeInLeftBig", + "fadeInRight", + "fadeInRightBig", + "fadeInUp", + "fadeInUpBig", + "fadeInTopLeft", + "fadeInTopRight", + "fadeInBottomLeft", + "fadeInBottomRight", // Flippers - "flip", // 35 - "flipInX", // 36 - "flipInY", // 37 + "flip", + "flipInX", + "flipInY", // Lightspeed - "lightSpeedInRight", // 38 - "lightSpeedInLeft", // 39 + "lightSpeedInRight", + "lightSpeedInLeft", // Rotating entrances - "rotateIn", // 40 - "rotateInDownLeft", // 41 - "rotateInDownRight", // 42 - "rotateInUpLeft", // 43 - "rotateInUpRight", // 44 + "rotateIn", + "rotateInDownLeft", + "rotateInDownRight", + "rotateInUpLeft", + "rotateInUpRight", // Specials - "jackInTheBox", // 45 - "rollIn", // 46 + "jackInTheBox", + "rollIn", // Zooming entrances - "zoomIn", // 47 - "zoomInDown", // 48 - "zoomInLeft", // 49 - "zoomInRight", // 50 - "zoomInUp", // 51 + "zoomIn", + "zoomInDown", + "zoomInLeft", + "zoomInRight", + "zoomInUp", // Sliding entrances - "slideInDown", // 52 - "slideInLeft", // 53 - "slideInRight", // 54 - "slideInUp" // 55 + "slideInDown", + "slideInLeft", + "slideInRight", + "slideInUp" ]; const _AnimateCSSOut = [ - null, // 0 not used (default MM animation) - "backOutDown", // 1 - "backOutLeft", // 2 - "backOutRight", // 3 - "backOutUp", // 4 + // Back exits + "backOutDown", + "backOutLeft", + "backOutRight", + "backOutUp", // Bouncing exits - "bounceOut", // 5 - "bounceOutDown", // 6 - "bounceOutLeft", // 7 - "bounceOutRight", // 8 - "bounceOutUp", // 9 + "bounceOut", + "bounceOutDown", + "bounceOutLeft", + "bounceOutRight", + "bounceOutUp", // Fading exits - "fadeOut", // 10 - "fadeOutDown", // 11 - "fadeOutDownBig", // 12 - "fadeOutLeft", // 13 - "fadeOutLeftBig", // 14 - "fadeOutRight", // 15 - "fadeOutRightBig", // 16 - "fadeOutUp", // 17 - "fadeOutUpBig", // 18 - "fadeOutTopLeft", // 19 - "fadeOutTopRight", // 20 - "fadeOutBottomRight", // 21 - "fadeOutBottomLeft", // 22 + "fadeOut", + "fadeOutDown", + "fadeOutDownBig", + "fadeOutLeft", + "fadeOutLeftBig", + "fadeOutRight", + "fadeOutRightBig", + "fadeOutUp", + "fadeOutUpBig", + "fadeOutTopLeft", + "fadeOutTopRight", + "fadeOutBottomRight", + "fadeOutBottomLeft", // Flippers - "flipOutX", // 23 - "flipOutY", // 24 + "flipOutX", + "flipOutY", // Lightspeed - "lightSpeedOutRight", // 25 - "lightSpeedOutLeft", // 26 + "lightSpeedOutRight", + "lightSpeedOutLeft", // Rotating exits - "rotateOut", // 27 - "rotateOutDownLeft", // 28 - "rotateOutDownRight", // 29 - "rotateOutUpLeft", // 30 - "rotateOutUpRight", // 31 + "rotateOut", + "rotateOutDownLeft", + "rotateOutDownRight", + "rotateOutUpLeft", + "rotateOutUpRight", // Specials - "hinge", // 32 - "rollOut", // 33 + "hinge", + "rollOut", // Zooming exits - "zoomOut", // 34 - "zoomOutDown", // 35 - "zoomOutLeft", // 36 - "zoomOutRight", // 37 - "zoomOutUp", // 38 + "zoomOut", + "zoomOutDown", + "zoomOutLeft", + "zoomOutRight", + "zoomOutUp", // Sliding exits - "slideOutDown", // 39 - "slideOutLeft", // 40 - "slideOutRight", // 41 - "slideOutUp" // 42 + "slideOutDown", + "slideOutLeft", + "slideOutRight", + "slideOutUp" ]; /** diff --git a/js/loader.js b/js/loader.js index 517999bb86..a5dc36fcab 100644 --- a/js/loader.js +++ b/js/loader.js @@ -88,6 +88,8 @@ const Loader = (function () { path: `${moduleFolder}/`, file: `${moduleName}.js`, position: moduleData.position, + animateIn: moduleData.animateIn, + animateOut: moduleData.animateOut, hiddenOnStartup: moduleData.hiddenOnStartup, header: moduleData.header, configDeepMerge: typeof moduleData.configDeepMerge === "boolean" ? moduleData.configDeepMerge : false, diff --git a/js/main.js b/js/main.js index 962ec8700b..8fc01cad68 100644 --- a/js/main.js +++ b/js/main.js @@ -245,20 +245,25 @@ const MM = (function () { if (moduleWrapper !== null) { clearTimeout(module.showHideTimer); - // haveAnimate for verify if we are using AninateCSS - // we check AnimateCSS Array for validate it too - const haveAnimate = options.animate && _AnimateCSSOut[options.animate]; - - if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + // 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) + var haveAnimateName = null; + // check if have valid animateOut in module definition + if (module.data.animateOut && _AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; + // can't be override with options.animate + else if (options.animate && _AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; + + if (!haveAnimateName) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; else { - Log.log(`${module.identifier} Has animateOut: ${haveAnimate}`); - await AnimateCSS(module.identifier, _AnimateCSSOut[options.animate], speed / 1000); + Log.log(`${module.identifier} Has animateOut: ${haveAnimateName}`); + await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); } moduleWrapper.style.opacity = 0; moduleWrapper.classList.add("hidden"); - if (!haveAnimate) { + if (!haveAnimateName) { module.showHideTimer = setTimeout(function () { // To not take up any space, we just make the position absolute. // since it's fade out anyway, we can see it lay above or @@ -327,11 +332,16 @@ const MM = (function () { if (moduleWrapper !== null) { clearTimeout(module.showHideTimer); - // haveAnimate for verify if we are using AninateCSS - // we check AnimateCSS Array for validate it too - const haveAnimate = options.animate && _AnimateCSSIn[options.animate]; + // haveAnimateName for verify if we are using AninateCSS library + // we check _AnimateCSSIn Array for validate it + // and finaly return the animate name or `null` (for default MM² animation) + var haveAnimateName = null; + // check if have valid animateOut in module definition (config.animateIn) + if (module.data.animateIn && _AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; + // can't be override with options.animate + else if (options.animate && _AnimateCSSIn.indexOf(options.animate) !== -1) haveAnimateName = options.animate; - if (!haveAnimate) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + if (!haveAnimateName) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. moduleWrapper.style.position = "static"; moduleWrapper.classList.remove("hidden"); @@ -342,15 +352,15 @@ const MM = (function () { const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; moduleWrapper.style.opacity = 1; - if (!haveAnimate) { + if (!haveAnimateName) { module.showHideTimer = setTimeout(function () { if (typeof callback === "function") { callback(); } }, speed); } else { - Log.log(`${module.identifier} Has animateIn: ${haveAnimate}`); - AnimateCSS(module.identifier, _AnimateCSSIn[options.animate], speed / 1000).then(() => { + Log.log(`${module.identifier} Has animateIn: ${haveAnimateName}`); + AnimateCSS(module.identifier, haveAnimateName, speed / 1000).then(() => { if (typeof callback === "function") { callback(); } @@ -558,8 +568,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The number of microseconds for the animation. - * @param {number} [animateOut] AnimateCss animation number before hidden - * @param {number} [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation name before hidden + * @param {number} [animateIn] AnimateCss animation name on show */ updateDom: function (module, speed, animateOut, animateIn) { if (!(module instanceof Module)) { diff --git a/js/module.js b/js/module.js index aaf8bc9bdd..b4a7c95c14 100644 --- a/js/module.js +++ b/js/module.js @@ -193,7 +193,7 @@ const Module = Class.extend({ }, /********************************************* - * The methods below don"t need subclassing. * + * The methods below don't need subclassing. * *********************************************/ /** @@ -205,6 +205,9 @@ const Module = Class.extend({ this.name = data.name; this.identifier = data.identifier; this.hidden = false; + // is it really useful? (not sure) + // this.animateIn = data.animateIn; + // this.animateOut = data.animateOut; this.setConfig(data.config, data.configDeepMerge); }, @@ -331,7 +334,7 @@ const Module = Class.extend({ * @param {number} [animateOut] AnimateCss animation number before hidden * @param {number} [animateIn] AnimateCss animation number on show */ - updateDom: function (speed, animateOut = 0, animateIn = 0) { + updateDom: function (speed, animateOut = null, animateIn = null) { MM.updateDom(this, speed, animateOut, animateIn); }, From 15bf1348591e353ac73a4cb33438a6d84d137a2c Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 11 Jun 2023 18:24:23 +0200 Subject: [PATCH 14/19] update change log // update fonctions definitions --- CHANGELOG.md | 1 + js/main.js | 8 ++++---- js/module.js | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb2fec4416..917d009f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ _This release is scheduled to be released on 2023-07-01._ - Set Timezone `Europe/Berlin` in unit tests (needed for new formatTime tests) - Added no-param-reassign eslint rule and fix warnings - Added optional AnimateCSS animate for `hide()`, `show()`, `updateDom()` +- Added AnimateIn and animateOut in module config definition ### Removed diff --git a/js/main.js b/js/main.js index 8fc01cad68..d0940f7565 100644 --- a/js/main.js +++ b/js/main.js @@ -102,8 +102,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The (optional) number of microseconds for the animation. - * @param {number} [animateOut] AnimateCss animation number before hidden - * @param {number} [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation name before hidden + * @param {number} [animateIn] AnimateCss animation name on show * @returns {Promise} Resolved when the dom is fully updated. */ const updateDom = function (module, speed, animateOut, animateIn) { @@ -132,8 +132,8 @@ const MM = (function () { * @param {number} [speed] The (optional) number of microseconds for the animation. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. - * @param {number} [animateOut] AnimateCss animation number before hidden - * @param {number} [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation name before hidden + * @param {number} [animateIn] AnimateCss animation name on show * @returns {Promise} Resolved when the module dom has been updated. */ const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn) { diff --git a/js/module.js b/js/module.js index b4a7c95c14..d0e476e04b 100644 --- a/js/module.js +++ b/js/module.js @@ -331,8 +331,8 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. * @param {number} [speed] The speed of the animation. - * @param {number} [animateOut] AnimateCss animation number before hidden - * @param {number} [animateIn] AnimateCss animation number on show + * @param {number} [animateOut] AnimateCss animation name before hidden + * @param {number} [animateIn] AnimateCss animation name on show */ updateDom: function (speed, animateOut = null, animateIn = null) { MM.updateDom(this, speed, animateOut, animateIn); From f5e2a8dad31b80f816b84558830c93b5a4b6268a Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sun, 11 Jun 2023 21:09:44 +0200 Subject: [PATCH 15/19] Apply AnimateIn rules on the first start --- CHANGELOG.md | 1 + js/main.js | 44 ++++++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 917d009f68..bd96e0c22e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ _This release is scheduled to be released on 2023-07-01._ - Added no-param-reassign eslint rule and fix warnings - Added optional AnimateCSS animate for `hide()`, `show()`, `updateDom()` - Added AnimateIn and animateOut in module config definition +- Apply AnimateIn rules on the first start ### Removed diff --git a/js/main.js b/js/main.js index d0940f7565..8bdda26390 100644 --- a/js/main.js +++ b/js/main.js @@ -22,6 +22,10 @@ const MM = (function () { return; } + var haveAnimateIn = null; + // check if have valid animateIn in module definition (module.data.animateIn) + if (module.data.animateIn && _AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateIn = module.data.animateIn; + const wrapper = selectWrapper(module.data.position); const dom = document.createElement("div"); @@ -50,7 +54,12 @@ const MM = (function () { moduleContent.className = "module-content"; dom.appendChild(moduleContent); - const domCreationPromise = updateDom(module, 0); + // create the domCreationPromise with AnimateCSS (with animateIn of module definition) + // or just display it + var domCreationPromise; + if (haveAnimateIn) domCreationPromise = updateDom(module, 500, null, null, true); + else domCreationPromise = updateDom(module, 0); + domCreationPromises.push(domCreationPromise); domCreationPromise .then(function () { @@ -102,11 +111,12 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The (optional) number of microseconds for the animation. - * @param {number} [animateOut] AnimateCss animation name before hidden - * @param {number} [animateIn] AnimateCss animation name on show + * @param {string} [animateOut] AnimateCss animation name before hidden + * @param {string} [animateIn] AnimateCss animation name on show + * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start) * @returns {Promise} Resolved when the dom is fully updated. */ - const updateDom = function (module, speed, animateOut, animateIn) { + const updateDom = function (module, speed, animateOut, animateIn, createAnimatedDom = false) { return new Promise(function (resolve) { const newHeader = module.getHeader(); let newContentPromise = module.getDom(); @@ -118,7 +128,7 @@ const MM = (function () { newContentPromise .then(function (newContent) { - const updatePromise = updateDomWithContent(module, speed, newHeader, newContent, animateOut, animateIn); + const updatePromise = updateDomWithContent(module, speed, newHeader, newContent, animateOut, animateIn, createAnimatedDom); updatePromise.then(resolve).catch(Log.error); }) @@ -132,11 +142,12 @@ const MM = (function () { * @param {number} [speed] The (optional) number of microseconds for the animation. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. - * @param {number} [animateOut] AnimateCss animation name before hidden - * @param {number} [animateIn] AnimateCss animation name on show + * @param {string} [animateOut] AnimateCss animation name before hidden + * @param {string} [animateIn] AnimateCss animation name on show + * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start) * @returns {Promise} Resolved when the module dom has been updated. */ - const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn) { + const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn, createAnimatedDom = false) { return new Promise(function (resolve) { if (module.hidden || !speed) { updateModuleContent(module, newHeader, newContent); @@ -155,6 +166,15 @@ const MM = (function () { return; } + if (createAnimatedDom) { + updateModuleContent(module, newHeader, newContent); + if (!module.hidden) { + showModule(module, speed, null, { animate: animateIn }); + } + resolve(); + return; + } + hideModule( module, speed / 2, @@ -249,7 +269,7 @@ const MM = (function () { // we check _AnimateCSSOut Array for validate it // and finaly return the animate name or `null` (for default MM² animation) var haveAnimateName = null; - // check if have valid animateOut in module definition + // check if have valid animateOut in module definition (module.data.animateOut) if (module.data.animateOut && _AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; // can't be override with options.animate else if (options.animate && _AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; @@ -336,7 +356,7 @@ const MM = (function () { // we check _AnimateCSSIn Array for validate it // and finaly return the animate name or `null` (for default MM² animation) var haveAnimateName = null; - // check if have valid animateOut in module definition (config.animateIn) + // check if have valid animateOut in module definition (module.data.animateIn) if (module.data.animateIn && _AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; // can't be override with options.animate else if (options.animate && _AnimateCSSIn.indexOf(options.animate) !== -1) haveAnimateName = options.animate; @@ -568,8 +588,8 @@ const MM = (function () { * Update the dom for a specific module. * @param {Module} module The module that needs an update. * @param {number} [speed] The number of microseconds for the animation. - * @param {number} [animateOut] AnimateCss animation name before hidden - * @param {number} [animateIn] AnimateCss animation name on show + * @param {string} [animateOut] AnimateCss animation name before hidden + * @param {string} [animateIn] AnimateCss animation name on show */ updateDom: function (module, speed, animateOut, animateIn) { if (!(module instanceof Module)) { From c3e271949d2b566378f207eef55117387febe0f0 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Sat, 2 Sep 2023 12:25:00 +0200 Subject: [PATCH 16/19] review animateCSS rules --- js/main.js | 56 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/js/main.js b/js/main.js index 8bdda26390..58e521c2cd 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, 500, null, null, true); + if (haveAnimateIn) domCreationPromise = updateDom(module, 1000, null, haveAnimateIn, true); else domCreationPromise = updateDom(module, 0); domCreationPromises.push(domCreationPromise); @@ -166,7 +166,8 @@ const MM = (function () { return; } - if (createAnimatedDom) { + if (createAnimatedDom && animateIn !== null) { + // Log.log(`${module.identifier} createAnimatedDom (${animateIn})`); updateModuleContent(module, newHeader, newContent); if (!module.hidden) { showModule(module, speed, null, { animate: animateIn }); @@ -274,16 +275,24 @@ const MM = (function () { // can't be override with options.animate else if (options.animate && _AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; - if (!haveAnimateName) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; - else { - Log.log(`${module.identifier} Has animateOut: ${haveAnimateName}`); + if (haveAnimateName) { + // with AnimateCSS + // Log.log(`${module.identifier} Has animateOut: ${haveAnimateName}`); await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); - } - - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); + // AnimateCSS is now done + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + moduleWrapper.style.position = "fixed"; - if (!haveAnimateName) { + updateWrapperStates(); + if (typeof callback === "function") { + callback(); + } + } else { + // default MM² Animate + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); module.showHideTimer = setTimeout(function () { // To not take up any space, we just make the position absolute. // since it's fade out anyway, we can see it lay above or @@ -297,14 +306,6 @@ const MM = (function () { callback(); } }, speed); - } else { - // AnimateCSS is now done - moduleWrapper.style.position = "fixed"; - - updateWrapperStates(); - if (typeof callback === "function") { - callback(); - } } } else { // invoke callback even if no content, issue 1308 @@ -321,7 +322,7 @@ const MM = (function () { * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - const showModule = function (module, speed, callback, options = {}) { + const showModule = async function (module, speed, callback, options = {}) { // remove lockString if set in options. if (options.lockString) { const index = module.lockStrings.indexOf(options.lockString); @@ -372,19 +373,20 @@ const MM = (function () { const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; moduleWrapper.style.opacity = 1; - if (!haveAnimateName) { + if (haveAnimateName) { + // with AnimateCSS + // Log.log(`${module.identifier} Has animateIn: ${haveAnimateName}`); + await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); + if (typeof callback === "function") { + callback(); + } + } else { + // default MM² Animate module.showHideTimer = setTimeout(function () { if (typeof callback === "function") { callback(); } }, speed); - } else { - Log.log(`${module.identifier} Has animateIn: ${haveAnimateName}`); - AnimateCSS(module.identifier, haveAnimateName, speed / 1000).then(() => { - if (typeof callback === "function") { - callback(); - } - }); } } else { // invoke callback From 2f6ed13386998da4918db5ab373c02cbb84136f6 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Wed, 6 Sep 2023 18:36:21 +0200 Subject: [PATCH 17/19] some correct needed (see logs) and add updateDom object option * (animateCSS.js) `_AnimateCSSIn` -> `AnimateCSSIn` * (animateCSS.js) `_AnimateCSSOut` -> `AnimateCSSOut` * (main.js) Rename `AnimateCSSOut` and `AnimateCSSIn` in accord with animateCSS.js * (main.js) Add Log.debug in animate functionality * (main.js) correct var haveAnimateName to let haveAnimateName * (main.js) Add options object for updateDom() for control speed and animate * (module.js) change value name speed -> updateOptions for more visibility and in accord with new functionality --- js/animateCSS.js | 4 ++-- js/main.js | 52 +++++++++++++++++++++++++++++++----------------- js/module.js | 11 +++------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/js/animateCSS.js b/js/animateCSS.js index 49f36ad41d..ae6e7bec7b 100644 --- a/js/animateCSS.js +++ b/js/animateCSS.js @@ -6,7 +6,7 @@ */ /* enumeration of animations in Array **/ -const _AnimateCSSIn = [ +const AnimateCSSIn = [ // Attention seekers "bounce", "flash", @@ -74,7 +74,7 @@ const _AnimateCSSIn = [ "slideInUp" ]; -const _AnimateCSSOut = [ +const AnimateCSSOut = [ // Back exits "backOutDown", "backOutLeft", diff --git a/js/main.js b/js/main.js index 58e521c2cd..8e909f5161 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,4 @@ -/* global Loader, defaults, Translator, AnimateCSS, _AnimateCSSIn, _AnimateCSSOut */ +/* global Loader, defaults, Translator, AnimateCSS, AnimateCSSIn, AnimateCSSOut */ /* MagicMirror² * Main System @@ -22,9 +22,9 @@ const MM = (function () { return; } - var haveAnimateIn = null; + let haveAnimateIn = null; // check if have valid animateIn in module definition (module.data.animateIn) - if (module.data.animateIn && _AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateIn = module.data.animateIn; + if (module.data.animateIn && AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateIn = module.data.animateIn; const wrapper = selectWrapper(module.data.position); @@ -110,14 +110,30 @@ const MM = (function () { /** * Update the dom for a specific module. * @param {Module} module The module that needs an update. - * @param {number} [speed] The (optional) number of microseconds for the animation. - * @param {string} [animateOut] AnimateCss animation name before hidden - * @param {string} [animateIn] AnimateCss animation name on show - * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start) + * @param {object|number} [updateOptions] The (optional) number of microseconds for the animation or object with updateOptions (speed/animates) + * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start of MagicMirror) * @returns {Promise} Resolved when the dom is fully updated. */ - const updateDom = function (module, speed, animateOut, animateIn, createAnimatedDom = false) { + const updateDom = function (module, updateOptions, createAnimatedDom = false) { return new Promise(function (resolve) { + let speed = updateOptions; + let animateOut = null; + let animateIn = null; + if (typeof updateOptions === "object") { + if (typeof updateOptions.options === "object" && updateOptions.options.speed !== undefined) { + speed = updateOptions.options.speed; + Log.debug(`updateDom: ${module.identifier} Has speed in object: ${speed}`); + if (typeof updateOptions.options.animate === "object") { + animateOut = updateOptions.options.animate.out; + animateIn = updateOptions.options.animate.in; + Log.debug(`updateDom: ${module.identifier} Has animate in object: out->${animateOut}, in->${animateIn}`); + } + } else { + Log.debug(`updateDom: ${module.identifier} Has no speed in object`); + speed = 0; + } + } + const newHeader = module.getHeader(); let newContentPromise = module.getDom(); @@ -167,7 +183,7 @@ const MM = (function () { } if (createAnimatedDom && animateIn !== null) { - // Log.log(`${module.identifier} createAnimatedDom (${animateIn})`); + Log.debug(`${module.identifier} createAnimatedDom (${animateIn})`); updateModuleContent(module, newHeader, newContent); if (!module.hidden) { showModule(module, speed, null, { animate: animateIn }); @@ -267,17 +283,17 @@ const MM = (function () { clearTimeout(module.showHideTimer); // haveAnimateName for verify if we are using AninateCSS library - // we check _AnimateCSSOut Array for validate it + // we check AnimateCSSOut Array for validate it // and finaly return the animate name or `null` (for default MM² animation) var haveAnimateName = null; // check if have valid animateOut in module definition (module.data.animateOut) - if (module.data.animateOut && _AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; + if (module.data.animateOut && AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; // can't be override with options.animate - else if (options.animate && _AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; + else if (options.animate && AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; if (haveAnimateName) { // with AnimateCSS - // Log.log(`${module.identifier} Has animateOut: ${haveAnimateName}`); + Log.debug(`${module.identifier} Has animateOut: ${haveAnimateName}`); await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); // AnimateCSS is now done moduleWrapper.style.opacity = 0; @@ -354,13 +370,13 @@ const MM = (function () { clearTimeout(module.showHideTimer); // haveAnimateName for verify if we are using AninateCSS library - // we check _AnimateCSSIn Array for validate it + // we check AnimateCSSIn Array for validate it // and finaly return the animate name or `null` (for default MM² animation) - var haveAnimateName = null; + let haveAnimateName = null; // check if have valid animateOut in module definition (module.data.animateIn) - if (module.data.animateIn && _AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; + if (module.data.animateIn && AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; // can't be override with options.animate - else if (options.animate && _AnimateCSSIn.indexOf(options.animate) !== -1) haveAnimateName = options.animate; + else if (options.animate && AnimateCSSIn.indexOf(options.animate) !== -1) haveAnimateName = options.animate; if (!haveAnimateName) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. @@ -375,7 +391,7 @@ const MM = (function () { if (haveAnimateName) { // with AnimateCSS - // Log.log(`${module.identifier} Has animateIn: ${haveAnimateName}`); + Log.debug(`${module.identifier} Has animateIn: ${haveAnimateName}`); await AnimateCSS(module.identifier, haveAnimateName, speed / 1000); if (typeof callback === "function") { callback(); diff --git a/js/module.js b/js/module.js index d0e476e04b..62534b0178 100644 --- a/js/module.js +++ b/js/module.js @@ -205,9 +205,6 @@ const Module = Class.extend({ this.name = data.name; this.identifier = data.identifier; this.hidden = false; - // is it really useful? (not sure) - // this.animateIn = data.animateIn; - // this.animateOut = data.animateOut; this.setConfig(data.config, data.configDeepMerge); }, @@ -330,12 +327,10 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. - * @param {number} [speed] The speed of the animation. - * @param {number} [animateOut] AnimateCss animation name before hidden - * @param {number} [animateIn] AnimateCss animation name on show + * @param {number|object} [updateOptions] The speed of the animation or object with for updateOptions (speed/animates) */ - updateDom: function (speed, animateOut = null, animateIn = null) { - MM.updateDom(this, speed, animateOut, animateIn); + updateDom: function (updateOptions) { + MM.updateDom(this, updateOptions); }, /** From a405b26a0632c1f2558315f96a4e4f9e923384d6 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Wed, 6 Sep 2023 20:05:37 +0200 Subject: [PATCH 18/19] missing new definition --- js/main.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/js/main.js b/js/main.js index 8e909f5161..bf0c1c405b 100644 --- a/js/main.js +++ b/js/main.js @@ -605,11 +605,9 @@ const MM = (function () { /** * Update the dom for a specific module. * @param {Module} module The module that needs an update. - * @param {number} [speed] The number of microseconds for the animation. - * @param {string} [animateOut] AnimateCss animation name before hidden - * @param {string} [animateIn] AnimateCss animation name on show + * @param {object|number} [updateOptions] The (optional) number of microseconds for the animation or object with updateOptions (speed/animates) */ - updateDom: function (module, speed, animateOut, animateIn) { + updateDom: function (module, updateOptions) { if (!(module instanceof Module)) { Log.error("updateDom: Sender should be a module."); return; @@ -621,7 +619,7 @@ const MM = (function () { } // Further implementation is done in the private method. - updateDom(module, speed, animateOut, animateIn); + updateDom(module, updateOptions); }, /** From ffa2f5d017fd1290d3deeed89d1ab02e977f7045 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Wed, 6 Sep 2023 20:11:14 +0200 Subject: [PATCH 19/19] correct var -> let --- js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index bf0c1c405b..5efce70abe 100644 --- a/js/main.js +++ b/js/main.js @@ -285,7 +285,7 @@ const MM = (function () { // 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) - var haveAnimateName = null; + let haveAnimateName = null; // check if have valid animateOut in module definition (module.data.animateOut) if (module.data.animateOut && AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; // can't be override with options.animate