diff --git a/index.html b/index.html index d84f515..1c5cb53 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@
' const SVG_DOWNLOAD_SCREENSHOT_BUTTON = '' - +const SVG_LOADING_CUBE = '' class FigniViewerElement extends ModelViewerElement { static #MODEL_ATTRIBUTE = ['item-id', 'token', 'model-tag'] static #TOOL_ATTRIBUTE = ['screenshot'] @@ -119,27 +119,38 @@ class FigniViewerElement extends ModelViewerElement { this.minCameraOrbit = FigniViewerElement.#MIN_CAMERA_ORBIT const loadingAnimationHolder = document.createElement('div') + const loadingAnimation = document.createElement('div') + const cubes = document.createElement('div') const progressBarHolder = document.createElement('span') this.#progressBar = document.createElement('span') - const loadingAnimationSpinner = document.createElement('span') + const loadingText = document.createElement('span') + for (let i = 0; i < 4; i++) { + const cube = document.createElement('div') + cube.innerHTML = SVG_LOADING_CUBE + cube.classList.add('figni-viewer-cube') + cube.classList.add(`figni-viewer-cube${i + 1}`) + cubes.appendChild(cube) + } + loadingText.innerText = 'LOADING' loadingAnimationHolder.setAttribute('slot', 'progress-bar') this.#progressBar.classList.add('figni-viewer-progress-bar') progressBarHolder.classList.add('figni-viewer-progress-bar-holder') - loadingAnimationSpinner.classList.add('figni-viewer-loading-animation-spinner') + cubes.classList.add('figni-viewer-cubes') + loadingAnimation.classList.add('figni-viewer-loading-animation') + loadingText.classList.add('figni-viewer-loading-text') loadingAnimationHolder.classList.add('figni-viewer-loading-animation-holder') this.addEventListener('progress', (e) => { const p = e.detail.totalProgress this.#progressBar.style.setProperty('--progress-bar-width', `${Math.ceil(p * 100)}%`) if (p === 1) { loadingAnimationHolder.classList.add('figni-viewer-loading-animation-hide') - if (loadingAnimationHolder.style.opacity === 0) { - loadingAnimationHolder.style.display = 'none' - } } }) progressBarHolder.appendChild(this.#progressBar) - loadingAnimationHolder.appendChild(loadingAnimationSpinner) + loadingAnimation.appendChild(cubes) + loadingAnimationHolder.appendChild(loadingAnimation) loadingAnimationHolder.appendChild(progressBarHolder) + loadingAnimationHolder.appendChild(loadingText) this.appendChild(loadingAnimationHolder) // 値の取得 @@ -588,7 +599,7 @@ class FigniViewerElement extends ModelViewerElement { if (panel.dataset.vertical == 'middle') { panel.style.maxHeight = `calc(${Number( window.getComputedStyle(this).height.slice(0, -2) - )}px - 4rem )` + )}px - 5rem )` } else { panel.style.maxHeight = `calc(${ Number(window.getComputedStyle(this).height.slice(0, -2)) / 2 diff --git a/src/style.scss b/src/style.scss index e06be4f..70f6fbb 100644 --- a/src/style.scss +++ b/src/style.scss @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&family=Spartan:wght@700&display=swap'); :root { --figni-viewer-primary: rgb(255, 115, 59); @@ -14,6 +14,8 @@ --figni-viewer-link: rgb(59, 94, 255); --figni-viewer-button: rgb(59, 94, 255); --figni-viewer-button-tp: rgba(59, 94, 255, 0.8); + --figni-viewer-contents-font: 'Noto Sans JP', sans-serif; + --figni-viewer-ui-font: 'Spartan', 'Noto Sans JP', sans-serif; } figni-viewer { @@ -22,7 +24,7 @@ figni-viewer { } figni-viewer * { - font-family: 'Noto Sans JP', sans-serif; + font-family: var(--figni-viewer-contents-font); color: var(--figni-viewer-black); } @@ -280,8 +282,8 @@ figni-viewer * { .figni-viewer-ar-button span { display: block; - line-height: 1.5; color: rgb(255, 115, 59); + font-family: var(--figni-viewer-ui-font); } .figni-viewer-panel-hide { @@ -336,6 +338,7 @@ figni-viewer * { transform: translate(-50%, -50%); z-index: 9999; pointer-events: none; + transition: opacity 0.3s ease-out; } .figni-viewer-progress-bar-holder { @@ -343,7 +346,7 @@ figni-viewer * { max-width: 10rem; width: 100%; height: 0.5rem; - background-color: var(--figni-viewer-gray-100); + background-color: var(--figni-viewer-gray-300-tp); overflow: hidden; border-radius: 0.25rem; } @@ -356,71 +359,108 @@ figni-viewer * { transition: all 0.5s cubic-bezier(0, 1, 0.3, 1); } -.figni-viewer-loading-animation-spinner { - display: block; - width: 5rem; - height: 5rem; - margin-top: 3.5rem; - margin-bottom: 3rem; - background-color: var(--figni-viewer-gray-300); - border-radius: 0.5rem; - -webkit-animation: sk-rotateplane 1.5s infinite cubic-bezier(0, 1, 0.3, 1); - animation: sk-rotateplane 1.5s infinite cubic-bezier(0, 1, 0.3, 1); +$w: 40px; +$h: 46.6px; +$xspace: $w/2; +$yspace: $h/4 - 1; +$speed: 2s; +$ease: cubic-bezier(0, 1, 0.3, 1); + +.figni-viewer-cubes { + position: absolute; } -@-webkit-keyframes sk-rotateplane { - 0% { - -webkit-transform: perspective(120px); - } +.figni-viewer-loading-animation { + position: relative; + width: 100px; + height: 60px; + margin-top: 2rem; + margin-bottom: 2rem; +} - 50% { - -webkit-transform: perspective(120px) rotateY(180deg); - } +.figni-viewer-loading-text { + margin-top: 1.5rem; + color: var(--figni-viewer-gray-300); + font-family: var(--figni-viewer-ui-font); + font-size: 0.75rem; + animation: loading-text-blinking 2s infinite ease-in-out; +} - 100% { - -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); - } +@keyframes loading-text-blinking { + 0% { opacity: 1; } + 50% { opacity: 0; } + 100% { opacity: 1; } } -@keyframes sk-rotateplane { - 0% { - transform: perspective(120px) rotateX(0deg) rotateY(0deg); - -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); - } +.figni-viewer-cube { + width: $w; + height: $h; + position: absolute; + transition: all ease-out .3s; +} - 50% { - transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - } +.figni-viewer-cube-svg { + fill: var(--figni-viewer-gray-500); +} - 100% { - transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - } +.figni-viewer-cube-window { + fill: var(--figni-viewer-gray-50); } -.figni-viewer-loading-animation-hide { - -webkit-animation: loading-animation-hide 0.5s ease-out; - animation: loading-animation-hide 0.5s ease-out; - animation-fill-mode: forwards; +.figni-viewer-cube1 { + animation: cube1-animation $speed $ease infinite; +} +.figni-viewer-cube2 { + animation: cube2-animation $speed $ease infinite; +} +.figni-viewer-cube3 { + animation: cube3-animation $speed $ease infinite; + z-index: 2; +} +.figni-viewer-cube4 { + animation: cube4-animation $speed $ease infinite; +} +.figni-viewer-cube-svg-window { + fill: var(--figni-viewer-gray-50); } -@-webkit-keyframes loading-animation-hide { + +@keyframes cube1-animation { 0% { - opacity: 1; + transform: translate(0,0); + } 50% { + transform: translate($xspace,-$yspace); + } 100% { + transform: translate($xspace*2,0); } +} - 100% { - opacity: 0; +@keyframes cube2-animation { + 0%, 50% { + transform: translate($xspace*2, 0px); + } 100% { + transform: translate($xspace*3, $yspace); } } -@keyframes loading-animation-hide { +@keyframes cube3-animation { 0% { - opacity: 1; + transform: translate($xspace*3, $yspace); + } 50% { + transform: translate($xspace*2, $yspace*2); + } 100% { + transform: translate($xspace, $yspace); } +} - 100% { - opacity: 0; +@keyframes cube4-animation { + 0%, 50% { + transform: translate($xspace, $yspace); + } 100% { + transform: translate(0, 0); } } +.figni-viewer-loading-animation-hide { + opacity: 0; + visibility: hidden !important; +} \ No newline at end of file