forked from platypush/platypush
[Camera UI] Dynamic fullscreen support.
This commit is contained in:
parent
3fddf67949
commit
b69e950076
2 changed files with 87 additions and 25 deletions
|
@ -1,10 +1,17 @@
|
|||
<template>
|
||||
<div class="camera">
|
||||
<div class="camera-container">
|
||||
<div class="frame-container" ref="frameContainer">
|
||||
<div class="camera" ref="cameraRoot">
|
||||
<div class="camera-container"
|
||||
:class="{fullscreen: fullscreen_}"
|
||||
ref="cameraContainer">
|
||||
<div class="frame-canvas" ref="frameCanvas">
|
||||
<div class="frame-container"
|
||||
:class="{vertical: isCameraVertical, horizontal: !isCameraVertical}"
|
||||
:style="{aspectRatio: aspectRatio}"
|
||||
ref="frameContainer">
|
||||
<div class="no-frame" v-if="!streaming && !capturing && !captured">The camera is not active</div>
|
||||
<img class="frame" :src="url" ref="frame" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="left">
|
||||
|
@ -34,6 +41,14 @@
|
|||
<button type="button" @click="$refs.paramsModal.show()" title="Settings">
|
||||
<i class="fas fa-cog" />
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
:title="fullscreen_ ? 'Exit fullscreen' : 'Fullscreen'"
|
||||
@click="fullscreen_ = !fullscreen_"
|
||||
v-if="!fullscreen">
|
||||
<i class="fas fa-expand" v-if="!fullscreen_" />
|
||||
<i class="fas fa-compress" v-else />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,7 +119,7 @@
|
|||
<input name="grayscale" type="checkbox" v-model="attrs.grayscale" @change="onGrayscaleChanged"/>
|
||||
</label>
|
||||
|
||||
<Slot />
|
||||
<slot />
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
|
@ -118,12 +133,6 @@ export default {
|
|||
name: "Camera",
|
||||
components: {Modal},
|
||||
mixins: [CameraMixin],
|
||||
props: {
|
||||
cameraPlugin: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
fullURL() {
|
||||
|
|
|
@ -6,6 +6,11 @@ export default {
|
|||
mixins: [Utils],
|
||||
|
||||
props: {
|
||||
fullscreen: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
cameraPlugin: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
@ -17,9 +22,11 @@ export default {
|
|||
streaming: false,
|
||||
capturing: false,
|
||||
captured: false,
|
||||
fullscreen_: false,
|
||||
audioOn: false,
|
||||
url: null,
|
||||
attrs: {},
|
||||
resizeObserver: null,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -37,6 +44,20 @@ export default {
|
|||
grayscale: parseInt(0 + this.attrs.grayscale),
|
||||
}
|
||||
},
|
||||
|
||||
aspectRatio() {
|
||||
if (!this.attrs?.resolution)
|
||||
return 1
|
||||
|
||||
return `${this.attrs.resolution[0]}/${this.attrs.resolution[1]}`
|
||||
},
|
||||
|
||||
isCameraVertical() {
|
||||
if (!this.attrs?.resolution)
|
||||
return false
|
||||
|
||||
return this.attrs.resolution[1] > this.attrs.resolution[0]
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -82,25 +103,41 @@ export default {
|
|||
},
|
||||
|
||||
onDeviceChanged() {},
|
||||
onFlipChanged() {},
|
||||
|
||||
onFlipChanged() {
|
||||
this.onSizeChanged()
|
||||
},
|
||||
|
||||
onSizeChanged() {
|
||||
const degToRad = (deg) => (deg * Math.PI)/180
|
||||
const rot = degToRad(this.params.rotate)
|
||||
let width = Math.round(this.params.scale_x * Math.abs(this.params.resolution[0] * Math.cos(rot) + this.params.resolution[1] * Math.sin(rot)))
|
||||
let height = Math.round(this.params.scale_y * Math.abs(this.params.resolution[0] * Math.sin(rot) + this.params.resolution[1] * Math.cos(rot)))
|
||||
const outerWidth = this.$refs.frameContainer.parentElement.offsetWidth
|
||||
const outerHeight = this.$refs.frameContainer.parentElement.offsetHeight
|
||||
|
||||
if (width > window.innerWidth) {
|
||||
height = Math.round(height * (window.innerWidth / width))
|
||||
width = window.innerWidth
|
||||
let width = (
|
||||
Math.round(
|
||||
this.params.scale_x * Math.abs(this.params.resolution[0] * Math.cos(rot) + this.params.resolution[1] * Math.sin(rot))
|
||||
) + 'px'
|
||||
)
|
||||
|
||||
let height = (
|
||||
Math.round(
|
||||
this.params.scale_y * Math.abs(this.params.resolution[0] * Math.sin(rot) + this.params.resolution[1] * Math.cos(rot))
|
||||
) + 'px'
|
||||
)
|
||||
|
||||
if (this.fullscreen_) {
|
||||
if (this.params.resolution[0] > this.params.resolution[1]) {
|
||||
width = '100%'
|
||||
height = (outerHeight * (this.params.resolution[1] / this.params.resolution[0])) + 'px'
|
||||
} else {
|
||||
height = '100%'
|
||||
width = (outerWidth * (this.params.resolution[0] / this.params.resolution[1])) + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
if (height > window.innerHeight) {
|
||||
width = Math.round(width * (window.innerHeight / height))
|
||||
height = window.innerHeight
|
||||
}
|
||||
|
||||
this.$refs.frameContainer.style.width = `${width}px`
|
||||
this.$refs.frameContainer.style.height = `${height}px`
|
||||
this.$refs.frameContainer.style.width = width
|
||||
this.$refs.frameContainer.style.height = height
|
||||
},
|
||||
|
||||
onFpsChanged() {},
|
||||
|
@ -133,6 +170,7 @@ export default {
|
|||
},
|
||||
|
||||
mounted() {
|
||||
this.fullscreen_ = this.fullscreen
|
||||
this.$refs.frame.addEventListener('load', this.onFrameLoaded)
|
||||
this.onSizeChanged()
|
||||
this.$watch(() => this.attrs.resolution, this.onSizeChanged)
|
||||
|
@ -141,6 +179,21 @@ export default {
|
|||
this.$watch(() => this.attrs.rotate, this.onSizeChanged)
|
||||
this.$watch(() => this.attrs.scale_x, this.onSizeChanged)
|
||||
this.$watch(() => this.attrs.scale_y, this.onSizeChanged)
|
||||
|
||||
const onOrientationOrSizeChange = () => {
|
||||
this.onSizeChanged()
|
||||
}
|
||||
|
||||
onOrientationOrSizeChange()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.resizeObserver = new ResizeObserver(onOrientationOrSizeChange)
|
||||
this.resizeObserver.observe(this.$refs?.frameContainer?.parentElement)
|
||||
})
|
||||
},
|
||||
|
||||
unmouted() {
|
||||
this.resizeObserver?.disconnect()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue