单独的插件广告窗口

This commit is contained in:
xu_yanfeng 2025-01-23 14:12:07 +08:00
parent 81ee5063f2
commit 88cdcf1a8e
4 changed files with 60 additions and 188 deletions

View File

@ -91,6 +91,10 @@ export enum GA_EventName {
* 广 * 广
*/ */
ShowAd = "show_ad", ShowAd = "show_ad",
/**
* 使inspector检查游戏节点
*/
DoInspector = "do_inspector",
} }
export enum GA_Button { export enum GA_Button {
Github = "github", Github = "github",

View File

@ -1,36 +1,24 @@
<template> <template>
<div v-show="ads.length && isShow" class="ad"> <div v-show="ads.length" class="ad">
<div class="header">
<div class="title">Recommend</div>
<div class="line"></div>
<div class="close" @click="onClose" :title="closeTitle">
<div class="icon">x</div>
</div>
</div>
<div class="body" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave"> <div class="body" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
<div class="left slide" @click="onClickBtnLeft"> <div class="list ccui-scrollbar">
<div class="arrow">&lt;</div>
</div>
<div class="list" ref="elAd" @wheel="onWheel">
<Banner v-for="(item, index) in ads" :data="item" :key="index"></Banner> <Banner v-for="(item, index) in ads" :data="item" :key="index"></Banner>
</div> </div>
<div class="right slide" @click="onClickBtnRight">
<div class="arrow">&gt;</div>
</div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import ccui from "@xuyanfeng/cc-ui"; import ccui from "@xuyanfeng/cc-ui";
import { defineComponent, onMounted, onUnmounted, ref, toRaw } from "vue"; import { defineComponent, onMounted, onUnmounted, ref, toRaw } from "vue";
import { AdItem, getAdData } from "./loader";
import { emitter, Msg } from "./const";
import { ga } from "./util";
import { GA_EventName } from "../../ga/type"; import { GA_EventName } from "../../ga/type";
import Banner from "./banner.vue";
import { emitter, Msg } from "./const";
import { AdItem, getAdData } from "./loader";
import { ga } from "./util";
const { CCButton } = ccui.components; const { CCButton } = ccui.components;
export default defineComponent({ export default defineComponent({
name: "ad", name: "ad",
components: { CCButton }, components: { CCButton, Banner },
setup(props, { emit }) { setup(props, { emit }) {
onMounted(async () => { onMounted(async () => {
const data = await getAdData(); const data = await getAdData();
@ -48,191 +36,44 @@ export default defineComponent({
} }
ads.value = data.data; ads.value = data.data;
console.log("get ads ", toRaw(ads.value)); console.log("get ads ", toRaw(ads.value));
closeTitle.value = `display again in ${data.showDuration} minute`;
visibleAd(data.showDuration); ga(GA_EventName.ShowAd);
adScroll(data.scrollDuration);
});
onUnmounted(() => {
clearInterval(timer);
}); });
onUnmounted(() => {});
function testBanner() { function testBanner() {
const data = new AdItem(); const data = new AdItem();
data.name = "ad test 11111111111 11111111111 44444444444444 5555555555555 111111111111111111 2222222222222222 33333333333333 444444444444444"; data.name = "ad test 11111111111 11111111111 44444444444444 5555555555555 111111111111111111 2222222222222222 33333333333333 444444444444444";
data.store = "http://www.baidu.com"; data.store = "http://www.baidu.com";
emitter.emit(Msg.ChangeAd, data); emitter.emit(Msg.ChangeAd, data);
} }
let timer = null;
const key = "close-time";
function adScroll(scrollDuration: number) {
timer = setInterval(() => {
// return;
if (stopAutoScroll) {
return;
}
if (elAd.value) {
const el = elAd.value as HTMLElement;
let left = el.scrollLeft + adWidth;
if (el.scrollLeft + el.clientWidth >= el.scrollWidth) {
left = 0;
}
el.scrollTo({ left, behavior: "smooth" });
}
}, scrollDuration * 1000);
}
function visibleAd(showDuration: number) {
const time = Number(localStorage.getItem(key) || "0");
if (time) {
//
const diff = (Date.now() - time) / 1000 / 60;
isShow.value = diff >= showDuration;
if (isShow.value && ads.value.length) {
ga(GA_EventName.ShowAd);
}
}
}
const closeTitle = ref("");
let ads = ref<AdItem[]>([]); let ads = ref<AdItem[]>([]);
const elAd = ref<HTMLElement>(null);
const adWidth = 300;
const isShow = ref(true);
let stopAutoScroll = false;
return { return {
isShow,
elAd,
ads, ads,
closeTitle, onMouseEnter() {},
onClose() { onMouseLeave() {},
isShow.value = false;
localStorage.setItem(key, Date.now().toString());
ga(GA_EventName.CloseAd);
},
onWheel(event: WheelEvent) {
if (!elAd.value) {
return;
}
event.preventDefault();
const div = elAd.value as HTMLElement;
if (event.deltaY > 0) {
div.scrollTo({ left: div.scrollLeft + adWidth, behavior: "smooth" });
} else {
div.scrollTo({ left: div.scrollLeft - adWidth, behavior: "smooth" });
}
},
async onClickBtnLeft() {
if (elAd.value) {
const el = elAd.value as HTMLElement;
el.scrollTo({ left: el.scrollLeft - adWidth, behavior: "smooth" });
}
},
async onClickBtnRight() {
if (elAd.value) {
const el = elAd.value as HTMLElement;
el.scrollTo({ left: el.scrollLeft + adWidth, behavior: "smooth" });
}
},
onMouseEnter() {
stopAutoScroll = true;
},
onMouseLeave() {
stopAutoScroll = false;
},
}; };
}, },
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@color-bg: #8d8d8da6;
@color-hover: #f9c04e;
@color-active: #ffaa00;
.ad { .ad {
display: flex; display: flex;
.header { flex-direction: column;
display: flex;
align-items: flex-end;
.title {
box-shadow: 0px 0px 2px 0px;
font-size: 12px;
user-select: none;
background-color: white;
// border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding: 3px 9px;
}
.line {
height: 1px;
flex: 1;
box-shadow: 0px 0px 2px 0px;
}
.close {
box-shadow: 0px 0px 3px 0px;
background-color: white;
border-top-left-radius: 10px;
cursor: pointer;
color: rgb(138, 138, 138);
width: 20px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
.icon {
user-select: none;
font-size: 14px;
&:hover {
color: black;
}
&:active {
color: #ffaa00;
}
}
}
}
.body { .body {
display: flex; display: flex;
position: relative; overflow: hidden;
.list { .list {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: row; flex-direction: column;
overflow: hidden;
}
.left {
left: 0;
background-image: linear-gradient(to left, rgba(0, 0, 0, 0), @color-bg);
&:hover {
background-image: linear-gradient(to left, rgba(0, 0, 0, 0), @color-hover);
}
&:active {
background-image: linear-gradient(to left, rgba(0, 0, 0, 0), @color-active);
}
}
.right {
right: 0px;
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), @color-bg);
&:hover {
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), @color-hover);
}
&:active {
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), @color-active);
}
}
.slide {
display: flex;
height: 100%;
width: 20px;
cursor: pointer;
flex-direction: row;
align-items: center; align-items: center;
position: absolute; overflow: auto;
justify-content: center;
.arrow {
user-select: none;
font-size: 22px;
font-weight: bold;
color: rgb(133, 133, 133);
}
} }
} }
} }

