From 8733f159f9f3443b6fd859030ce41000e474b9de Mon Sep 17 00:00:00 2001 From: Julian Prieber <60265788+JulianPrieber@users.noreply.github.com> Date: Wed, 14 Sep 2022 13:11:38 +0200 Subject: [PATCH] Added animation Credit: https://codepen.io/chriscoyier/pen/XWNqxyY --- resources/views/studio/theme.blade.php | 124 ++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/resources/views/studio/theme.blade.php b/resources/views/studio/theme.blade.php index ca3b669..ff4ac53 100644 --- a/resources/views/studio/theme.blade.php +++ b/resources/views/studio/theme.blade.php @@ -121,7 +121,7 @@ table, th, td {


Theme updater -
+
@@ -232,7 +232,127 @@ try{ if($GLOBALS['updateAv'] == true) echo ' element + this.content = el.querySelector('.content'); + + // Store the animation object (so we can cancel it if needed) + this.animation = null; + // Store if the element is closing + this.isClosing = false; + // Store if the element is expanding + this.isExpanding = false; + // Detect user clicks on the summary element + this.summary.addEventListener('click', (e) => this.onClick(e)); + } + + onClick(e) { + // Stop default behaviour from the browser + e.preventDefault(); + // Add an overflow on the
to avoid content overflowing + this.el.style.overflow = 'hidden'; + // Check if the element is being closed or is already closed + if (this.isClosing || !this.el.open) { + this.open(); + // Check if the element is being openned or is already open + } else if (this.isExpanding || this.el.open) { + this.shrink(); + } + } + + shrink() { + // Set the element as "being closed" + this.isClosing = true; + + // Store the current height of the element + const startHeight = `${this.el.offsetHeight}px`; + // Calculate the height of the summary + const endHeight = `${this.summary.offsetHeight}px`; + + // If there is already an animation running + if (this.animation) { + // Cancel the current animation + this.animation.cancel(); + } + + // Start a WAAPI animation + this.animation = this.el.animate({ + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight] + }, { + duration: 400, + easing: 'ease-out' + }); + + // When the animation is complete, call onAnimationFinish() + this.animation.onfinish = () => this.onAnimationFinish(false); + // If the animation is cancelled, isClosing variable is set to false + this.animation.oncancel = () => this.isClosing = false; + } + + open() { + // Apply a fixed height on the element + this.el.style.height = `${this.el.offsetHeight}px`; + // Force the [open] attribute on the details element + this.el.open = true; + // Wait for the next frame to call the expand function + window.requestAnimationFrame(() => this.expand()); + } + + expand() { + // Set the element as "being expanding" + this.isExpanding = true; + // Get the current fixed height of the element + const startHeight = `${this.el.offsetHeight}px`; + // Calculate the open height of the element (summary height + content height) + const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`; + + // If there is already an animation running + if (this.animation) { + // Cancel the current animation + this.animation.cancel(); + } + + // Start a WAAPI animation + this.animation = this.el.animate({ + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight] + }, { + duration: 400, + easing: 'ease-out' + }); + // When the animation is complete, call onAnimationFinish() + this.animation.onfinish = () => this.onAnimationFinish(true); + // If the animation is cancelled, isExpanding variable is set to false + this.animation.oncancel = () => this.isExpanding = false; + } + + onAnimationFinish(open) { + // Set the open attribute based on the parameter + this.el.open = open; + // Clear the stored animation + this.animation = null; + // Reset isClosing & isExpanding + this.isClosing = false; + this.isExpanding = false; + // Remove the overflow hidden and the fixed height + this.el.style.height = this.el.style.overflow = ''; + } +} + +document.querySelectorAll('details').forEach((el) => { + new Accordion(el); +}); + + + @endif @endforeach
Theme name: