diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index 73e36241..fab03a92 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -13,7 +13,6 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DhCountdowns extends HandlebarsApplicationMixin(ApplicationV2) { previousCountdownData = null; changedCountdownsForAnimation = new Set(); - countdownChangeAnimationTimeout = null; constructor(options = {}) { super(options); @@ -95,35 +94,41 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application .countdowns; /* Handle animations to draw attention to countdown values changing */ - if (this.changedCountdownsForAnimation.size) { - if (this.countdownChangeAnimationTimeout) - clearTimeout(this.countdownChangeAnimationTimeout); + const typesToAnimate = new Set(); + for (const countdownKey of this.changedCountdownsForAnimation) { + const shimmerAnimation = [ + { backgroundPositionX: '98%' }, + { backgroundPositionX: '0%' } + ]; + const shimmerTiming = { + duration: 1000, + iterations: 1 + }; - this.countdownChangeAnimationTimeout = setTimeout(() => { - this.changedCountdownsForAnimation.clear(); - const selector = '.countdown-container, .header-type-toggles .header-type'; - for (const element of this.element.querySelectorAll(selector)) { - element.classList.remove('change-glow'); - } - }, 3000); + const element = this.element.querySelector(`.countdown-container[data-countdown="${countdownKey}"]`); + element.animate(shimmerAnimation, shimmerTiming); - /* If the countdown is not currently visible, add a glow to the CountdownType pill */ - const visibleTypes = this.visibleCountdownTypes; - for (const countdownKey of this.changedCountdownsForAnimation) { - const countdown = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns) - .countdowns[countdownKey]; - if (!visibleTypes.includes(countdown?.type)) { - this.element.querySelector(`.header-type-toggles .header-type[data-type="${countdown.type}"]`) - .classList.add('change-glow'); - } - - /* If the countdown element is not rendered the user doesn't have permissions to it. No animation needed on the elment itself */ - const countdownElement = this.element.querySelector(`.countdown-container[data-countdown="${countdownKey}"]`); - if (!countdownElement) continue; - - countdownElement.classList.add('change-glow'); - } + const countdown = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns) + .countdowns[countdownKey]; + if (!this.visibleCountdownTypes.includes(countdown?.type)) + typesToAnimate.add(countdown.type); } + + for (const type of typesToAnimate) { + const pulseAnimation = [ + { boxShadow: '0 0 1px 1px var(--golden)' }, + { boxShadow: '0 0 2px 2px var(--golden)' } + ]; + const pulseTiming = { + duration: 1000, + iterations: 3 + }; + + const element = this.element.querySelector(`.header-type-toggles .header-type[data-type="${type}"]`); + element.animate(pulseAnimation, pulseTiming); + } + + this.changedCountdownsForAnimation.clear(); } /** Returns countdown data filtered by ownership */ diff --git a/module/data/countdowns.mjs b/module/data/countdowns.mjs index 6630c302..8e55ed31 100644 --- a/module/data/countdowns.mjs +++ b/module/data/countdowns.mjs @@ -25,7 +25,8 @@ export default class DhCountdowns extends foundry.abstract.DataModel { return acc; }, []); - foundry.ui.countdowns.changedCountdownsForAnimation.add(...changedCountdowns); + for (const countdownKey of changedCountdowns) + foundry.ui.countdowns.changedCountdownsForAnimation.add(countdownKey); } } diff --git a/styles/less/ui/countdown/countdown.less b/styles/less/ui/countdown/countdown.less index d7cc83ff..96e01ffd 100644 --- a/styles/less/ui/countdown/countdown.less +++ b/styles/less/ui/countdown/countdown.less @@ -88,10 +88,6 @@ &.inactive { opacity: 0.4; } - - &.change-glow { - animation: glow 1s ease-in-out infinite; - } } } } @@ -118,13 +114,9 @@ display: flex; width: 100%; border-radius: 6px; - - &.change-glow { - animation: shimmer 1s ease-out; - background: linear-gradient(-45deg, transparent 30%, light-dark(@dark-blue-40, @golden-40) 35%, transparent 40%); - background-size: 300%; - background-position-x: 100% - } + background: linear-gradient(-45deg, transparent 30%, light-dark(@dark-blue-40, @golden-40) 35%, transparent 40%); + background-size: 300%; + background-position-x: 100%; &.icon-only { gap: 8px; @@ -225,23 +217,4 @@ // } } } - - @keyframes glow { - 0% { - box-shadow: 0 0 1px 1px @golden; - } - - 100% { - box-shadow: 0 0 2px 2px @golden; - } - } - - @keyframes shimmer { - from { - background-position-x: 98%; - } - to { - background-position-x: 0% - } - } }