| @@ -84,7 +84,8 @@ export default { | |||
| // uploadImgTip2:'Please upload unobstructed frontal photo', | |||
| uploadImgTip2:'please upload a clear frontal photo', | |||
| entered:'entered' | |||
| entered:'entered', | |||
| subtitles:"subtitles", | |||
| }, | |||
| // 我的视频 | |||
| @@ -83,6 +83,7 @@ export default { | |||
| uploadImgTip1:'点此上传图片', | |||
| uploadImgTip2:'请确保上传图片为无遮挡的正脸图片', | |||
| entered:'已输入', | |||
| subtitles:"字幕", | |||
| }, | |||
| // 我的视频 | |||
| @@ -0,0 +1,133 @@ | |||
| <template> | |||
| <div :class="classObj" class="app-wrapper"> | |||
| <!-- 手机设备侧边栏打开遮罩层 --> | |||
| <div | |||
| v-if="classObj.mobile && classObj.openSidebar" | |||
| class="drawer-bg" | |||
| @click="handleOutsideClick" | |||
| ></div> | |||
| <Sidebar class="sidebar-container" /> | |||
| <div :class="{ hasTagsView: showTagsView }" class="main-container"> | |||
| <div :class="{ 'fixed-header': fixedHeader }"> | |||
| <navbar /> | |||
| <tags-view v-if="showTagsView" /> | |||
| </div> | |||
| <!--主页面--> | |||
| <app-main /> | |||
| <!-- 设置面板 --> | |||
| <RightPanel v-if="showSettings"> | |||
| <settings /> | |||
| </RightPanel> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script setup lang="ts"> | |||
| import { computed, watchEffect } from "vue"; | |||
| import { useWindowSize } from "@vueuse/core"; | |||
| import { AppMain, Navbar, Settings, TagsView } from "./components/index"; | |||
| import SignSucceed from "../views/signSucceed/index.vue"; | |||
| import Sidebar from "./components/Sidebar/index.vue"; | |||
| import RightPanel from "@/components/RightPanel/index.vue"; | |||
| import { useAppStore } from "@/store/modules/app"; | |||
| import { useSettingsStore } from "@/store/modules/settings"; | |||
| import { useRoute, useRouter } from "vue-router"; | |||
| const route = useRoute(); | |||
| const { params } = route; | |||
| const { width } = useWindowSize(); | |||
| /** | |||
| * 响应式布局容器固定宽度 | |||
| * | |||
| * 大屏(>=1200px) | |||
| * 中屏(>=992px) | |||
| * 小屏(>=768px) | |||
| */ | |||
| const WIDTH = 992; | |||
| const appStore = useAppStore(); | |||
| const settingsStore = useSettingsStore(); | |||
| const fixedHeader = computed(() => settingsStore.fixedHeader); | |||
| const showTagsView = computed(() => settingsStore.tagsView); | |||
| const showSettings = computed(() => settingsStore.showSettings); | |||
| const classObj = computed(() => ({ | |||
| hideSidebar: !appStore.sidebar.opened, | |||
| openSidebar: appStore.sidebar.opened, | |||
| withoutAnimation: appStore.sidebar.withoutAnimation, | |||
| mobile: appStore.device === "mobile", | |||
| })); | |||
| watchEffect(() => { | |||
| if (width.value < WIDTH) { | |||
| appStore.toggleDevice("mobile"); | |||
| appStore.closeSideBar(true); | |||
| } else { | |||
| appStore.toggleDevice("desktop"); | |||
| if (width.value >= 1200) { | |||
| //大屏 | |||
| appStore.openSideBar(true); | |||
| } else { | |||
| appStore.closeSideBar(true); | |||
| } | |||
| } | |||
| }); | |||
| function handleOutsideClick() { | |||
| appStore.closeSideBar(false); | |||
| } | |||
| onMounted(() => {}); | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .app-wrapper { | |||
| &::after { | |||
| display: table; | |||
| clear: both; | |||
| content: ""; | |||
| } | |||
| position: relative; | |||
| width: 100%; | |||
| height: 100%; | |||
| e &.mobile.openSidebar { | |||
| position: fixed; | |||
| top: 0; | |||
| } | |||
| } | |||
| .fixed-header { | |||
| position: fixed; | |||
| top: 0; | |||
| right: 0; | |||
| z-index: 9; | |||
| width: calc(100% - #{$sideBarWidth}); | |||
| transition: width 0.28s; | |||
| } | |||
| .hideSidebar .fixed-header { | |||
| width: calc(100% - 54px); | |||
| } | |||
| .mobile .fixed-header { | |||
| width: 100%; | |||
| } | |||
| .drawer-bg { | |||
| position: absolute; | |||
| top: 0; | |||
| z-index: 999; | |||
| width: 100%; | |||
| height: 100%; | |||
| background: #000; | |||
| opacity: 0.3; | |||
| } | |||
| </style> | |||
| @@ -1,27 +1,101 @@ | |||
| <template> | |||
| <div :class="classObj" class="app-wrapper"> | |||
| <!-- 手机设备侧边栏打开遮罩层 --> | |||
| <div | |||
| v-if="classObj.mobile && classObj.openSidebar" | |||
| class="drawer-bg" | |||
| @click="handleOutsideClick" | |||
| ></div> | |||
| <Sidebar class="sidebar-container" /> | |||
| <div :class="{ hasTagsView: showTagsView }" class="main-container"> | |||
| <div :class="{ 'fixed-header': fixedHeader }"> | |||
| <navbar /> | |||
| <tags-view v-if="showTagsView" /> | |||
| <div class="app-wrapper"> | |||
| <!-- 侧边栏 --> | |||
| <div class="Sidebar"> | |||
| <div class="imgBox"> | |||
| <img | |||
| class="boxCentreImg" | |||
| src="../assets//img/left-top-logo.png" | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <!-- 侧边路由列表 --> | |||
| <div class="myRouter"> | |||
| <!-- 创建视频页 --> | |||
| <div class="myRouter-item" @click="router.push('/createVideo')"> | |||
| <div class="icon"> | |||
| <el-icon><i-ep-edit /></el-icon> | |||
| </div> | |||
| {{ $t("createVideo.title") }} | |||
| </div> | |||
| <!-- 我的视频 --> | |||
| <div class="myRouter-item" @click="router.push('/myCreating')"> | |||
| <div class="icon"> | |||
| <el-icon><i-ep-menu /></el-icon> | |||
| </div> | |||
| {{ $t("myCreating.title") }} | |||
| </div> | |||
| <!-- 测试功能页 --> | |||
| <div | |||
| v-if="false" | |||
| class="myRouter-item" | |||
| @click="router.push('/moveImg')" | |||
| > | |||
| <div class="icon"> | |||
| <el-icon><i-ep-edit /></el-icon> | |||
| </div> | |||
| {{ $t("createVideo.title") }} | |||
| </div> | |||
| <!-- 商店 --> | |||
| <div class="myRouter-item pricing" @click="router.push('/myStore')"> | |||
| <div class="icon"> | |||
| <el-icon><i-ep-Goods /></el-icon> | |||
| </div> | |||
| {{ $t("shop.title") }} | |||
| </div> | |||
| <!-- api --> | |||
| <div class="myRouter-item API" @click="router.push('/APIAccess')"> | |||
| <div class="icon"> | |||
| <el-icon><i-ep-DocumentAdd /></el-icon> | |||
| </div> | |||
| {{ $t("API.title") }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 右边显示部分 --> | |||
| <div class="rightBox"> | |||
| <!-- nav栏 --> | |||
| <div class="nav"> | |||
| <!-- 路由名字 --> | |||
| <div style="position: absolute; left: 30px; font-size: 26px"> | |||
| {{ $t(routeName as string) }} | |||
| </div> | |||
| <!-- 语言 --> | |||
| <!--语言选择--> | |||
| <el-tooltip | |||
| style="cursor: pointer; z-index: 999" | |||
| class="box-item" | |||
| effect="dark" | |||
| :content="$t('navbar.LanguageChange')" | |||
| placement="top-start" | |||
| > | |||
| <lang-select class="navItem" style="color: #ffffff" /> | |||
| </el-tooltip> | |||
| <!-- 账户 --> | |||
| <div | |||
| class="navItem" | |||
| v-if="AccessToken" | |||
| @click="router.push('myAccount')" | |||
| > | |||
| {{ $t("navbar.account") }} | |||
| </div> | |||
| <!-- 登录 --> | |||
| <div class="navItem" v-if="!AccessToken" @click="router.push('login')"> | |||
| {{ $t("navbar.goLogin") }} | |||
| </div> | |||
| <!--主页面--> | |||
| <app-main /> | |||
| <!-- 设置面板 --> | |||
| <RightPanel v-if="showSettings"> | |||
| <settings /> | |||
| </RightPanel> | |||
| <!-- 注销 --> | |||
| <div | |||
| class="navItem" | |||
| v-if="AccessToken" | |||
| @click="logout" | |||
| style="margin-left: 10px" | |||
| > | |||
| {{ $t("navbar.logout") }} | |||
| </div> | |||
| </div> | |||
| <!-- 主页面 --> | |||
| <app-main style="background-color: #000" /> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| @@ -29,18 +103,42 @@ | |||
| <script setup lang="ts"> | |||
| import { computed, watchEffect } from "vue"; | |||
| import { useWindowSize } from "@vueuse/core"; | |||
| import { AppMain, Navbar, Settings, TagsView } from "./components/index"; | |||
| import SignSucceed from "../views/signSucceed/index.vue"; | |||
| import Sidebar from "./components/Sidebar/index.vue"; | |||
| import RightPanel from "@/components/RightPanel/index.vue"; | |||
| import { AppMain, Navbar } from "./components/index"; | |||
| import LangSelect from "@/components/LangSelect/index.vue"; | |||
| import { useAppStore } from "@/store/modules/app"; | |||
| import { useSettingsStore } from "@/store/modules/settings"; | |||
| // import { useSettingsStore } from "@/store/modules/settings"; | |||
| import { useRoute, useRouter } from "vue-router"; | |||
| import { useI18n } from "vue-i18n"; | |||
| import { userInfoModules } from "@/store/modules/userInfo"; | |||
| const userInfoPinia = userInfoModules(); | |||
| const route = useRoute(); | |||
| const router = useRouter(); | |||
| const { params } = route; | |||
| const { width } = useWindowSize(); | |||
| const AccessToken = localStorage.getItem("AccessToken"); | |||
| // 当前语言状态与国际化组件 | |||
| const { locale } = useI18n(); | |||
| const lanChange = ref(locale); | |||
| function logout() { | |||
| const msg = | |||
| (lanChange.value as string) == "zh-cn" | |||
| ? "确定退出登录吗?" | |||
| : "Are you sure to log out?"; | |||
| const notice = (lanChange.value as string) == "zh-cn" ? "提示" : "Notice"; | |||
| const confirm = (lanChange.value as string) == "zh-cn" ? "确定" : "Confirm"; | |||
| const cancel = (lanChange.value as string) == "zh-cn" ? "取消" : "Cancel"; | |||
| ElMessageBox.confirm(msg, notice, { | |||
| confirmButtonText: confirm, | |||
| cancelButtonText: cancel, | |||
| }).then(() => { | |||
| userInfoPinia.loginOut(); | |||
| router.push(`/login`); | |||
| localStorage.removeItem("AccessToken"); | |||
| }); | |||
| } | |||
| /** | |||
| * 响应式布局容器固定宽度 | |||
| * | |||
| @@ -51,18 +149,7 @@ const { width } = useWindowSize(); | |||
| const WIDTH = 992; | |||
| const appStore = useAppStore(); | |||
| const settingsStore = useSettingsStore(); | |||
| const fixedHeader = computed(() => settingsStore.fixedHeader); | |||
| const showTagsView = computed(() => settingsStore.tagsView); | |||
| const showSettings = computed(() => settingsStore.showSettings); | |||
| const classObj = computed(() => ({ | |||
| hideSidebar: !appStore.sidebar.opened, | |||
| openSidebar: appStore.sidebar.opened, | |||
| withoutAnimation: appStore.sidebar.withoutAnimation, | |||
| mobile: appStore.device === "mobile", | |||
| })); | |||
| // const settingsStore = useSettingsStore(); | |||
| watchEffect(() => { | |||
| if (width.value < WIDTH) { | |||
| @@ -79,6 +166,13 @@ watchEffect(() => { | |||
| } | |||
| } | |||
| }); | |||
| const routeName = ref(route.meta.name); | |||
| watch( | |||
| () => route.meta.name, | |||
| (newName) => { | |||
| routeName.value = newName; | |||
| } | |||
| ); | |||
| function handleOutsideClick() { | |||
| appStore.closeSideBar(false); | |||
| @@ -87,47 +181,112 @@ function handleOutsideClick() { | |||
| onMounted(() => {}); | |||
| </script> | |||
| <!-- 新样式 --> | |||
| <style lang="scss" scoped> | |||
| .app-wrapper { | |||
| &::after { | |||
| display: table; | |||
| clear: both; | |||
| content: ""; | |||
| width: 1920px; | |||
| display: flex; | |||
| } | |||
| .Sidebar { | |||
| width: 230px; | |||
| background-color: #000; | |||
| height: 100vh; | |||
| color: #fff; | |||
| .imgBox { | |||
| width: 100%; | |||
| height: 80px; | |||
| position: relative; | |||
| img { | |||
| max-width: 80%; | |||
| max-height: 80%; | |||
| } | |||
| } | |||
| .myRouter { | |||
| position: relative; | |||
| height: calc(100% - 80px); | |||
| padding: 200px 20px 0; | |||
| color: #fff; | |||
| // color: #868593; | |||
| position: relative; | |||
| width: 100%; | |||
| height: 100%; | |||
| e &.mobile.openSidebar { | |||
| position: fixed; | |||
| top: 0; | |||
| } | |||
| } | |||
| &-item { | |||
| display: flex; | |||
| width: 100%; | |||
| height: 50px; | |||
| padding-left: 10px; | |||
| font-size: 20px; | |||
| font-weight: 500; | |||
| line-height: 50px; | |||
| text-align: center; | |||
| cursor: pointer; | |||
| // border-bottom: 2px solid #fff; | |||
| transition: all 0.3s; | |||
| border-radius: 5px; | |||
| margin-bottom: 20px; | |||
| margin-right: 20px; | |||
| border-bottom: 2px solid #fff; | |||
| .icon { | |||
| width: 40px; | |||
| height: 40px; | |||
| color: #fff; | |||
| border-radius: 50%; | |||
| .fixed-header { | |||
| position: fixed; | |||
| top: 0; | |||
| right: 0; | |||
| z-index: 9; | |||
| width: calc(100% - #{$sideBarWidth}); | |||
| transition: width 0.28s; | |||
| } | |||
| .el-icon { | |||
| width: 25px; | |||
| height: 25px; | |||
| font-size: 25px; | |||
| // color: #797a9f; | |||
| color: #fff; | |||
| text-align: center; | |||
| vertical-align: sub; | |||
| } | |||
| } | |||
| .hideSidebar .fixed-header { | |||
| width: calc(100% - 54px); | |||
| } | |||
| &:hover { | |||
| // background: rgba(255, 255, 255, 0.2); | |||
| color: #000; | |||
| background: #fff; | |||
| .el-icon { | |||
| // color: #d4d0ff; | |||
| color: #000; | |||
| } | |||
| } | |||
| } | |||
| .mobile .fixed-header { | |||
| width: 100%; | |||
| .pricing { | |||
| position: absolute; | |||
| bottom: 80px; | |||
| width: calc(100% - 40px); | |||
| text-align: center; | |||
| } | |||
| .API { | |||
| position: absolute; | |||
| bottom: 20px; | |||
| width: calc(100% - 40px); | |||
| text-align: center; | |||
| } | |||
| } | |||
| } | |||
| .drawer-bg { | |||
| position: absolute; | |||
| top: 0; | |||
| z-index: 999; | |||
| width: 100%; | |||
| height: 100%; | |||
| background: #000; | |||
| opacity: 0.3; | |||
| .rightBox { | |||
| width: 1690px; | |||
| // background-color: #000; | |||
| .nav { | |||
| position: relative; | |||
| display: flex; | |||
| justify-content: flex-end; | |||
| align-items: center; | |||
| margin-right: 20px; | |||
| width: 100%; | |||
| height: 80px; | |||
| background-color: #000; | |||
| padding: 30px; | |||
| // padding: 30px 30px 0 1500px; | |||
| color: #fff; | |||
| .navItem { | |||
| font-size: 16px; | |||
| margin-right: 30px; | |||
| color: #fff; | |||
| cursor: pointer; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @@ -123,6 +123,25 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
| }, | |||
| ], | |||
| }, | |||
| // 测试页面 | |||
| { | |||
| path: "/", | |||
| component: Layout, | |||
| redirect: "/moveImg", | |||
| children: [ | |||
| { | |||
| path: "moveImg", | |||
| component: () => import("@/views/moveImg/index.vue"), | |||
| name: "moveImg", | |||
| meta: { | |||
| title: "moveImg", | |||
| icon: "homepage", | |||
| affix: true, | |||
| name: "moveImg.title", | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| // { | |||
| // path: "/dashboard", | |||
| // component: Layout, | |||
| @@ -3,6 +3,13 @@ body { | |||
| // font-size: 14px; | |||
| } | |||
| .boxCentreImg { | |||
| position: absolute; | |||
| top: 50%; | |||
| left: 50%; | |||
| transform: translate(-50%, -50%); | |||
| } | |||
| .inmiddle { | |||
| position: absolute; | |||
| // top: 50%; | |||
| @@ -1,7 +1,7 @@ | |||
| <template> | |||
| <div class="page flex justify-around"> | |||
| <!-- 左侧栏 --> | |||
| <div class="left scrolly"> | |||
| <div class="left "> | |||
| <!-- 顶部 --> | |||
| <!-- 选中AiFace --> | |||
| <div class="left-top" v-show="showUploadBtn == 1"> | |||
| @@ -24,6 +24,11 @@ | |||
| <div class="bigImg inmiddle"> | |||
| <img :src="imgUrl" alt="" class="inmiddle" /> | |||
| </div> | |||
| <!-- 字幕开关 --> | |||
| <div v-if="imgUrl" class="SubtitlesSwitch"> | |||
| <p>{{ $t('createVideo.subtitles') }}</p> | |||
| <el-switch v-model="SubtitlesSwitch" /> | |||
| </div> | |||
| </div> | |||
| <!-- 选中需要上传的图片前 --> | |||
| <div class="left-top" v-show="showUploadBtn == 2"> | |||
| @@ -151,6 +156,7 @@ | |||
| v-if="showFace == 0" | |||
| v-infinite-scroll="loadMoreAiFaceSystem" | |||
| :infinite-scroll-disabled="overLoadSystem" | |||
| infinite-scroll-distance="10" | |||
| > | |||
| <!-- 上传图片组件 --> | |||
| <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | |||
| @@ -177,6 +183,7 @@ | |||
| v-if="showFace == 1" | |||
| v-infinite-scroll="loadMoreAiFaceUser" | |||
| :infinite-scroll-disabled="overLoadUser" | |||
| infinite-scroll-distance="10" | |||
| > | |||
| <!-- 上传图片组件 --> | |||
| <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | |||
| @@ -207,8 +214,7 @@ | |||
| <div | |||
| class="Aipicture" | |||
| v-if="showFace == 2" | |||
| v-infinite-scroll="loadMoreAiFaceUser" | |||
| :infinite-scroll-disabled="overLoadUser" | |||
| > | |||
| <div class="title"> | |||
| <el-icon><i-ep-Lock /></el-icon> | |||
| @@ -747,7 +753,7 @@ const AiFaceList = ref([]); //系统相册列表 | |||
| const userAiFaceList = ref([]); //个人相册列表 | |||
| const feceItemLoading = ref(false); | |||
| const feceItemLoading2 = ref(false); | |||
| const pageSize = ref(30); //加载页数 | |||
| function getAiFaceList(pageNum, pageSize, sendType) { | |||
| feceItemLoading.value = true; | |||
| personPhotoList(pageNum, pageSize, sendType) | |||
| @@ -779,7 +785,7 @@ const overLoadUser = ref(false); //禁用个人相册加载更多 | |||
| //系统相册触底加载更多 | |||
| function loadMoreAiFaceSystem() { | |||
| pageNumSystem.value += 1; | |||
| personPhotoList(pageNumSystem.value, 20, 1) | |||
| personPhotoList(pageNumSystem.value, pageSize.value, 1) | |||
| .then((res) => { | |||
| AiFaceList.value.push(...res.data.list); | |||
| if (res.data.list.length == 0) { | |||
| @@ -793,8 +799,9 @@ function loadMoreAiFaceSystem() { | |||
| } | |||
| //个人相册触底加载更多 | |||
| function loadMoreAiFaceUser() { | |||
| console.log(12333212311); | |||
| pageNumUser.value += 1; | |||
| personPhotoUserListList(pageNumUser.value, 20, 3) | |||
| personPhotoUserListList(pageNumUser.value, pageSize.value, 3) | |||
| .then((res) => { | |||
| if (res.data.list.length == 0) { | |||
| overLoadUser.value = true; | |||
| @@ -837,7 +844,7 @@ async function deleteFaceImg(id) { | |||
| imgUrl.value = null; | |||
| faceItemActive.value = null; | |||
| userAiFaceList.value = []; | |||
| getAiFaceUserList(1, 10, 3); | |||
| getAiFaceUserList(1, pageSize.value, 3); | |||
| pageNumUser.value = 1; | |||
| overLoadUser.value = false; | |||
| } catch (error) { | |||
| @@ -953,7 +960,7 @@ async function changeFile() { | |||
| compressionImgLoad.value = false; | |||
| showUploadBtn.value = 4; | |||
| userAiFaceList.value = []; | |||
| getAiFaceUserList(1, 10, 3); | |||
| getAiFaceUserList(1, pageSize.value, 3); | |||
| pageNumUser.value = 1; | |||
| overLoadUser.value = false; | |||
| faceItemActive.value = res2.data.id; | |||
| @@ -1903,6 +1910,10 @@ function copyAnswerContent() { | |||
| } | |||
| //#endregion ---------------------------- | |||
| //#region 字幕部分 | |||
| const SubtitlesSwitch=ref(false) //字幕开关 | |||
| //#endregion ---------------------------- | |||
| //#region | |||
| //#endregion ---------------------------- | |||
| @@ -1920,9 +1931,9 @@ const t = globalProperties.$t(string); | |||
| //#region 页面初始化 | |||
| onMounted(async () => { | |||
| getAiFaceList(1, 20, 1); | |||
| getAiFaceList(1, pageSize.value, 1); | |||
| if (AccessToken) { | |||
| getAiFaceUserList(1, 20, 3); | |||
| getAiFaceUserList(1, pageSize.value, 3); | |||
| await getmusicListPerson( | |||
| musicListPageNumPerson.value, | |||
| musicListPageSize.value | |||
| @@ -1963,7 +1974,6 @@ onUnmounted(() => { | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| // height: 1000px; | |||
| height: 1000px; | |||
| height: calc(100vh - 80px); | |||
| // padding: 20px 0 0 40px; | |||
| background-color: #fff; | |||
| @@ -1971,13 +1981,15 @@ onUnmounted(() => { | |||
| } | |||
| .left { | |||
| width: 68%; | |||
| // height: 860px; | |||
| height: 1000px; | |||
| max-height: 100%; | |||
| // height: 1000px; | |||
| // max-height: 100%; | |||
| padding: 20px; | |||
| overflow: hidden; | |||
| overflow-y: scroll; | |||
| // overflow-y: scroll; | |||
| height: 100%; | |||
| :deep(.el-input__wrapper) { | |||
| border: none; | |||
| border-bottom: 2px solid #000; | |||
| @@ -1985,6 +1997,7 @@ onUnmounted(() => { | |||
| box-shadow: none; | |||
| } | |||
| .el-icon.icon-edit { | |||
| width: 35px; | |||
| height: 35px; | |||
| @@ -1998,8 +2011,10 @@ onUnmounted(() => { | |||
| width: 100%; | |||
| // height: 65%; | |||
| // height: 580px; | |||
| height: 65%; | |||
| height: 67%; | |||
| // height: calc(70vh - 80px ); | |||
| z-index: 9999; | |||
| margin-bottom: 10px; | |||
| .uploadBtn { | |||
| position: relative; | |||
| padding: 10px 15px; | |||
| @@ -2205,12 +2220,22 @@ onUnmounted(() => { | |||
| } | |||
| } | |||
| } | |||
| .SubtitlesSwitch { | |||
| position: absolute; | |||
| right: 0; | |||
| top: 0px; | |||
| padding: 10px; | |||
| border-radius: 20px; | |||
| background-color: #f1f2f6; | |||
| text-align: center; | |||
| } | |||
| } | |||
| &-bottom { | |||
| width: 100%; | |||
| height: 32%; | |||
| margin-top: 10px; | |||
| height: 30%; | |||
| // height: calc(30vh - 80px ); | |||
| // margin-top: 10px; | |||
| .tab { | |||
| padding: 10px; | |||
| > div { | |||
| @@ -2238,16 +2263,17 @@ onUnmounted(() => { | |||
| flex-wrap: wrap; | |||
| justify-content: flex-start; | |||
| width: 100%; | |||
| height: 220px; | |||
| // height: 220px; | |||
| height: 90%; | |||
| overflow-y: scroll; | |||
| .faceItem { | |||
| position: relative; | |||
| margin-right: 30px; | |||
| margin-bottom: 35px; | |||
| width: 150px; | |||
| height: 150px; | |||
| width: 100px; | |||
| height: 100px; | |||
| // padding: 0 25px; | |||
| line-height: 150px; | |||
| line-height: 100px; | |||
| text-align: center; | |||
| border-radius: 50%; | |||
| background-color: #fbf8f8; | |||
| @@ -2263,8 +2289,8 @@ onUnmounted(() => { | |||
| right: 0; | |||
| bottom: 0; | |||
| z-index: 3; | |||
| width: 150px; | |||
| height: 150px; | |||
| width: 100px; | |||
| height: 100px; | |||
| border-radius: 50%; | |||
| background-color: #fbf8f8; | |||
| overflow: hidden; | |||
| @@ -2279,7 +2305,7 @@ onUnmounted(() => { | |||
| .deleteIcon { | |||
| position: absolute; | |||
| top: 0; | |||
| right: 15px; | |||
| right: -5px; | |||
| z-index: 999; | |||
| width: 25px; | |||
| height: 25px; | |||
| @@ -2291,7 +2317,7 @@ onUnmounted(() => { | |||
| cursor: pointer; | |||
| } | |||
| .uploadImg { | |||
| line-height: 145px; | |||
| line-height: 100px; | |||
| font-size: 50px; | |||
| font-weight: 700; | |||
| text-align: center; | |||
| @@ -2413,8 +2439,8 @@ onUnmounted(() => { | |||
| .right { | |||
| width: 32%; | |||
| // height: 860px; | |||
| height: 1000px; | |||
| max-height: 100%; | |||
| // height: 1000px; | |||
| // max-height: 100%; | |||
| padding: 30px 30px 20px 30px; | |||
| background-color: #f1f2f6; | |||
| border-radius: 30px 0 0 0; | |||
| @@ -2422,6 +2448,7 @@ onUnmounted(() => { | |||
| z-index: 2; | |||
| overflow: hidden; | |||
| overflow-y: scroll; | |||
| height: 100%; | |||
| .subscript { | |||
| position: absolute; | |||
| top: 30px; | |||
| @@ -0,0 +1,131 @@ | |||
| <template> | |||
| <div class="page"> | |||
| <div class="canvasBox"> | |||
| <canvas class="canvas" id="canvas" width="960" height="540"> | |||
| <!-- 背景图 --> | |||
| <!-- <div class="bjImg"> | |||
| <img src="../../assets/img/lake.jpg" alt="" /> | |||
| </div> --> | |||
| <!-- 数字人 --> | |||
| <!-- <div class="people"></div> --> | |||
| <!-- 素材 --> | |||
| <!-- <div class="other"></div> --> | |||
| </canvas> | |||
| <img | |||
| style="display: none; width: 200px; height: 200px" | |||
| id="bjImg" | |||
| src="../../assets/img/star.png" | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div class="container"> | |||
| <div class="box red"></div> | |||
| <div class="box white"></div> | |||
| <div class="box green"></div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script setup> | |||
| //#region 导入 | |||
| import { fabric } from "fabric"; | |||
| //#endregion --------------------------- | |||
| //#region 画布交互 | |||
| let canvas = new fabric.Canvas("canvas"); | |||
| //#endregion --------------------------- | |||
| onMounted(() => { | |||
| let canvas = new fabric.Canvas("canvas"); | |||
| let imgElement = document.getElementById("bjImg"); //声明我们的图片 | |||
| let imgInstance = new fabric.Image(imgElement, { | |||
| //设置图片位置和样子 | |||
| // left: 100, | |||
| // top: 100, | |||
| // width: 400, | |||
| // height: 200, | |||
| // angle: 30, //设置图形顺时针旋转角度 | |||
| }); | |||
| console.log(imgInstance); | |||
| canvas.add(imgInstance); | |||
| // canvas.on("mouse:up", function (options) { | |||
| // console.log(options.e.clientX, options.e.clientY); | |||
| // }); | |||
| }); | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| position: relative; | |||
| padding: 10px; | |||
| } | |||
| .canvasBox { | |||
| // position: absolute; | |||
| // top: 50%; | |||
| // left: 50%; | |||
| // transform: translate(-50%); | |||
| width: 100%; | |||
| height: 100%; | |||
| .canvas-container { | |||
| } | |||
| background-color: green; | |||
| .canvas { | |||
| background-color: skyblue; | |||
| .bjImg { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100px; | |||
| height: 100px; | |||
| z-index: 999; | |||
| img { | |||
| width: 100px; | |||
| height: 100px; | |||
| } | |||
| } | |||
| .people { | |||
| } | |||
| .other { | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| <style lang="scss" scoped> | |||
| .container { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| width: 80px; | |||
| height: 20px; | |||
| perspective: 500px; | |||
| transition: transform 0.5s; | |||
| } | |||
| .box { | |||
| width: 20px; | |||
| height: 20px; | |||
| transition: transform 0.5s; | |||
| transform-style: preserve-3d; | |||
| } | |||
| .red { | |||
| background-color: red; | |||
| } | |||
| .white { | |||
| background-color: white; | |||
| transform: translateZ(20px); | |||
| } | |||
| .green { | |||
| background-color: green; | |||
| transform: translateZ(-20px); | |||
| } | |||
| .container:hover .box { | |||
| transform: rotateY(180deg); | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,16 @@ | |||
| /** | |||
| * @description:根据状态返回状态名 | |||
| * @param {number} status | |||
| * @return: statusName | |||
| */ | |||
| export const getStatus = status => { | |||
| if (status == 0) { | |||
| return "manuscript" | |||
| } else if (status == 1 || status == 2 || status == 4 || status == 6) { | |||
| return "generating" | |||
| } else if (status == 3) { | |||
| return "generationFailed" | |||
| } else if (status == 5) { | |||
| return "generationSucceed" | |||
| } | |||
| } | |||