diff options
Diffstat (limited to 'public/bluebey-studio/src/background.js')
| -rw-r--r-- | public/bluebey-studio/src/background.js | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/public/bluebey-studio/src/background.js b/public/bluebey-studio/src/background.js index 72bc396..adc7f94 100644 --- a/public/bluebey-studio/src/background.js +++ b/public/bluebey-studio/src/background.js @@ -16,8 +16,9 @@ /** The library already downloaded into `assets/backgrounds/` (see CREDITS.json). * Most are Poly Haven *HDRIs* - CC0 photographs of real places - so each one comes * with a floor, a horizon and perspective, which is what gives a picture depth - * that a flat wall texture cannot. `mutoujima` is the exception: an original - * illustration drawn for this studio by the author, not a third-party CC0 photo. */ + * that a flat wall texture cannot. `mutoujima`, `dokan` and `uchu` are the + * exceptions: original illustrations drawn for this studio by the author, not + * CC0 photos. */ export const BACKGROUND_PRESETS = [ { name: 'empty_warehouse_01', label: '倉庫' }, { name: 'ballroom', label: '広間' }, @@ -32,6 +33,8 @@ export const BACKGROUND_PRESETS = [ { name: 'spiaggia_di_mondello', label: '海岸' }, // ポリヘイブンの写真ではなく、作者(安竹洋平)が描き起こしたオリジナルの一枚絵。 { name: 'mutoujima', label: '無人島' }, + { name: 'dokan', label: '土管のある空き地' }, + { name: 'uchu', label: '宇宙船の中' }, // 「ぶるべーを探せ!」用。物がたくさん詰まっていて、同じ形が何度も出てくる場所。 { name: 'abandoned_factory_canteen_01', label: '廃工場の食堂' }, { name: 'basement_boxing_ring', label: '地下室のリング' }, @@ -471,12 +474,22 @@ export function createBackdrop({ stage, resolveUrl, onNeedsRender } = {}) { return dataUrl; } - /** Japanese, actionable text for the ways `getUserMedia` usually fails. */ + /* Shown whenever the page is not a secure context. This is a fact about the + * web platform, not about any one browser, so the wording must not point a + * finger at the browser the user happens to be holding. */ + const INSECURE_CAMERA_REASON = + 'この開き方(http のアドレス)では、どのブラウザでもカメラを使えません。https のサイトか localhost で開いてください。'; + + /** + * Japanese, actionable text for the ways `getUserMedia` usually fails. On a + * phone this toast is all the user has to go on, so each case names the exact + * thing to tap instead of just stating that something went wrong. + */ function cameraFailureReason(error) { switch (error?.name) { case 'NotAllowedError': case 'PermissionDeniedError': - return 'カメラの使用が許可されていません'; + return 'カメラが許可されていません。URLバーのアイコン→カメラ→「許可」に変え(一度「ブロック」するとブラウザは覚えています)、端末の設定でもアプリに許可してください(Android: 設定→アプリ→Brave→権限→カメラ/iOS: 設定→Brave→カメラ)。'; case 'NotFoundError': case 'DevicesNotFoundError': return '使えるカメラが見つかりませんでした'; @@ -487,7 +500,9 @@ export function createBackdrop({ stage, resolveUrl, onNeedsRender } = {}) { case 'ConstraintNotSatisfiedError': return '指定したカメラを使用できません'; case 'SecurityError': - return 'カメラを使うには https か localhost が必要です'; + // No `mediaDevices` at all is the usual symptom, but this covers the + // same cause when a sandboxed frame raises the error instead. + return INSECURE_CAMERA_REASON; default: return 'カメラを起動できませんでした'; } @@ -496,7 +511,14 @@ export function createBackdrop({ stage, resolveUrl, onNeedsRender } = {}) { async function startCamera(facing = 'environment') { const mediaDevices = globalThis.navigator?.mediaDevices; if (!mediaDevices || typeof mediaDevices.getUserMedia !== 'function') { - return { ok: false, reason: 'カメラを使うには https か localhost が必要です' }; + // An insecure page has no `mediaDevices` at all. Say so plainly rather + // than leaving the user to think their camera or browser is broken. + return { + ok: false, + reason: globalThis.isSecureContext === false + ? INSECURE_CAMERA_REASON + : 'カメラを使うには https か localhost が必要です', + }; } stopCamera(); |
