Update voice demo camera drawer

This commit is contained in:
Xin Wang
2026-06-02 13:22:08 +08:00
parent aae751f3f3
commit 89d0777830
3 changed files with 42 additions and 67 deletions

View File

@@ -78,6 +78,7 @@ const els = {
cameraPhoto: document.getElementById("camera-photo"),
cameraCanvas: document.getElementById("camera-canvas"),
cameraStartBtn: document.getElementById("camera-start-btn"),
cameraDeviceRow: document.getElementById("camera-device-row"),
cameraDeviceSelect: document.getElementById("camera-device-select"),
cameraUpload: document.getElementById("camera-upload"),
cameraSamples: document.getElementById("camera-samples"),
@@ -257,9 +258,6 @@ function syncCameraDrawer(value) {
els.cameraQuestion.textContent = prompt;
renderSampleThumbnails();
selectDefaultImage();
refreshVideoDevices().then(() => {
if (!state.cameraActive) populateDeviceSelect();
});
} else {
els.cameraState.textContent = "状态 -";
els.cameraQuestion.textContent = "";
@@ -987,6 +985,8 @@ async function startCamera(deviceId) {
state.cameraStream.getVideoTracks?.()[0]?.getSettings?.().deviceId ||
deviceId;
populateDeviceSelect(activeId);
// Reveal the camera device dropdown only while the camera is in use.
els.cameraDeviceRow.hidden = false;
setCameraButtonEnabled();
}
@@ -998,6 +998,7 @@ function stopCameraStream() {
els.cameraVideo.srcObject = null;
state.cameraActive = false;
els.cameraStartBtn.classList.remove("is-active");
els.cameraDeviceRow.hidden = true;
}
function captureFromCamera() {

View File

@@ -108,51 +108,15 @@
<p id="camera-question" class="camera-drawer__question"></p>
<div
id="camera-samples"
class="camera-drawer__samples"
aria-label="示例图片,点击选择"
></div>
<div class="camera-drawer__sources">
<div class="camera-drawer__camera-row">
<label class="device-picker">
<span class="device-picker__label">摄像头</span>
<select
id="camera-device-select"
class="device-picker__select"
disabled
>
<option value="">默认摄像头</option>
</select>
</label>
<button
id="camera-start-btn"
class="mic-btn cam-btn"
type="button"
title="打开摄像头"
>
<svg
class="mic-btn__icon"
viewBox="0 0 24 24"
width="24"
height="24"
aria-hidden="true"
>
<path
d="M4 8h3l1.2-1.6A1 1 0 0 1 9 6h6a1 1 0 0 1 .8.4L17 8h3a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z"
fill="none"
stroke="currentColor"
stroke-width="1.6"
/>
<circle
cx="12"
cy="13"
r="3.2"
fill="none"
stroke="currentColor"
stroke-width="1.6"
/>
</svg>
<span class="mic-btn__label">使用摄像头</span>
</button>
</div>
<label
class="btn btn--ghost camera-drawer__source camera-drawer__source--upload"
class="btn btn--ghost camera-drawer__source"
>
上传图片
<input
@@ -162,13 +126,30 @@
hidden
/>
</label>
<button
id="camera-start-btn"
class="btn btn--ghost camera-drawer__source"
type="button"
title="打开摄像头"
>
使用摄像头
</button>
</div>
<div
id="camera-samples"
class="camera-drawer__samples"
aria-label="示例图片,点击选择"
></div>
<label
id="camera-device-row"
class="device-picker camera-drawer__device-row"
hidden
>
<span class="device-picker__label">选择摄像头</span>
<select
id="camera-device-select"
class="device-picker__select"
disabled
>
<option value="">默认摄像头</option>
</select>
</label>
<button
id="camera-done-btn"

View File

@@ -270,36 +270,29 @@ body {
cursor: not-allowed;
}
/* 上传图片 + 使用摄像头 share one row. */
.camera-drawer__sources {
display: flex;
flex-direction: column;
gap: 8px;
}
/* Mirror the mic controls: labeled device select + an action pill button. */
.camera-drawer__camera-row {
display: flex;
align-items: flex-end;
gap: 8px;
}
.camera-drawer__camera-row .device-picker {
flex: 1 1 auto;
/* The camera device dropdown only appears after "使用摄像头" is selected. */
.camera-drawer__device-row {
max-width: none;
}
.cam-btn {
flex-shrink: 0;
.camera-drawer__device-row[hidden] {
display: none;
}
.cam-btn.is-active {
background: var(--success);
/* Active state for the "使用摄像头" button once the camera is live. */
.camera-drawer__source.is-active {
border-color: var(--success);
color: #fff;
box-shadow: 0 0 0 6px rgba(45, 210, 139, 0.18);
color: var(--success);
}
.camera-drawer__source {
flex: 1 1 0;
display: inline-flex;
align-items: center;
justify-content: center;