load video without click
This commit is contained in:
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
src/App.vue
10
src/App.vue
@ -1,14 +1,19 @@
|
||||
<template>
|
||||
<!-- <List>123132</List> -->
|
||||
<CameraList />
|
||||
<!-- <CameraItem-->
|
||||
<!-- name="测试球机视频"-->
|
||||
<!-- source="https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv"-->
|
||||
<!-- />-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CameraList from "./components/CameraList.vue";
|
||||
// import CameraItem from "@/components/CameraItem.vue";
|
||||
// import List from "./infinite-list-vue.umd.cjs";
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
// CameraItem,
|
||||
CameraList,
|
||||
},
|
||||
};
|
||||
@ -17,7 +22,6 @@ export default {
|
||||
<style>
|
||||
#app {
|
||||
background-color: #f6f6f6;
|
||||
//width: 100vw;
|
||||
//height: 100vh;
|
||||
//width: 100vw; //height: 100vh;
|
||||
}
|
||||
</style>
|
||||
|
@ -3,10 +3,12 @@
|
||||
<div class="camera-name">
|
||||
{{ props.name }}
|
||||
</div>
|
||||
<video ref="previewVideoRef" class="camera-player"></video>
|
||||
<video
|
||||
ref="videoElementRef"
|
||||
:class="`camera-player ${isFullscreen ? 'fullscreen-video' : ''}`"
|
||||
></video>
|
||||
<div class="overlay" @click="openPlayModal">
|
||||
<!-- <img src="../assets/stLine-play-l@3x.png" alt="" width="40" height="40" /> -->
|
||||
<span class="iconfont icon-bofang_o" style="font-size: 60px"></span>
|
||||
<!-- <span class="iconfont icon-bofang_o" style="font-size: 60px"></span>-->
|
||||
</div>
|
||||
<div v-if="showModal" class="modal-overlay" @click="closePlayModal">
|
||||
<span
|
||||
@ -15,16 +17,14 @@
|
||||
@click.stop="exitFullscreen"
|
||||
></span>
|
||||
<div ref="rotateElementRef" :class="`modal`">
|
||||
<video
|
||||
ref="videoElementRef"
|
||||
:class="`camera-player ${isFullscreen ? 'fullscreen-video' : ''}`"
|
||||
></video>
|
||||
|
||||
<div
|
||||
:class="`video-overlay ${isFullscreen ? 'fullscreen-video' : ''}`"
|
||||
@click.stop="switchPlayStatus"
|
||||
>
|
||||
<div v-if="isFullscreen" class="arrow-control">
|
||||
<div
|
||||
v-if="isFullscreen && props.name.includes('球机')"
|
||||
class="arrow-control"
|
||||
>
|
||||
<div
|
||||
:class="`up iconfont icon-up ${pressed.up ? 'pressed' : ''}`"
|
||||
@touchend="moveCamera('stop')"
|
||||
@ -67,108 +67,83 @@
|
||||
</div>
|
||||
</template>
|
||||
<script name="camera" setup>
|
||||
import { nextTick, onUnmounted, reactive, ref, toRefs } from "vue";
|
||||
import { nextTick, onMounted, onUnmounted, reactive, ref, toRefs } from "vue";
|
||||
import flvjs from "flv.js";
|
||||
import axios from "axios";
|
||||
// import { useRoute } from "vue-router";
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
default:
|
||||
"https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv",
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const { source } = toRefs(props);
|
||||
// const route = useRoute();
|
||||
// document.title = route.query.proname;
|
||||
const showModal = ref(false);
|
||||
const isFullscreen = ref(false);
|
||||
const rotateElementRef = ref();
|
||||
const videoElementRef = ref();
|
||||
let flvPlayer;
|
||||
// const previewVideoRef = ref();
|
||||
// onMounted(() => {
|
||||
// const flvPlayer = flvjs.createPlayer({
|
||||
// type: "flv",
|
||||
// url: props.source,
|
||||
// isLive: true,
|
||||
// });
|
||||
// flvPlayer.attachMediaElement(previewVideoRef.value);
|
||||
// flvPlayer.load();
|
||||
// console.log();
|
||||
// // loadVideo(props.source);
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
flvPlayer = flvjs.createPlayer({
|
||||
type: "flv",
|
||||
url: props.source,
|
||||
});
|
||||
if (flvjs.isSupported()) {
|
||||
flvPlayer.attachMediaElement(videoElementRef.value);
|
||||
flvPlayer.load();
|
||||
flvPlayer.on("ERROR", flvPlayerEventHandler);
|
||||
}
|
||||
});
|
||||
const openPlayModal = () => {
|
||||
showModal.value = true;
|
||||
nextTick(() => {
|
||||
flvPlayer = flvjs.createPlayer({
|
||||
type: "flv",
|
||||
url: props.source,
|
||||
});
|
||||
if (videoElementRef.value) {
|
||||
rotateElementRef.value.appendChild(videoElementRef.value);
|
||||
}
|
||||
if (flvjs.isSupported()) {
|
||||
flvPlayer.attachMediaElement(videoElementRef.value);
|
||||
// flvPlayer.attachMediaElement();
|
||||
flvPlayer.load();
|
||||
flvPlayer.on("ERROR", flvPlayerEventHandler);
|
||||
flvPlayer.play();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// file为视频的文件对象,可使用 input[file] 进行获取
|
||||
const loadVideo = async (url) => {
|
||||
const resp = await axios.get(url);
|
||||
const file = new File([resp.data], "monitor.flv");
|
||||
console.log(file);
|
||||
return new Promise(function (resolve, reject) {
|
||||
const videoElem = document.createElement("video");
|
||||
const dataUrl = URL.createObjectURL(file);
|
||||
// 当前帧的数据是可用的
|
||||
videoElem.onloadeddata = function () {
|
||||
resolve(videoElem);
|
||||
};
|
||||
videoElem.onerror = function (e) {
|
||||
console.log(e);
|
||||
reject("video 后台加载失败");
|
||||
};
|
||||
// 设置 auto 预加载数据, 否则会出现截图为黑色图片的情况
|
||||
videoElem.setAttribute("preload", "auto");
|
||||
videoElem.src = dataUrl;
|
||||
const closePlayModal = () => {
|
||||
// flvPlayer.on("ERROR", flvPlayerEventHandler);
|
||||
// flvPlayer.pause();
|
||||
// flvPlayer.unload();
|
||||
// flvPlayer.detachMediaElement();
|
||||
// flvPlayer.destroy();
|
||||
// flvPlayer = null;
|
||||
showModal.value = false;
|
||||
nextTick(() => {
|
||||
document.querySelector(".camera-item")?.appendChild(videoElementRef.value);
|
||||
if (flvjs.isSupported()) {
|
||||
flvPlayer.pause();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const closePlayModal = () => {
|
||||
flvPlayer.on("ERROR", flvPlayerEventHandler);
|
||||
flvPlayer.pause();
|
||||
flvPlayer.unload();
|
||||
flvPlayer.detachMediaElement();
|
||||
flvPlayer.destroy();
|
||||
flvPlayer = null;
|
||||
showModal.value = false;
|
||||
};
|
||||
const videoElementRef = ref();
|
||||
// const playBtnRef = ref();
|
||||
// let flvPlayer = flvjs.createPlayer({
|
||||
// type: "flv",
|
||||
// url: "https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv",
|
||||
// });
|
||||
|
||||
const flvPlayerEventHandler = (e) => {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
// 切换播放状态
|
||||
const switchPlayStatus = () => {
|
||||
if (!videoElementRef.value) return;
|
||||
if (videoElementRef.value.paused) {
|
||||
console.log(flvPlayer);
|
||||
flvPlayer.play();
|
||||
} else {
|
||||
flvPlayer.pause();
|
||||
// flvPlayer.pause();
|
||||
}
|
||||
};
|
||||
const isFullscreen = ref(false);
|
||||
const rotateElementRef = ref();
|
||||
|
||||
/* 进入全屏 */
|
||||
const videoFullscreen = () => {
|
||||
const scale = screen.availWidth / videoElementRef.value.offsetHeight;
|
||||
videoElementRef.value.style.setProperty("--scale", scale);
|
||||
@ -176,6 +151,11 @@ const videoFullscreen = () => {
|
||||
isFullscreen.value = true;
|
||||
};
|
||||
|
||||
/* 退出全屏 */
|
||||
const exitFullscreen = () => {
|
||||
isFullscreen.value = false;
|
||||
};
|
||||
|
||||
const token = ref("");
|
||||
const loadToken = async () => {
|
||||
const url = new URL(source.value);
|
||||
@ -185,17 +165,23 @@ const loadToken = async () => {
|
||||
return resp.data.URLToken;
|
||||
};
|
||||
|
||||
/*方向按钮是否按下*/
|
||||
const pressed = reactive({
|
||||
left: false,
|
||||
right: false,
|
||||
up: false,
|
||||
down: false,
|
||||
});
|
||||
|
||||
/**
|
||||
* 控制摄像头转动
|
||||
* @param arrow 上下左右和停止
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
const moveCamera = async (arrow) => {
|
||||
if (!token.value) {
|
||||
token.value = await loadToken();
|
||||
}
|
||||
|
||||
const serial = source.value.split("/flv/hls/")[1].split("_")[0];
|
||||
const url = new URL(source.value);
|
||||
await axios.get(
|
||||
@ -211,9 +197,6 @@ const moveCamera = async (arrow) => {
|
||||
}
|
||||
};
|
||||
|
||||
const exitFullscreen = () => {
|
||||
isFullscreen.value = false;
|
||||
};
|
||||
onUnmounted(() => {
|
||||
console.log("destroy player here");
|
||||
|
||||
@ -235,7 +218,7 @@ onUnmounted(() => {
|
||||
@import "../assets/fonts/iconfont.css";
|
||||
|
||||
.camera-item {
|
||||
// height: 300px;
|
||||
height: 400px;
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 20px;
|
||||
@ -282,8 +265,7 @@ onUnmounted(() => {
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
// position: relative;
|
||||
background-color: rgba(153, 153, 153, 0.363);
|
||||
backdrop-filter: blur(12px);
|
||||
|
||||
.quit-fullscreen {
|
||||
position: fixed;
|
||||
@ -312,14 +294,9 @@ onUnmounted(() => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
//background-color: #eee;
|
||||
z-index: 999999;
|
||||
left: 0;
|
||||
top: 0;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// z-index: 99;
|
||||
// position: relative;
|
||||
.fullscreen {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
@ -354,6 +331,7 @@ onUnmounted(() => {
|
||||
right: 25px;
|
||||
bottom: 25px;
|
||||
z-index: 9999;
|
||||
backdrop-filter: blur(12px);
|
||||
|
||||
.iconfont {
|
||||
width: 32px;
|
@ -5,31 +5,18 @@
|
||||
<NSelect
|
||||
v-model:value="queryParams.query"
|
||||
:options="projectList"
|
||||
placeholder="请选择项目"
|
||||
label-field="PRONAME"
|
||||
placeholder="请选择项目"
|
||||
value-field="PROID"
|
||||
@update:value="projectClicked"
|
||||
/>
|
||||
</NConfigProvider>
|
||||
</div>
|
||||
|
||||
<!-- <select
|
||||
name="pets"
|
||||
v-model="queryParams.query"
|
||||
id="proj-select"
|
||||
@change="projectClicked"
|
||||
>
|
||||
<option value="">请选择项目</option>
|
||||
<option v-for="item in projectList" :value="item.PROID">
|
||||
{{ item.PRONAME }}
|
||||
</option>
|
||||
</select> -->
|
||||
|
||||
<div v-if="queryParams.query" class="naive-tabs">
|
||||
<NTabs type="segment">
|
||||
<NTabPane name="camera" tab="摄像头列表">
|
||||
<!-- v-if="queryParams.query && activeIndex == 0" -->
|
||||
<div class="camera-list" ref="cameraListRef">
|
||||
<div ref="cameraListRef" class="camera-list">
|
||||
<camera
|
||||
v-for="(item, index) in cameraList"
|
||||
:key="index"
|
||||
@ -37,7 +24,7 @@
|
||||
:source="item.flvUrl"
|
||||
></camera>
|
||||
<div v-if="!cameraList.length" class="empty">
|
||||
<img src="../assets/empty.png" alt="" />
|
||||
<img alt="" src="../assets/empty.png" />
|
||||
摄像头列表为空
|
||||
</div>
|
||||
</div>
|
||||
@ -45,46 +32,31 @@
|
||||
<NTabPane name="image" tab="图片列表">
|
||||
<!-- v-else-if="queryParams.query && activeIndex == 1" -->
|
||||
<div class="image-list">
|
||||
<div class="image-item" v-for="item in imageList" :key="item.PIC">
|
||||
<div v-for="item in imageList" :key="item.PIC" class="image-item">
|
||||
<!-- <img :src="`${protocol}//${host}/portal/r/${item}`" alt="" /> -->
|
||||
<!-- <img :src="`http://81.68.90.198:8088/portal/r/${item}`" alt="" /> -->
|
||||
<!-- TODO:test -->
|
||||
<!-- :src="`${protocol}//${host}/portal/r/${item.PIC}`" -->
|
||||
<NImage
|
||||
class="n-image-item"
|
||||
:src="`http://81.68.90.198:8088/portal/r/${item.PIC}`"
|
||||
:previewed-img-props="{
|
||||
draggable: true,
|
||||
style: { border: 'none' },
|
||||
}"
|
||||
:src="`http://81.68.90.198:8088/portal/r/${item.PIC}`"
|
||||
class="n-image-item"
|
||||
></NImage>
|
||||
<div class="uplode-time">{{ item.CREATEDATE }}</div>
|
||||
</div>
|
||||
<div v-if="!imageList.length" class="empty">
|
||||
<img src="../assets/empty.png" alt="" />
|
||||
<img alt="" src="../assets/empty.png" />
|
||||
图片列表为空
|
||||
</div>
|
||||
</div>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</div>
|
||||
<!-- <div class="switch" v-if="queryParams.query">
|
||||
<div
|
||||
:class="`switch-item ${activeIndex == 0 ? 'active' : ''}`"
|
||||
@click="activeIndex = 0"
|
||||
>
|
||||
摄像头列表
|
||||
</div>
|
||||
<div
|
||||
:class="`switch-item ${activeIndex == 1 ? 'active' : ''}`"
|
||||
@click="activeIndex = 1"
|
||||
>
|
||||
图片列表
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div v-else class="empty">
|
||||
<img src="../assets/empty.png" alt="" />
|
||||
<img alt="" src="../assets/empty.png" />
|
||||
请选择项目
|
||||
</div>
|
||||
</div>
|
||||
@ -92,16 +64,17 @@
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from "vue";
|
||||
import camera from "./camera.vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
NSelect,
|
||||
NConfigProvider,
|
||||
zhCN,
|
||||
NTabs,
|
||||
NTabPane,
|
||||
NImage,
|
||||
NSelect,
|
||||
NTabPane,
|
||||
NTabs,
|
||||
zhCN,
|
||||
} from "naive-ui";
|
||||
import Camera from "./CameraItem.vue";
|
||||
|
||||
const cameraLoading = ref(true);
|
||||
const projectList = ref([
|
||||
// {
|
||||
@ -120,18 +93,18 @@ const queryParams = reactive({
|
||||
cmd: "com.awspaas.user.apps.cmp_camera_list",
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// sid: sid,
|
||||
sid: sid,
|
||||
// TODO:test
|
||||
sid: "b9e99f78-2f6e-4d1c-aea9-4364f4191d30",
|
||||
// sid: "b9e99f78-2f6e-4d1c-aea9-4364f4191d30",
|
||||
query: undefined,
|
||||
});
|
||||
// const activeIndex = ref(0);
|
||||
const loadProjectList = async () => {
|
||||
// const resp = await axios.get(`http://localhost:3000/project-list`);
|
||||
// TODO:test
|
||||
const resp = await axios.get(
|
||||
"/api/portal/r/jd?cmd=com.awspaas.user.apps.cmp_screen_getProjectList&sid=b9e99f78-2f6e-4d1c-aea9-4364f4191d30"
|
||||
);
|
||||
// const resp = await axios.get(
|
||||
// "/api/portal/r/jd?cmd=com.awspaas.user.apps.cmp_screen_getProjectList&sid=b9e99f78-2f6e-4d1c-aea9-4364f4191d30"
|
||||
// );
|
||||
// const resp = {
|
||||
// data: [{
|
||||
// "SUPERVISORID": "",
|
||||
@ -180,9 +153,9 @@ const loadProjectList = async () => {
|
||||
// "ID": "a0fb6df5-48e4-442f-8b9d-da5861c1bf41"
|
||||
// }]
|
||||
// }
|
||||
// const resp = await axios.get(
|
||||
// "./jd?cmd=com.awspaas.user.apps.cmp_screen_getProjectList&sid=" + sid
|
||||
// );
|
||||
const resp = await axios.get(
|
||||
"./jd?cmd=com.awspaas.user.apps.cmp_screen_getProjectList&sid=" + sid
|
||||
);
|
||||
return resp.data;
|
||||
};
|
||||
|
||||
@ -198,9 +171,9 @@ const projectClicked = () => {
|
||||
const loadCameraList = async () => {
|
||||
cameraLoading.value = true;
|
||||
// TODO:test
|
||||
const resp = await axios(`/api/portal/r/jd`, {
|
||||
params: queryParams,
|
||||
});
|
||||
// const resp = await axios(`/api/portal/r/jd`, {
|
||||
// params: queryParams,
|
||||
// });
|
||||
// const resp = {
|
||||
// data: {
|
||||
// "code": 0,
|
||||
@ -232,19 +205,12 @@ const loadCameraList = async () => {
|
||||
// "total": 4
|
||||
// }
|
||||
// }
|
||||
const resp = await axios.get("./jd", {
|
||||
params: queryParams,
|
||||
});
|
||||
cameraList.value = resp.data.rows;
|
||||
total.value = resp.data.total;
|
||||
cameraLoading.value = false;
|
||||
// if (total.value == 0) {
|
||||
// const rep = await axios.get(
|
||||
// `./jd?cmd=com.awspaas.user.apps.cmp_photo_list&sid=${sid}&proId=${queryParams.query}`
|
||||
// ); // 摄像头列表为空时,获取图片列表
|
||||
|
||||
// const rep = await axios.get(
|
||||
// `/api/portal/r/jd?cmd=com.awspaas.user.apps.cmp_photo_list&sid=${sid}&proId=${queryParams.query}`
|
||||
// ); // 摄像头列表为空时,获取图片列表
|
||||
// imageList.value = rep.data;
|
||||
// }
|
||||
};
|
||||
|
||||
const loadImageList = async () => {
|
||||
@ -253,7 +219,7 @@ const loadImageList = async () => {
|
||||
// ); // 摄像头列表为空时,获取图片列表
|
||||
// TODO:test
|
||||
const resp = await axios.get(
|
||||
`/api/portal/r/jd?cmd=com.awspaas.user.apps.cmp_photo_list&sid=b9e99f78-2f6e-4d1c-aea9-4364f4191d30&proId=${queryParams.query}`
|
||||
`./jd?cmd=com.awspaas.user.apps.cmp_photo_list&sid=${sid}&proId=${queryParams.query}`
|
||||
); // 摄像头列表为空时,获取图片列表
|
||||
imageList.value = resp.data;
|
||||
};
|
||||
@ -286,31 +252,29 @@ loadProjectList().then((data) => {
|
||||
projectList.value = data;
|
||||
if (projectList.value.length) return projectList.value[0].PROID;
|
||||
});
|
||||
// .then((proid) => {
|
||||
// queryParams.query = proid;
|
||||
// queryParams.pageNum = 1;
|
||||
// loadCameraList();
|
||||
// });
|
||||
</script>
|
||||
<style>
|
||||
/* body {
|
||||
background-color: #f6f6f6;
|
||||
} */
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.naive-select-wrap {
|
||||
width: 750px;
|
||||
padding: 20px 20px 0px;
|
||||
}
|
||||
|
||||
.naive-tabs {
|
||||
padding: 20px 20px 0;
|
||||
}
|
||||
|
||||
.nav-bar {
|
||||
width: 750px;
|
||||
height: 88px;
|
||||
@ -322,6 +286,7 @@ loadProjectList().then((data) => {
|
||||
font-size: 32px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.switch {
|
||||
width: 686px;
|
||||
height: 76px;
|
||||
@ -332,6 +297,7 @@ loadProjectList().then((data) => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
|
||||
.switch-item {
|
||||
width: 331px;
|
||||
height: 60px;
|
||||
@ -339,20 +305,24 @@ loadProjectList().then((data) => {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.camera-list {
|
||||
// margin-top: 108px;
|
||||
// padding: 0px 20px 0px;
|
||||
}
|
||||
|
||||
.image-list {
|
||||
// padding: 0px 20px 0px;
|
||||
.image-item {
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
|
||||
.uplode-time {
|
||||
color: indianred;
|
||||
position: absolute;
|
||||
@ -364,6 +334,7 @@ loadProjectList().then((data) => {
|
||||
border-radius: 999px;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
// border-radius: 10px;
|
||||
// overflow: hidden;
|
||||
:deep(.n-image-item) {
|
||||
@ -375,6 +346,7 @@ loadProjectList().then((data) => {
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// img {
|
||||
// object-fit: cover;
|
||||
// border-radius: 10px;
|
||||
@ -392,6 +364,7 @@ loadProjectList().then((data) => {
|
||||
margin: 2vw 2vw 5vw 2vw;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.empty {
|
||||
// flex: 1;
|
||||
flex-grow: 1;
|
||||
@ -399,9 +372,11 @@ loadProjectList().then((data) => {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
// height:80vh;
|
||||
}
|
||||
</style>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import camera from "./camera.vue";
|
||||
import camera from "./CameraItem.vue";
|
||||
|
||||
const cameraList = ref([
|
||||
{
|
||||
|
@ -13,6 +13,6 @@ module.exports = defineConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
publicPath: "./",
|
||||
assetsDir: "../apps/com.awspaas.user.apps.cmp/monitor",
|
||||
// publicPath: "./",
|
||||
// assetsDir: "../apps/com.awspaas.user.apps.cmp/monitor",
|
||||
});
|
||||
|
Reference in New Issue
Block a user