From 6dde7503a1ee0176d660841071ff14b73009bd04 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:59:51 +0900 Subject: [PATCH 1/7] =?UTF-8?q?enhance(frontend):=20=E9=9F=B3=E5=A3=B0?= =?UTF-8?q?=E3=83=93=E3=82=B8=E3=83=A5=E3=82=A2=E3=83=A9=E3=82=A4=E3=82=B6?= =?UTF-8?q?=E3=83=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/MkMediaAudio.vue | 442 ++++++++++++++++-- 1 file changed, 391 insertions(+), 51 deletions(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index b7052ad918..eff1bee266 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -10,15 +10,19 @@ SPDX-License-Identifier: AGPL-3.0-only tabindex="0" :class="[ $style.audioContainer, + controlsShowing && $style.active, (audio.isSensitive && prefer.s.highlightSensitiveMedia) && $style.sensitive, ]" + @mouseover.passive="onMouseOver" + @mousemove.passive="onMouseMove" + @mouseleave.passive="onMouseLeave" @contextmenu.stop @keydown.stop > @@ -35,71 +39,83 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
-
- + + +
+
-
- + +
+
ALT
+
-
{{ hms(elapsedTimeMs) }}
-
- +
+
+ +
+
+ +
+
{{ hms(elapsedTimeMs) }}
+
+ + +
-
@@ -421,8 +656,6 @@ onDeactivated(() => { .audioContainer { container-type: inline-size; position: relative; - border: .5px solid var(--MI_THEME-divider); - border-radius: var(--MI-radius); overflow: clip; &:focus-visible { @@ -446,15 +679,46 @@ onDeactivated(() => { } } +.indicators { + display: inline-flex; + position: absolute; + top: 10px; + left: 10px; + pointer-events: none; + opacity: .5; + gap: 6px; +} + +.indicator { + font-size: 0.8em; + padding: 2px 5px; +} + +.hide { + display: block; + position: absolute; + border-radius: 6px; + background-color: var(--MI_THEME-fg); + color: hsl(from var(--MI_THEME-accent) h s calc(l + 10)); + font-size: 12px; + opacity: .5; + padding: 5px 8px; + text-align: center; + cursor: pointer; + top: 12px; + right: 12px; +} + .hidden { width: 100%; + height: 100%; background: #000; border: none; outline: none; font: inherit; color: inherit; cursor: pointer; - padding: 12px 0; + padding: 60px 0; display: flex; align-items: center; justify-content: center; @@ -466,6 +730,54 @@ onDeactivated(() => { color: #fff; } +.audioRoot { + background: #000; + position: relative; + width: 100%; + height: 100%; + object-fit: contain; + border-radius: var(--MI-radius); + overflow: clip; +} + +.audio { + display: block; + height: 100%; + width: 100%; +} + +.audioOverlayPlayButton { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + + opacity: 0; + transition: opacity .4s ease-in-out; + + background: var(--MI_THEME-accent); + color: #fff; + padding: 1rem; + border-radius: 99rem; + + font-size: 1.1rem; + + &:focus-visible { + outline: none; + } +} + +.audioLoading { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + .audioControls { display: grid; grid-template-areas: @@ -474,22 +786,47 @@ onDeactivated(() => { grid-template-columns: auto auto 1fr auto auto; align-items: center; gap: 4px 8px; - padding: 10px; + + padding: 35px 10px 10px 10px; + background: linear-gradient(rgba(0, 0, 0, 0),rgba(0, 0, 0, .75)); + + position: absolute; + left: 0; + right: 0; + bottom: 0; + + transform: translateY(100%); + pointer-events: none; + opacity: 0; + transition: opacity .4s ease-in-out, transform .4s ease-in-out; +} + +.active { + .audioControls { + transform: translateY(0); + opacity: 1; + pointer-events: auto; + } + + .audioOverlayPlayButton { + opacity: 1; + } } .controlsChild { display: flex; align-items: center; gap: 4px; + color: #fff; .controlButton { padding: 6px; border-radius: calc(var(--MI-radius) / 2); + transition: background-color .2s ease-in-out; font-size: 1.05rem; &:hover { - color: var(--MI_THEME-accent); - background-color: var(--MI_THEME-accentedBg); + background-color: var(--MI_THEME-accent); } &:focus-visible { @@ -521,6 +858,9 @@ onDeactivated(() => { .seekbarRoot { grid-area: seekbar; + /* ▼シークバー操作をやりやすくするためにクリックイベントが伝播されないエリアを拡張する */ + margin: -10px; + padding: 10px; } @container (min-width: 500px) { From 2b0801dfdd27cc7cbb2828f67d5b4297df78f7e1 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:06:12 +0900 Subject: [PATCH 2/7] fix --- packages/frontend/src/components/MkMediaAudio.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index eff1bee266..04b24bb38d 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only From 05b6244b64d4c3e009ff727fc99c10176e1b230d Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:15:27 +0900 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20avatar=E3=81=AE=E7=B8=A6=E6=A8=AA?= =?UTF-8?q?=E6=AF=94=E3=81=8C1:1=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=84?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=AB=E7=94=BB=E5=83=8F=E3=81=8C=E3=82=86?= =?UTF-8?q?=E3=81=8C=E3=82=80=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkMediaAudio.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 04b24bb38d..ee5a19a62e 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -412,11 +412,15 @@ function drawVisualizer() { // 波形の中心にアバターを円形にくりぬいて描画 const avatarSize = radius; + const avatarHeight = Math.max(userAvatarImage.value.height * (avatarSize / userAvatarImage.value.width), avatarSize); + const avatarWidth = Math.max(userAvatarImage.value.width * (avatarSize / userAvatarImage.value.height), avatarSize); + const avatarDx = centerX - avatarWidth / 2; + const avatarDy = centerY - avatarHeight / 2; canvasCtx.value.save(); canvasCtx.value.beginPath(); canvasCtx.value.arc(centerX, centerY, avatarSize / 2, 0, Math.PI * 2); canvasCtx.value.clip(); - canvasCtx.value.drawImage(userAvatarImage.value, centerX - avatarSize / 2, centerY - avatarSize / 2, avatarSize, avatarSize); + canvasCtx.value.drawImage(userAvatarImage.value, avatarDx, avatarDy, avatarWidth, avatarHeight); canvasCtx.value.restore(); if (isActuallyPlaying.value) { From 18418f980795bb52408988b4ba9e8a46adf6175f Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:18:00 +0900 Subject: [PATCH 4/7] fix --- .../frontend/src/components/MkMediaAudio.vue | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index ee5a19a62e..94f9cef010 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -101,7 +101,7 @@ SPDX-License-Identifier: AGPL-3.0-only From 8137a07559763e1a43f13a7bd4e4d07dcd1e6746 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:24:56 +0900 Subject: [PATCH 5/7] remove unnecessary code --- packages/frontend/src/components/MkMediaAudio.vue | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 94f9cef010..f9dba9187c 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -579,13 +579,6 @@ function init() { // 音量制御はGainNode audioEl.value.volume = 1; - - hasAudio(audioEl.value).then(had => { - if (!had && audioEl.value) { - audioEl.value.loop = audioEl.value.muted = true; - audioEl.value.play(); - } - }); } }, { immediate: true, From 83be510754b124e44f3cb10f71048c52de6a3b92 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:29:18 +0900 Subject: [PATCH 6/7] fix lint --- packages/frontend/src/components/MkMediaAudio.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index f9dba9187c..485c733eb4 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -343,7 +343,7 @@ const userAvatarImage = computed(() => { function drawVisualizer() { if (!canvasEl.value || !canvasCtx.value || !audioEl.value || !audioSource.value) return; - if (document.visibilityState === 'hidden') { + if (window.document.visibilityState === 'hidden') { if (isActuallyPlaying.value) { visualizerTickFrameId = window.requestAnimationFrame(drawVisualizer); } else { From 8c12ed3ce3bc305b575e4c50843c82b6b8e600a6 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:31:08 +0900 Subject: [PATCH 7/7] fix --- packages/frontend/src/components/MkMediaAudio.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 485c733eb4..576a5c98ce 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -603,6 +603,10 @@ function dispose() { window.clearTimeout(controlStateTimer); controlStateTimer = null; } + if (visualizerTickFrameId) { + window.cancelAnimationFrame(visualizerTickFrameId); + visualizerTickFrameId = null; + } if (audioSource.value) { audioSource.value.disconnect(); audioSource.value = null;