fix: improve front camera detection on macOS by checking video track label
This commit is contained in:
@@ -8,7 +8,7 @@ const scannedCodes = ref([])
|
|||||||
const hasMultipleCameras = ref(false)
|
const hasMultipleCameras = ref(false)
|
||||||
const isFullscreen = ref(false)
|
const isFullscreen = ref(false)
|
||||||
const videoAspect = ref(1)
|
const videoAspect = ref(1)
|
||||||
const isFront = computed(() => facingMode.value === 'user')
|
const isMirrored = ref(false)
|
||||||
const wrapperRef = ref(null)
|
const wrapperRef = ref(null)
|
||||||
const bgCanvas = ref(null)
|
const bgCanvas = ref(null)
|
||||||
let bgRafId = null
|
let bgRafId = null
|
||||||
@@ -65,7 +65,7 @@ const paintDetections = (codes) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const scale = drawWidth / vw
|
const scale = drawWidth / vw
|
||||||
const isMirrored = isFront.value
|
// Canvas is mirrored via CSS if isMirrored is true, so no manual coordinate mirroring needed
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
const styles = getComputedStyle(document.documentElement)
|
const styles = getComputedStyle(document.documentElement)
|
||||||
@@ -84,10 +84,6 @@ const paintDetections = (codes) => {
|
|||||||
const transform = (p) => {
|
const transform = (p) => {
|
||||||
let x = p.x * scale + startX
|
let x = p.x * scale + startX
|
||||||
let y = p.y * scale + startY
|
let y = p.y * scale + startY
|
||||||
|
|
||||||
if (isMirrored) {
|
|
||||||
x = width - x
|
|
||||||
}
|
|
||||||
return { x, y }
|
return { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +199,23 @@ const startScan = async () => {
|
|||||||
|
|
||||||
stream = await navigator.mediaDevices.getUserMedia(constraints)
|
stream = await navigator.mediaDevices.getUserMedia(constraints)
|
||||||
|
|
||||||
|
// Detect actual facing mode to mirror front camera correctly
|
||||||
|
const videoTrack = stream.getVideoTracks()[0]
|
||||||
|
if (videoTrack) {
|
||||||
|
const settings = videoTrack.getSettings()
|
||||||
|
if (settings.facingMode) {
|
||||||
|
isMirrored.value = settings.facingMode === 'user'
|
||||||
|
} else {
|
||||||
|
// Fallback: check label for desktop cameras or assume requested mode
|
||||||
|
const label = videoTrack.label ? videoTrack.label.toLowerCase() : ''
|
||||||
|
if (label.includes('front') || label.includes('facetime') || label.includes('macbook')) {
|
||||||
|
isMirrored.value = true
|
||||||
|
} else {
|
||||||
|
isMirrored.value = facingMode.value === 'user'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (videoRef.value) {
|
if (videoRef.value) {
|
||||||
videoRef.value.srcObject = stream
|
videoRef.value.srcObject = stream
|
||||||
// Wait for metadata to play
|
// Wait for metadata to play
|
||||||
@@ -464,7 +477,7 @@ const isUrl = (string) => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="camera-wrapper"
|
class="camera-wrapper"
|
||||||
:class="{ 'clickable': !isFullscreen, 'is-front': isFront }"
|
:class="{ 'clickable': !isFullscreen, 'is-mirrored': isMirrored }"
|
||||||
:style="desktopFullscreenStyle"
|
:style="desktopFullscreenStyle"
|
||||||
ref="wrapperRef"
|
ref="wrapperRef"
|
||||||
@click="!isFullscreen && toggleFullscreen()"
|
@click="!isFullscreen && toggleFullscreen()"
|
||||||
@@ -472,13 +485,13 @@ const isUrl = (string) => {
|
|||||||
<video
|
<video
|
||||||
ref="videoRef"
|
ref="videoRef"
|
||||||
class="camera-feed"
|
class="camera-feed"
|
||||||
:class="{ 'is-front': isFront }"
|
:class="{ 'is-mirrored': isMirrored }"
|
||||||
autoplay
|
autoplay
|
||||||
playsinline
|
playsinline
|
||||||
muted
|
muted
|
||||||
></video>
|
></video>
|
||||||
|
|
||||||
<canvas ref="overlayCanvas" class="scan-overlay-canvas"></canvas>
|
<canvas ref="overlayCanvas" class="scan-overlay-canvas" :class="{ 'is-mirrored': isMirrored }"></canvas>
|
||||||
|
|
||||||
<div v-if="error" class="error-overlay">
|
<div v-if="error" class="error-overlay">
|
||||||
<p>{{ error }}</p>
|
<p>{{ error }}</p>
|
||||||
@@ -632,7 +645,7 @@ const isUrl = (string) => {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.camera-feed.is-front {
|
.camera-feed.is-mirrored {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,6 +659,10 @@ const isUrl = (string) => {
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scan-overlay-canvas.is-mirrored {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* front mirror canvas removed */
|
/* front mirror canvas removed */
|
||||||
|
|
||||||
.error-overlay {
|
.error-overlay {
|
||||||
|
|||||||
Reference in New Issue
Block a user