View File

@ -9,13 +9,18 @@
<i class="iconfont icon_cocos cocos" @mousedown="onMouseDown" @mouseenter="onMouseEnterCocosLogo"></i> <i class="iconfont icon_cocos cocos" @mousedown="onMouseDown" @mouseenter="onMouseEnterCocosLogo"></i>
</div> </div>
<!-- <Memory></Memory> --> <!-- <Memory></Memory> -->
<CCDialog></CCDialog>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import ccui from "@xuyanfeng/cc-ui";
import { defineComponent, onMounted, ref, toRaw } from "vue"; import { defineComponent, onMounted, ref, toRaw } from "vue";
import { GA_EventName } from "../../ga/type";
import Ad from "./ad.vue";
import Banner from "./banner.vue"; import Banner from "./banner.vue";
import Memory from "./memory.vue"; import Memory from "./memory.vue";
import { ga } from "./util";
const { CCDialog } = ccui.components;
interface ListItem { interface ListItem {
icon: string; icon: string;
txt: string; txt: string;
@ -23,20 +28,30 @@ interface ListItem {
} }
export default defineComponent({ export default defineComponent({
name: "ad", name: "ad",
components: { Banner, Memory }, components: { CCDialog, Banner, Memory },
setup() { setup() {
const keyAssistant = "assistant"; const keyAssistant = "assistant";
const listArray = ref<ListItem[]>([ const listArray = ref<ListItem[]>([
{ {
icon: "icon_shop_cart", icon: "icon_shop_cart ani_shop_cart",
txt: "Recommend Plugins", txt: "Recommended Plugins",
cb: () => {}, cb: () => {
ccui.dialog.showDialog({
title: "Recommended Plugins",
comp: Ad,
width: 310,
closeCB: () => {
ga(GA_EventName.CloseAd);
},
});
},
}, },
{ {
icon: "icon_target", icon: "icon_target",
txt: "Inspect Game", txt: "Inspect Game",
cb: () => { cb: () => {
ga(GA_EventName.DoInspector);
showBtns.value = false; showBtns.value = false;
picking.value = true; picking.value = true;
const cursor = document.body.style.cursor; const cursor = document.body.style.cursor;
@ -131,9 +146,17 @@ export default defineComponent({
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@color-bg: #8d8d8da6; @keyframes color-change {
@color-hover: #f9c04e; 0% {
@color-active: #ffaa00; color: #f00;
}
50% {
color: #0f0;
}
100% {
color: #f00;
}
}
.ad { .ad {
position: fixed; position: fixed;
z-index: 99999; z-index: 99999;
@ -177,6 +200,9 @@ export default defineComponent({
.icon { .icon {
font-size: 20px; font-size: 20px;
} }
.ani_shop_cart {
animation: color-change 2s infinite;
}
} }
} }
.cocos { .cocos {

View File

@ -80,8 +80,9 @@ export default defineComponent({
} }
.banner { .banner {
border: 2px solid #d2d2d2; border: 2px solid #d2d2d2;
border-bottom: 0;
background-color: #ffffff; background-color: #ffffff;
background-position: center center;
background-size: cover;
overflow: hidden; overflow: hidden;
min-width: 300px; min-width: 300px;
max-width: 300px; max-width: 300px;
@ -95,7 +96,7 @@ export default defineComponent({
&:hover { &:hover {
border: 2px solid #949494; border: 2px solid #949494;
border-bottom: 0;
background-color: #d1d1d1; background-color: #d1d1d1;
} }
.text { .text {