- run by vite
- change camera
This commit is contained in:
parent
782fa7f59f
commit
85d163fb64
57 changed files with 1494 additions and 1375 deletions
27
src/views/ErrorNotFoundPage.vue
Normal file
27
src/views/ErrorNotFoundPage.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Error404NotFound",
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="fullscreen bg-secondary text-white text-center q-pa-md flex flex-center"
|
||||
>
|
||||
<div>
|
||||
<div class="text-h1">ไม่พบหน้าที่ต้องการ</div>
|
||||
<div class="text-h2">(404 Page Not Found)</div>
|
||||
<q-btn
|
||||
class="q-mt-xl"
|
||||
color="white"
|
||||
text-color="secondary"
|
||||
unelevated
|
||||
to="/"
|
||||
label="กลับไปหน้าหลัก"
|
||||
no-caps
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,103 +1,103 @@
|
|||
<script setup lang="ts">
|
||||
import type { QTableProps } from "quasar";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import Table from "@/components/TableHistory.vue";
|
||||
import ToolBar from "@/components/ToolBar.vue";
|
||||
|
||||
// importStores
|
||||
import { useChekIn } from "@/stores/chekin";
|
||||
|
||||
const router = useRouter();
|
||||
const stores = useChekIn();
|
||||
|
||||
onMounted(() => {
|
||||
fetchlist();
|
||||
});
|
||||
|
||||
function fetchlist() {
|
||||
const listData = [
|
||||
{
|
||||
no: "1",
|
||||
date: "13/08/66",
|
||||
in: "11:20",
|
||||
loIn: "สำนักงาน ก.ก ",
|
||||
out: "",
|
||||
loOut: "",
|
||||
status: "",
|
||||
Morningstatus: "1",
|
||||
AfternoonStatus: "1",
|
||||
statusEdit: "wait",
|
||||
},
|
||||
{
|
||||
no: "2",
|
||||
date: "12/08/66",
|
||||
in: "08:04",
|
||||
loIn: "สำนักงาน ก.ก ",
|
||||
out: "17:01",
|
||||
loOut: "สำนักงาน ก.ก ",
|
||||
status: "ลงเวลาเรียบร้อย",
|
||||
Morningstatus: "2",
|
||||
AfternoonStatus: "2",
|
||||
statusEdit: "edit",
|
||||
},
|
||||
{
|
||||
no: "3",
|
||||
date: "11/08/66",
|
||||
in: "08:34",
|
||||
loIn: "สำนักงาน ก.ก ",
|
||||
out: "17:36",
|
||||
loOut: "สำนักงาน ก.ก ",
|
||||
status: "สาย ทำงานครบ",
|
||||
Morningstatus: "3",
|
||||
AfternoonStatus: "2",
|
||||
statusEdit: "edit",
|
||||
},
|
||||
{
|
||||
no: "4",
|
||||
date: "10/08/66",
|
||||
in: "08:48",
|
||||
loIn: "สำนักงาน ก.ก ",
|
||||
out: "17:00",
|
||||
loOut: "สำนักงาน ก.ก ",
|
||||
status: "สาย ทำงานไม่ครบ",
|
||||
Morningstatus: "3",
|
||||
AfternoonStatus: "3",
|
||||
statusEdit: "approve",
|
||||
},
|
||||
];
|
||||
stores.fetchHistoryList(listData);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12">
|
||||
<q-card flat class="row col-12 cardNone">
|
||||
<div
|
||||
class="bg-secondary text-white col-12 row items-center q-px-md q-py-sm"
|
||||
>
|
||||
<div class="col-2">
|
||||
<q-btn
|
||||
icon="arrow_backt"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
flat
|
||||
color="white"
|
||||
@click="router.go(-1)"
|
||||
/>
|
||||
</div>
|
||||
<q-space />
|
||||
<span class="text-body1 text-weight-bold col-8 text-center"
|
||||
>ประวัติการลงเวลา</span
|
||||
>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
<div class="col-12 q-pa-md text-grey-9">
|
||||
<ToolBar />
|
||||
<Table />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { QTableProps } from 'quasar'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Table from '@/components/TableHistory.vue'
|
||||
import ToolBar from '@/components/ToolBar.vue'
|
||||
|
||||
// importStores
|
||||
import { useChekIn } from '@/stores/chekin'
|
||||
|
||||
const router = useRouter()
|
||||
const stores = useChekIn()
|
||||
|
||||
onMounted(() => {
|
||||
fetchlist()
|
||||
})
|
||||
|
||||
function fetchlist() {
|
||||
const listData = [
|
||||
{
|
||||
no: '1',
|
||||
date: '13/08/66',
|
||||
in: '11:20',
|
||||
loIn: 'สำนักงาน ก.ก ',
|
||||
out: '',
|
||||
loOut: '',
|
||||
status: '',
|
||||
Morningstatus: '1',
|
||||
AfternoonStatus: '1',
|
||||
statusEdit: 'wait',
|
||||
},
|
||||
{
|
||||
no: '2',
|
||||
date: '12/08/66',
|
||||
in: '08:04',
|
||||
loIn: 'สำนักงาน ก.ก ',
|
||||
out: '17:01',
|
||||
loOut: 'สำนักงาน ก.ก ',
|
||||
status: 'ลงเวลาเรียบร้อย',
|
||||
Morningstatus: '2',
|
||||
AfternoonStatus: '2',
|
||||
statusEdit: 'edit',
|
||||
},
|
||||
{
|
||||
no: '3',
|
||||
date: '11/08/66',
|
||||
in: '08:34',
|
||||
loIn: 'สำนักงาน ก.ก ',
|
||||
out: '17:36',
|
||||
loOut: 'สำนักงาน ก.ก ',
|
||||
status: 'สาย ทำงานครบ',
|
||||
Morningstatus: '3',
|
||||
AfternoonStatus: '2',
|
||||
statusEdit: 'edit',
|
||||
},
|
||||
{
|
||||
no: '4',
|
||||
date: '10/08/66',
|
||||
in: '08:48',
|
||||
loIn: 'สำนักงาน ก.ก ',
|
||||
out: '17:00',
|
||||
loOut: 'สำนักงาน ก.ก ',
|
||||
status: 'สาย ทำงานไม่ครบ',
|
||||
Morningstatus: '3',
|
||||
AfternoonStatus: '3',
|
||||
statusEdit: 'approve',
|
||||
},
|
||||
]
|
||||
stores.fetchHistoryList(listData)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12">
|
||||
<q-card flat class="row col-12 cardNone">
|
||||
<div
|
||||
class="bg-secondary text-white col-12 row items-center q-px-md q-py-sm"
|
||||
>
|
||||
<div class="col-2">
|
||||
<q-btn
|
||||
icon="arrow_backt"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
flat
|
||||
color="white"
|
||||
@click="router.go(-1)"
|
||||
/>
|
||||
</div>
|
||||
<q-space />
|
||||
<span class="text-body1 text-weight-bold col-8 text-center"
|
||||
>ประวัติการลงเวลา</span
|
||||
>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
<div class="col-12 q-pa-md text-grey-9">
|
||||
<ToolBar />
|
||||
<Table />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,202 +1,134 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import moment, { Moment } from "moment";
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useQuasar } from 'quasar'
|
||||
import moment from 'moment'
|
||||
import Camera from 'simple-vue-camera'
|
||||
|
||||
// import Type
|
||||
import type { FormRef } from "@/interface/response/checkin";
|
||||
import type { FormRef } from '@/interface/response/checkin'
|
||||
// import components
|
||||
import MapCheck from "@/components/MapCheckin.vue";
|
||||
import MapCheck from '@/components/MapCheckin.vue'
|
||||
// import Stores
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useCounterMixin } from '@/stores/mixin'
|
||||
|
||||
const mixin = useCounterMixin();
|
||||
const { date2Thai, dialogConfirm } = mixin;
|
||||
const router = useRouter();
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin()
|
||||
const { date2Thai, dialogConfirm } = mixin
|
||||
const router = useRouter()
|
||||
const $q = useQuasar()
|
||||
|
||||
const stetusCheckin = ref(true);
|
||||
const stetusCheckin = ref(true)
|
||||
|
||||
onMounted(() => {
|
||||
updateClock();
|
||||
});
|
||||
updateClock()
|
||||
})
|
||||
|
||||
//time
|
||||
const dateNow = ref<Date>(new Date());
|
||||
const Thai = ref<Date>(dateNow.value);
|
||||
const formattedS = ref();
|
||||
const formattedM = ref();
|
||||
const formattedH = ref();
|
||||
const dateNow = ref<Date>(new Date())
|
||||
const Thai = ref<Date>(dateNow.value)
|
||||
const formattedS = ref()
|
||||
const formattedM = ref()
|
||||
const formattedH = ref()
|
||||
|
||||
function updateClock() {
|
||||
const date = Date.now();
|
||||
let hh = moment(date).format("HH");
|
||||
let mm = moment(date).format("mm");
|
||||
let ss = moment(date).format("ss");
|
||||
formattedS.value = ss;
|
||||
formattedM.value = mm;
|
||||
formattedH.value = hh;
|
||||
const date = Date.now()
|
||||
const hh = moment(date).format('HH')
|
||||
const mm = moment(date).format('mm')
|
||||
const ss = moment(date).format('ss')
|
||||
formattedS.value = ss
|
||||
formattedM.value = mm
|
||||
formattedH.value = hh
|
||||
}
|
||||
setInterval(updateClock, 1000);
|
||||
setInterval(updateClock, 1000)
|
||||
|
||||
//location
|
||||
const location = ref<string>("");
|
||||
const coordinates = ref<string>("13° 43’ 45” N 100° 31’ 26” E");
|
||||
const workplace = ref<string>("in-place");
|
||||
const useLocation = ref<string | null>("");
|
||||
const model = ref<string | null>("");
|
||||
const location = ref<string>('')
|
||||
const coordinates = ref<string>('13° 43’ 45” N 100° 31’ 26” E')
|
||||
const workplace = ref<string>('in-place')
|
||||
const useLocation = ref<string | null>('')
|
||||
const model = ref<string | null>('')
|
||||
const options = ref<string[]>([
|
||||
"ปฏิบัติงานที่บ้าน",
|
||||
"ลืมลงเวลาปฏิบัติงาน",
|
||||
"ไปประชุม/อบรม/สัมมนา/ปฏิบัติงานที่บ้านนอกสถานที่",
|
||||
"ขออนุญาตออกนอกสถานที่",
|
||||
"อื่นๆ",
|
||||
]);
|
||||
'ปฏิบัติงานที่บ้าน',
|
||||
'ลืมลงเวลาปฏิบัติงาน',
|
||||
'ไปประชุม/อบรม/สัมมนา/ปฏิบัติงานที่บ้านนอกสถานที่',
|
||||
'ขออนุญาตออกนอกสถานที่',
|
||||
'อื่นๆ',
|
||||
])
|
||||
function selectLocation() {
|
||||
if (model.value === "อื่นๆ") {
|
||||
useLocation.value = "";
|
||||
if (model.value === 'อื่นๆ') {
|
||||
useLocation.value = ''
|
||||
} else {
|
||||
useLocation.value = model.value;
|
||||
useLocation.value = model.value
|
||||
}
|
||||
}
|
||||
//camera
|
||||
const camera = ref(false);
|
||||
const hasPhoto = ref<boolean>(true);
|
||||
const mediaStream = ref<MediaStream | null>(null);
|
||||
const video = ref<HTMLVideoElement | null>(null);
|
||||
const canvas = ref<HTMLCanvasElement | null>(null);
|
||||
const img = ref<any>(null);
|
||||
const camera = ref<InstanceType<typeof Camera>>()
|
||||
const cameraIsOn = ref<boolean>(false)
|
||||
const img = ref<any>(undefined)
|
||||
const photoWidth = ref<number>(350)
|
||||
const photoHeight = ref<number>(350)
|
||||
|
||||
const openCamera = () => {
|
||||
camera.value = true;
|
||||
camera.value && setupCamera();
|
||||
};
|
||||
const setupCamera = async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||
if (video.value) {
|
||||
video.value.srcObject = stream;
|
||||
}
|
||||
mediaStream.value = stream;
|
||||
} catch (error) {
|
||||
console.error("Error accessing camera:", error);
|
||||
}
|
||||
};
|
||||
function capturePhoto() {
|
||||
const videoElement = video.value;
|
||||
const canvasElement = canvas.value;
|
||||
if (!videoElement || !canvasElement) {
|
||||
console.error("Video or Canvas element not available");
|
||||
return;
|
||||
}
|
||||
const context = canvasElement.getContext("2d");
|
||||
if (!context) {
|
||||
console.error("Canvas context not available");
|
||||
return;
|
||||
}
|
||||
const desiredWidth = 150;
|
||||
const desiredHeight = 200;
|
||||
const zoomFactor = 10;
|
||||
cameraIsOn.value ? camera.value?.stop() : camera.value?.start()
|
||||
cameraIsOn.value = !cameraIsOn.value
|
||||
}
|
||||
|
||||
const videoAspectRatio = videoElement.videoWidth / videoElement.videoHeight;
|
||||
const canvasAspectRatio = desiredWidth / desiredHeight;
|
||||
|
||||
let drawWidth, drawHeight;
|
||||
|
||||
if (videoAspectRatio > canvasAspectRatio) {
|
||||
drawWidth = desiredWidth * zoomFactor;
|
||||
drawHeight = (desiredWidth * zoomFactor) / videoAspectRatio;
|
||||
} else {
|
||||
drawWidth = desiredHeight * zoomFactor * videoAspectRatio;
|
||||
drawHeight = desiredHeight * zoomFactor;
|
||||
}
|
||||
|
||||
canvasElement.width = drawWidth;
|
||||
canvasElement.height = drawHeight;
|
||||
if (context) {
|
||||
context.imageSmoothingEnabled = true;
|
||||
context.imageSmoothingQuality = "low";
|
||||
}
|
||||
|
||||
// context.drawImage(
|
||||
// videoElement,
|
||||
// 0,
|
||||
// 0,
|
||||
// canvasElement.width,
|
||||
// canvasElement.height
|
||||
// );
|
||||
context.drawImage(
|
||||
videoElement,
|
||||
0,
|
||||
0,
|
||||
videoElement.videoWidth,
|
||||
videoElement.videoHeight,
|
||||
0,
|
||||
0,
|
||||
drawWidth,
|
||||
drawHeight
|
||||
);
|
||||
async function capturePhoto() {
|
||||
const imageBlob: any = await camera.value?.snapshot(
|
||||
{ width: photoWidth.value, height: photoHeight.value },
|
||||
'image/png',
|
||||
0.5
|
||||
)
|
||||
|
||||
//ไฟล์รูป
|
||||
const dataURL = canvasElement.toDataURL(".image/.png");
|
||||
img.value = dataURL;
|
||||
console.log(img.value);
|
||||
camera.value?.stop()
|
||||
const url = URL.createObjectURL(imageBlob)
|
||||
img.value = url
|
||||
}
|
||||
|
||||
if (mediaStream.value) {
|
||||
mediaStream.value.getTracks().forEach((track) => track.stop());
|
||||
videoElement.srcObject = null;
|
||||
hasPhoto.value = false;
|
||||
}
|
||||
}
|
||||
function refreshPhoto() {
|
||||
hasPhoto.value = true;
|
||||
img.value = "";
|
||||
img.value = undefined
|
||||
camera.value?.start()
|
||||
}
|
||||
|
||||
// validate
|
||||
const useLocationRef = ref<object | null>(null);
|
||||
const modelRef = ref<object | null>(null);
|
||||
const useLocationRef = ref<object | null>(null)
|
||||
const modelRef = ref<object | null>(null)
|
||||
const objectRef: FormRef = {
|
||||
model: modelRef,
|
||||
useLocation: useLocationRef,
|
||||
};
|
||||
}
|
||||
function validateForm() {
|
||||
const hasError = [];
|
||||
const hasError = []
|
||||
for (const key in objectRef) {
|
||||
if (Object.prototype.hasOwnProperty.call(objectRef, key)) {
|
||||
const property = objectRef[key];
|
||||
if (property.value && typeof property.value.validate === "function") {
|
||||
const isValid = property.value.validate();
|
||||
hasError.push(isValid);
|
||||
const property = objectRef[key]
|
||||
if (property.value && typeof property.value.validate === 'function') {
|
||||
const isValid = property.value.validate()
|
||||
hasError.push(isValid)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasError.every((result) => result === true)) {
|
||||
confirm();
|
||||
confirm()
|
||||
} else {
|
||||
console.log("ไม่ผ่าน ");
|
||||
console.log('ไม่ผ่าน ')
|
||||
}
|
||||
}
|
||||
// ยืนยันการลงเวลา
|
||||
const dialogTime = ref<boolean>(false);
|
||||
const dialogTime = ref<boolean>(false)
|
||||
const confirm = () => {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
dialogTime.value = true;
|
||||
},
|
||||
"ยืนยันการบันทึกเวลา ?",
|
||||
"ต้องการยืนยันการบันทึกการลงเวลานี้ใช่หรือไม่"
|
||||
);
|
||||
};
|
||||
// ยิงไปที่ api แล้วแสดง popup
|
||||
dialogTime.value = true
|
||||
}
|
||||
|
||||
// class
|
||||
const getClass = (val: boolean) => {
|
||||
return {
|
||||
"bg-primary text-white col-12 row items-center q-px-md q-py-sm": val,
|
||||
"bg-red-9 text-white col-12 row items-center q-px-md q-py-sm": !val,
|
||||
};
|
||||
};
|
||||
'bg-primary text-white col-12 row items-center q-px-md q-py-sm': val,
|
||||
'bg-red-9 text-white col-12 row items-center q-px-md q-py-sm': !val,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -263,13 +195,12 @@ const getClass = (val: boolean) => {
|
|||
<MapCheck />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
class="card-container"
|
||||
@click="openCamera()"
|
||||
>
|
||||
<div v-if="!camera" class="preview-placeholder">
|
||||
<q-card flat bordered class="card-container">
|
||||
<div
|
||||
v-if="!cameraIsOn && img == null"
|
||||
class="preview-placeholder"
|
||||
@click="openCamera()"
|
||||
>
|
||||
<div class="text-center">
|
||||
<q-icon
|
||||
name="photo_camera"
|
||||
|
|
@ -279,18 +210,26 @@ const getClass = (val: boolean) => {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="hasPhoto" class="video-container">
|
||||
<video ref="video" autoplay class="video-element"></video>
|
||||
<canvas ref="canvas" class="canvas-element"></canvas>
|
||||
</div>
|
||||
<div v-else class="image-container">
|
||||
<div>
|
||||
<!-- แสดงกล้องตอนกดถ่ายภาพ -->
|
||||
<Camera
|
||||
:resolution="{ width: photoWidth, height: photoHeight }"
|
||||
ref="camera"
|
||||
:autoplay="false"
|
||||
:style="!img ? 'display: block' : 'display: none'"
|
||||
/>
|
||||
|
||||
<!-- แสดงรูปเมื่อกด capture -->
|
||||
<div v-if="img" class="image-container">
|
||||
<q-img :src="img" class="image-element"></q-img>
|
||||
<canvas ref="canvas" class="canvas-element"></canvas>
|
||||
</div>
|
||||
<div class="absolute-bottom-right q-ma-md">
|
||||
|
||||
<div
|
||||
v-if="cameraIsOn"
|
||||
class="absolute-bottom-right q-ma-md"
|
||||
>
|
||||
<q-btn
|
||||
v-if="hasPhoto"
|
||||
v-if="img == null"
|
||||
round
|
||||
push
|
||||
icon="photo_camera"
|
||||
|
|
@ -311,6 +250,7 @@ const getClass = (val: boolean) => {
|
|||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
||||
<div class="col-12 q-mb-md">
|
||||
<q-card
|
||||
bordered
|
||||
|
|
@ -377,6 +317,7 @@ const getClass = (val: boolean) => {
|
|||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
|
||||
<div class="col-12 text-right">
|
||||
<q-separator />
|
||||
<div class="col-12 q-pa-md">
|
||||
|
|
@ -471,8 +412,6 @@ const getClass = (val: boolean) => {
|
|||
height: 350px; /* Adjust as needed */
|
||||
background: #f6f5f5;
|
||||
}
|
||||
|
||||
.video-container,
|
||||
.image-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
@ -481,7 +420,6 @@ const getClass = (val: boolean) => {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.video-element,
|
||||
.image-element {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -489,7 +427,8 @@ const getClass = (val: boolean) => {
|
|||
border-radius: 5px; /* Adjust as needed */
|
||||
}
|
||||
|
||||
.canvas-element {
|
||||
display: none; /* Adjust as needed */
|
||||
.preview-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
42
src/views/SampleCamera.vue
Normal file
42
src/views/SampleCamera.vue
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<script setup lang="ts">
|
||||
import Camera from 'simple-vue-camera'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const camera = ref<InstanceType<typeof Camera>>();
|
||||
|
||||
const cameraIsOn = ref<boolean>(false)
|
||||
|
||||
const cameraOff = () => {
|
||||
cameraIsOn.value ? camera.value?.stop() : camera.value?.start()
|
||||
cameraIsOn.value = !cameraIsOn.value
|
||||
}
|
||||
|
||||
// Use camera reference to call functions
|
||||
const takePicture = async () => {
|
||||
const imageBlob = await camera.value?.snapshot(
|
||||
{ width: 640, height: 480 },
|
||||
'image/png',
|
||||
0.5
|
||||
)
|
||||
|
||||
console.log('imageBlob', imageBlob)
|
||||
camera.value?.stop()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row col-12">
|
||||
<div class="col-3">
|
||||
<Camera
|
||||
:resolution="{ width: 500, height: 500 }"
|
||||
ref="camera"
|
||||
:autoplay="false"
|
||||
>
|
||||
<q-btn color="primary" @click="cameraOff"
|
||||
>I'm on top of the video</q-btn
|
||||
>
|
||||
<q-btn color="primary" @click="takePicture">Take Picture</q-btn>
|
||||
</Camera>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Loading…
Add table
Add a link
Reference in a new issue