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; +}