diff --git a/public/graphics/app-icon b/public/graphics/app-icon
new file mode 100644
index 0000000..1b0adb9
--- /dev/null
+++ b/public/graphics/app-icon
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/public/graphics/app-icon.svg b/public/graphics/app-icon.svg
new file mode 100644
index 0000000..ddc0896
--- /dev/null
+++ b/public/graphics/app-icon.svg
@@ -0,0 +1,72 @@
+
+
+
+
diff --git a/public/index.html b/public/index.html
index e24059d..10f2d72 100644
--- a/public/index.html
+++ b/public/index.html
@@ -5,6 +5,7 @@
LED Cube
+
@@ -39,6 +40,22 @@
+
+
+
+
+
+
diff --git a/public/index.js b/public/index.js
index b75c5d5..6581c50 100644
--- a/public/index.js
+++ b/public/index.js
@@ -216,6 +216,13 @@ const FrameMenu = function (id) {
this.htmlButtonToggleAnimation = this.html.querySelector('#button-toggle-animation');
this.htmlButtonDeleteFrame = this.html.querySelector('#button-delete-frame');
this.htmlInputDuration = this.html.querySelector('#frame-duration');
+ this.htmlMenuGlobalDuration = this.html.querySelector('#global-duration-popup');
+ this.htmlButtonGlobalDuration = this.html.querySelector('#button-scale-duration');
+ this.htmlGlobalDurationSlider = this.html.querySelector('#global-duration-slider');
+ this.htmlGlobalDurationValue = this.html.querySelector('#global-duration-value');
+ this.htmlButtonChangeGlobalDuration = this.html.querySelector('#button-change-global-duration');
+ this.htmlButtonCloseGlobalDurationPopup = this.html.querySelector('#button-close-menu');
+
this.isAnimationPlaying = false;
@@ -267,6 +274,34 @@ const FrameMenu = function (id) {
}
);
+ this.htmlButtonGlobalDuration.addEventListener(
+ 'click',
+ () => {
+ this.htmlMenuGlobalDuration.style.display = 'inherit';
+ }
+ );
+
+ this.htmlGlobalDurationSlider.addEventListener(
+ 'input',
+ () => {
+ this.htmlGlobalDurationValue.innerText = this.htmlGlobalDurationSlider.value;
+ }
+ );
+
+ this.htmlButtonChangeGlobalDuration.addEventListener(
+ 'click',
+ () => {
+ this.onChangeGlobalDuration();
+ }
+ );
+
+ this.htmlButtonCloseGlobalDurationPopup.addEventListener(
+ 'click',
+ () => {
+ this.htmlMenuGlobalDuration.style.display = 'none';
+ }
+ )
+
this.slideToFrame = function (frameIndex) {
this.htmlSlider.value = frameIndex + 1;
this._updateFramePosition();
@@ -300,6 +335,8 @@ const FrameMenu = function (id) {
this.onToggleAnimation = function () {}
+ this.onChangeGlobalDuration = function () {}
+
this._increaseSliderMax = function () {
const frameNumber = parseInt(this.htmlSlider.max) + 1;
@@ -445,4 +482,15 @@ frameMenu.onFrameDelete = () => {
cube.currentFrame = cube.currentFrame < 0 ? 0 : cube.currentFrame;
frameMenu.slideToFrame(cube.currentFrame);
+}
+frameMenu.onChangeGlobalDuration = () => {
+ const factor = frameMenu.htmlGlobalDurationSlider.value / 100;
+
+ for (const frame of cube.frames) {
+ frame.duration *= factor;
+ }
+
+ frameMenu.htmlInputDuration.value = cube.frames[cube.currentFrame].duration;
+ frameMenu.htmlMenuGlobalDuration.style.display = 'none';
+ frameMenu,htmlGlobalDurationSlider.value = 100;
}
\ No newline at end of file
diff --git a/public/style.css b/public/style.css
index 8ed8bf4..084e09f 100644
--- a/public/style.css
+++ b/public/style.css
@@ -7,8 +7,10 @@ html {
}
body {
+ position: absolute;
width: 100%;
- height: 100%;
+ top: 0;
+ bottom: 0;
padding: 0;
margin: 0;
background-color: black;
@@ -92,9 +94,18 @@ button:hover {
justify-content: center;
align-items: center;
background-color: black;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
}
#animation-window {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 50px;
display: flex;
justify-content: center;
align-items: center;
@@ -106,6 +117,12 @@ button:hover {
padding: 20px;
display: flex;
align-items: center;
+ z-index: 1;
+}
+
+#frame-menu {
+ position: relative;
+ background-color: black;
}
#header-menu {
@@ -129,7 +146,7 @@ button:hover {
#cube {
display: block;
- padding-bottom: 80px;
+ padding-bottom: 200px;
}
.layer {
@@ -185,6 +202,7 @@ button:hover {
.selector-display {
padding-right: 40px;
+ background-color: black;
background-image: url("graphics/icon-dropdown.svg");
background-repeat: no-repeat;
background-size: auto 8px;
@@ -274,4 +292,77 @@ button:hover {
.row {
display: flex;
-}
\ No newline at end of file
+}
+
+.menu-fullscreen {
+ background-color: rgba(0, 0, 0, 0.7);
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ display: none;
+ justify-content: center;
+ align-items: center;
+}
+
+.submenu-popup {
+ display: none;
+ background-color: #091c59;
+ padding: 20px;
+ border: 2px solid white;
+ border-radius: 20px;
+ position: absolute;
+ right: -143px;
+ bottom: 57px;
+ box-shadow: 0 0 10px black;}
+
+.submenu-popup::before {
+ position: absolute;
+ content: '';
+ width: 0;
+ height: 0;
+ bottom: -20px;
+ right: 50%;
+ border-width: 10px;
+ border-style: solid;
+ border-color: #091c59 #091c59 transparent transparent;
+ filter: drop-shadow(0 2px 0 white);
+}
+
+.submenu-popup::after {
+ position: absolute;
+ content: '';
+ width: 0;
+ height: 0;
+ bottom: -20px;
+ left: 50%;
+ border-width: 10px;
+ border-style: solid;
+ border-color: #091c59 transparent transparent #091c59;
+ filter: drop-shadow(0 2px 0 white);
+}
+
+.value-slider {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 10px;
+}
+
+.container-slider-value {
+ display: inline-block;
+ width: 55px;
+}
+.slider-value {
+ margin-left: 10px;
+}
+
+.menu-fullscreen-button-line {
+ display: flex;
+ justify-content: space-between;
+}
+
+#duration-scale {
+ position: relative;
+}