Merge branch 'main' of http://18.167.251.121:10003/aidlab/Code-Create
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>test-ssg</title>
|
<title>test-ssg</title>
|
||||||
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_4403230_bui5mtufs1c.css" />
|
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_4403230_2woxf8yp826.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
<RouterView />
|
<RouterView />
|
||||||
<MainFooter />
|
<MainFooter />
|
||||||
<BackTop />
|
<BackTop />
|
||||||
|
|
||||||
|
<VideoModel />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -10,6 +12,7 @@
|
|||||||
import MainHeader from "./components/main-header.vue";
|
import MainHeader from "./components/main-header.vue";
|
||||||
import MainFooter from "./components/main-footer.vue";
|
import MainFooter from "./components/main-footer.vue";
|
||||||
import BackTop from "./components/back-top.vue";
|
import BackTop from "./components/back-top.vue";
|
||||||
|
import VideoModel from "./components/video-model.vue";
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
// .main {
|
// .main {
|
||||||
|
|||||||
74
src/components/video-model.vue
Normal file
74
src/components/video-model.vue
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||||
|
import MyEvent from "@/directives/myEvents";
|
||||||
|
//const props = defineProps({
|
||||||
|
//})
|
||||||
|
//const emit = defineEmits([
|
||||||
|
//])
|
||||||
|
const isVideoShow = ref(true)
|
||||||
|
const url = ref('')
|
||||||
|
const poster = ref('')
|
||||||
|
const playVideo = (data)=>{
|
||||||
|
url.value = data.url || ''
|
||||||
|
poster.value = data.poster || ''
|
||||||
|
isVideoShow.value = true
|
||||||
|
}
|
||||||
|
const closeVideoModel = ()=>{
|
||||||
|
url.value = ''
|
||||||
|
poster.value = ''
|
||||||
|
isVideoShow.value = false
|
||||||
|
}
|
||||||
|
onMounted(()=>{
|
||||||
|
MyEvent.add("playVideo",playVideo);
|
||||||
|
})
|
||||||
|
onUnmounted(()=>{
|
||||||
|
})
|
||||||
|
defineExpose({})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="vide-model" v-if="isVideoShow">
|
||||||
|
<div class="mask"></div>
|
||||||
|
<video :src="url" autoplay controls preload="metadata" controlslist="nodownload" :poster="poster"></video>
|
||||||
|
<div class="close-btn">
|
||||||
|
<span class="iconfont icon-close" @click="closeVideoModel"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.vide-model{
|
||||||
|
z-index: 99999;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
> .mask{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
background-color: rgba(0,0,0,.8);
|
||||||
|
}
|
||||||
|
> video{
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
max-height: 80vh;
|
||||||
|
max-width: 80vw;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
}
|
||||||
|
> .close-btn{
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
font-size: 30px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
span{
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
39
src/directives/myEvents.ts
Normal file
39
src/directives/myEvents.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
class MyEvent {
|
||||||
|
private events: Map<string, Array<(data: any) => void>>;
|
||||||
|
constructor() {
|
||||||
|
// 使用 Object 或 Map 存储,实现 O(1) 级别的查找
|
||||||
|
this.events = new Map()
|
||||||
|
}
|
||||||
|
add(name: string, call: (data: any) => void) {
|
||||||
|
if (!this.events.has(name)) {
|
||||||
|
this.events.set(name, [])
|
||||||
|
}
|
||||||
|
this.events.get(name)!.push(call)
|
||||||
|
}
|
||||||
|
remove(name: string, call?: (data: any) => void) {
|
||||||
|
if (!this.events.has(name)) return
|
||||||
|
|
||||||
|
if (!call) {
|
||||||
|
this.events.delete(name)
|
||||||
|
} else {
|
||||||
|
const callbacks = this.events.get(name)
|
||||||
|
const index = callbacks.indexOf(call)
|
||||||
|
if (index !== -1) {
|
||||||
|
callbacks.splice(index, 1)
|
||||||
|
}
|
||||||
|
// 如果该事件没有监听者了,彻底清理 key
|
||||||
|
if (callbacks.length === 0) {
|
||||||
|
this.events.delete(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(name: string, data?: any) {
|
||||||
|
const callbacks = this.events.get(name)
|
||||||
|
if (callbacks) {
|
||||||
|
// 使用 slice() 镜像一份副本,防止在执行回调过程中有 remove 操作导致索引错乱
|
||||||
|
callbacks.slice().forEach((cb) => cb(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default new MyEvent()
|
||||||
@@ -1,5 +1,16 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
defineExpose({})
|
import { ref } from "vue";
|
||||||
|
import MyEvent from "@/directives/myEvents";
|
||||||
|
let videoUrl = 'https://code-create.com.hk/wp-content/uploads/2023/05/codec_brand_vid_16x9_ENG.mp4'
|
||||||
|
let videoPosterUrl = 'https://code-create.com.hk/wp-content/uploads/revslider/video-media/codec_brand_vid_16x9_ENG_11_layer.jpeg'
|
||||||
|
const playVideo = ()=>{
|
||||||
|
MyEvent.emit("playVideo",{
|
||||||
|
url: videoUrl,
|
||||||
|
poster: videoPosterUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<section class="ecosystem">
|
<section class="ecosystem">
|
||||||
@@ -11,6 +22,8 @@ defineExpose({})
|
|||||||
</section>
|
</section>
|
||||||
<section class="ecosystem-video">
|
<section class="ecosystem-video">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<img src="https://code-create.com.hk/wp-content/uploads/revslider/video-media/codec_brand_vid_16x9_ENG_11_layer.jpeg" alt="">
|
||||||
|
<span class="iconfont icon-bofang" @click="playVideo"></span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,6 +61,36 @@ defineExpose({})
|
|||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 100px 0;
|
padding: 100px 0;
|
||||||
|
position: relative;
|
||||||
|
> img{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
> .icon-bofang{
|
||||||
|
font-size: 100px;
|
||||||
|
color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
animation: identifier 2s ease-in-out infinite;
|
||||||
|
// box-shadow: 0 0 10px #fff;
|
||||||
|
transition: .3s all;
|
||||||
|
cursor: pointer;
|
||||||
|
@keyframes identifier {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%,-50%) scale(1);
|
||||||
|
filter: drop-shadow(0px 0px 8px rgba(255, 255, 255, 1));
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-50%,-50%) scale(.95);
|
||||||
|
filter: drop-shadow(0px 0px 0px rgba(255, 255, 255, 1));
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%,-50%) scale(1);
|
||||||
|
filter: drop-shadow(0px 0px 8px rgba(255, 255, 255, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'about-us',
|
path: 'about-us',
|
||||||
|
name: 'about-us',
|
||||||
component: AboutView
|
component: AboutView
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
{
|
{
|
||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/types/**/*.d.ts"],
|
||||||
{ "path": "./tsconfig.app.json" },
|
"compilerOptions": {
|
||||||
{ "path": "./tsconfig.node.json" }
|
"forceConsistentCasingInFileNames": false, // ⚠️ 禁用大小写检查
|
||||||
]
|
"allowJs": true,
|
||||||
}
|
"baseUrl": ".",
|
||||||
|
"types": ["node", "unplugin-vue-define-options/macros-global"],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"],
|
||||||
|
"_c/*": ["./src/components/*"]
|
||||||
|
},
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false,
|
||||||
|
"noEmit": true,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"noEmitOnError": false
|
||||||
|
},
|
||||||
|
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user