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
-
+
Theme name: |
@@ -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