文本组件、弹幕文字、渐变文字、图片增加各种事件

main
刘妍 2025-03-03 10:53:17 +08:00
parent 6caaf21d3f
commit fc1442bfbf
5 changed files with 478 additions and 221 deletions

View File

@ -1,5 +1,12 @@
<template> <template>
<div :style="getStyle(borderRadius)"> <div
:style="getStyle(borderRadius)"
@click="clickBtn"
@dblclick="dblclickBtn"
@contextmenu="rightclickBtn"
@mouseenter="mouseenterBtn"
@mouseleave="mouseleaveBtn"
>
<n-image <n-image
:object-fit="fit" :object-fit="fit"
preview-disabled preview-disabled
@ -13,46 +20,100 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs } from 'vue' import { PropType, shallowReactive, watch, toRefs, onMounted } from 'vue';
import { requireErrorImg } from '@/utils' import { requireErrorImg } from '@/utils';
import { useChartDataFetch } from '@/hooks' import { useChartDataFetch } from '@/hooks';
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import { EventBus } from '@/utils/eventBus';
const props = defineProps({ const chartEditStore = useChartEditStore();
chartConfig: { const props = defineProps({
type: Object as PropType<CreateComponentType>, chartConfig: {
required: true type: Object as PropType<CreateComponentType>,
} required: true,
}) },
});
const { w, h } = toRefs(props.chartConfig.attr) const { w, h } = toRefs(props.chartConfig.attr);
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option) const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option);
const option = shallowReactive({ const option = shallowReactive({
dataset: '' dataset: '',
}) });
const getStyle = (radius: number) => { const getStyle = (radius: number) => {
return { return {
borderRadius: `${radius}px`, borderRadius: `${radius}px`,
overflow: 'hidden' overflow: 'hidden',
} cursor: 'pointer',
} };
};
// //
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
(newData: any) => { (newData: any) => {
option.dataset = newData option.dataset = newData;
}, },
{ {
immediate: true immediate: true,
} },
) );
// //
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData option.dataset = newData;
}) });
const clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
const dblclickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
};
const rightclickBtn = (event) => {
event.preventDefault(); //
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
};
const mouseenterBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
};
const mouseleaveBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
};
onMounted(() => {
// eventBus
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
console.log('data', data);
});
// websocket
EventBus.on(props.chartConfig.id + 'websocket', (data) => {
console.log('data', data);
});
});
</script> </script>

View File

@ -1,6 +1,13 @@
<template> <template>
<div class="go-text-box"> <div class="go-text-box">
<div class="content"> <div
class="content"
@click="clickBtn"
@dblclick="dblclickBtn"
@contextmenu="rightclickBtn"
@mouseenter="mouseenterBtn"
@mouseleave="mouseleaveBtn"
>
<span> <span>
{{ option.dataset }} {{ option.dataset }}
</span> </span>
@ -9,94 +16,156 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch, computed, ref } from 'vue' import { PropType, toRefs, shallowReactive, watch, computed, ref, onMounted } from 'vue';
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d';
import { useChartDataFetch } from '@/hooks' import { useChartDataFetch } from '@/hooks';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { option as configOption } from './config' import { option as configOption } from './config';
import { values } from 'lodash' import { values } from 'lodash';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import { EventBus } from '@/utils/eventBus';
const props = defineProps({ const chartEditStore = useChartEditStore();
chartConfig: { const props = defineProps({
type: Object as PropType<CreateComponentType & typeof option>, chartConfig: {
required: true type: Object as PropType<CreateComponentType & typeof option>,
} required: true,
}) },
});
const { w } = toRefs(props.chartConfig.attr) const { w } = toRefs(props.chartConfig.attr);
const { fontColor, fontSize, letterSpacing, fontWeight, animationTime, animationSpeed, boxShadow } = toRefs( const {
props.chartConfig.option fontColor,
) fontSize,
letterSpacing,
fontWeight,
animationTime,
animationSpeed,
boxShadow,
} = toRefs(props.chartConfig.option);
const option = shallowReactive({ const option = shallowReactive({
dataset: configOption.dataset dataset: configOption.dataset,
}) });
// //
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
(newData: any) => { (newData: any) => {
option.dataset = newData option.dataset = newData;
}, },
{ {
immediate: true, immediate: true,
deep: false deep: false,
} },
) );
// //
watch( watch(
props.chartConfig.option, props.chartConfig.option,
() => { () => {
try { try {
if (props.chartConfig.option.showShadow) { if (props.chartConfig.option.showShadow) {
boxShadow.value = `${props.chartConfig.option.hShadow}px ${props.chartConfig.option.vShadow}px ${props.chartConfig.option.blurShadow}px ${props.chartConfig.option.colorShadow}` boxShadow.value = `${props.chartConfig.option.hShadow}px ${props.chartConfig.option.vShadow}px ${props.chartConfig.option.blurShadow}px ${props.chartConfig.option.colorShadow}`;
} else { } else {
boxShadow.value = 'none' boxShadow.value = 'none';
}
} catch (error) {
console.log(error);
} }
} catch (error) { },
console.log(error) {
} immediate: true,
}, },
{ );
immediate: true
}
)
const transitionDuration = computed(() => { const transitionDuration = computed(() => {
return Math.floor((w.value as any) / (animationSpeed.value as any)) return Math.floor((w.value as any) / (animationSpeed.value as any));
}) });
// //
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => { useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
option.dataset = newData option.dataset = newData;
}) });
const clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
const dblclickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
};
const rightclickBtn = (event) => {
event.preventDefault(); //
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
};
const mouseenterBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
};
const mouseleaveBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
};
onMounted(() => {
// eventBus
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
console.log('data', data);
});
// websocket
EventBus.on(props.chartConfig.id + 'websocket', (data) => {
console.log('data', data);
});
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@include go('text-box') { @include go('text-box') {
display: flex; display: flex;
align-items: center; align-items: center;
.content { .content {
width: 100%; cursor: pointer;
color: v-bind('fontColor'); width: 100%;
font-size: v-bind('fontSize + "px"'); color: v-bind('fontColor');
letter-spacing: v-bind('letterSpacing + "px"'); font-size: v-bind('fontSize + "px"');
font-weight: v-bind('fontWeight'); letter-spacing: v-bind('letterSpacing + "px"');
text-shadow: v-bind('boxShadow'); font-weight: v-bind('fontWeight');
position: absolute; text-shadow: v-bind('boxShadow');
animation: barrage v-bind('transitionDuration + "s"') linear v-bind('animationTime + "s"') infinite; position: absolute;
} animation: barrage v-bind('transitionDuration + "s"') linear v-bind('animationTime + "s"')
@keyframes barrage { infinite;
from {
left: 100%;
transform: translateX(0);
} }
to { @keyframes barrage {
left: 0; from {
transform: translateX(-100%); left: 100%;
transform: translateX(0);
}
to {
left: 0;
transform: translateX(-100%);
}
} }
} }
}
</style> </style>

View File

@ -1,90 +1,155 @@
<template> <template>
<div class="go-text-box"> <div class="go-text-box">
<div class="content"> <div class="content">
<span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{ option.dataset }}</span> <span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{
<span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span> option.dataset
}}</span>
<span
style="white-space: pre-wrap; cursor: pointer"
v-else
@click="clickBtn"
@dblclick="dblclickBtn"
@contextmenu="rightclickBtn"
@mouseenter="mouseenterBtn"
@mouseleave="mouseleaveBtn"
>{{ option.dataset }}</span
>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch } from 'vue' import { PropType, toRefs, shallowReactive, watch, onMounted } from 'vue';
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d';
import { useChartDataFetch } from '@/hooks' import { useChartDataFetch } from '@/hooks';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { option as configOption } from './config' import { option as configOption } from './config';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import { EventBus } from '@/utils/eventBus';
const props = defineProps({ const chartEditStore = useChartEditStore();
chartConfig: { const props = defineProps({
type: Object as PropType<CreateComponentType & typeof option>, chartConfig: {
required: true type: Object as PropType<CreateComponentType & typeof option>,
} required: true,
}) },
});
const { const {
linkHead, linkHead,
link, link,
fontColor, fontColor,
fontSize, fontSize,
letterSpacing, letterSpacing,
paddingY, paddingY,
paddingX, paddingX,
textAlign, textAlign,
borderWidth, borderWidth,
borderColor, borderColor,
borderRadius, borderRadius,
writingMode, writingMode,
backgroundColor, backgroundColor,
fontWeight fontWeight,
} = toRefs(props.chartConfig.option) } = toRefs(props.chartConfig.option);
const option = shallowReactive({ const option = shallowReactive({
dataset: configOption.dataset dataset: configOption.dataset,
}) });
// //
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
(newData: any) => { (newData: any) => {
option.dataset = newData option.dataset = newData;
}, },
{ {
immediate: true, immediate: true,
deep: false deep: false,
} },
) );
// //
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => { useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
option.dataset = newData option.dataset = newData;
}) });
// //
const click = () => { const click = () => {
window.open(linkHead.value + link.value) window.open(linkHead.value + link.value);
} };
const clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
const dblclickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
};
const rightclickBtn = (event) => {
event.preventDefault(); //
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
};
const mouseenterBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
};
const mouseleaveBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
};
onMounted(() => {
// eventBus
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
console.log('data', data);
});
// websocket
EventBus.on(props.chartConfig.id + 'websocket', (data) => {
console.log('data', data);
});
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@include go('text-box') { @include go('text-box') {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: v-bind('textAlign'); justify-content: v-bind('textAlign');
overflow: hidden; overflow: hidden;
.content { .content {
color: v-bind('fontColor'); color: v-bind('fontColor');
padding: v-bind('`${paddingY}px ${paddingX}px`'); padding: v-bind('`${paddingY}px ${paddingX}px`');
font-size: v-bind('fontSize + "px"'); font-size: v-bind('fontSize + "px"');
letter-spacing: v-bind('letterSpacing + "px"'); letter-spacing: v-bind('letterSpacing + "px"');
writing-mode: v-bind('writingMode'); writing-mode: v-bind('writingMode');
font-weight: v-bind('fontWeight'); font-weight: v-bind('fontWeight');
border-style: solid; border-style: solid;
border-width: v-bind('borderWidth + "px"'); border-width: v-bind('borderWidth + "px"');
border-radius: v-bind('borderRadius + "px"'); border-radius: v-bind('borderRadius + "px"');
border-color: v-bind('borderColor'); border-color: v-bind('borderColor');
background-color: v-bind('backgroundColor'); background-color: v-bind('backgroundColor');
}
} }
}
</style> </style>

View File

@ -1,54 +1,116 @@
<template> <template>
<div class="go-text-box"> <div
class="go-text-box"
@click="clickBtn"
@dblclick="dblclickBtn"
@contextmenu="rightclickBtn"
@mouseenter="mouseenterBtn"
@mouseleave="mouseleaveBtn"
>
<n-gradient-text :size="size" :gradient="gradient"> <n-gradient-text :size="size" :gradient="gradient">
{{ option.dataset }} {{ option.dataset }}
</n-gradient-text> </n-gradient-text>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch } from 'vue' import { PropType, toRefs, shallowReactive, watch, onMounted } from 'vue';
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d';
import { useChartDataFetch } from '@/hooks' import { useChartDataFetch } from '@/hooks';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { option as configOption } from './config' import { option as configOption } from './config';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import { EventBus } from '@/utils/eventBus';
const props = defineProps({ const chartEditStore = useChartEditStore();
chartConfig: { const props = defineProps({
type: Object as PropType<CreateComponentType>, chartConfig: {
required: true type: Object as PropType<CreateComponentType>,
} required: true,
}) },
});
const option = shallowReactive({ const option = shallowReactive({
dataset: configOption.dataset dataset: configOption.dataset,
}) });
const { w, h } = toRefs(props.chartConfig.attr) const { w, h } = toRefs(props.chartConfig.attr);
const { size, gradient } = toRefs(props.chartConfig.option) const { size, gradient } = toRefs(props.chartConfig.option);
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
(newData: any) => { (newData: any) => {
option.dataset = newData option.dataset = newData;
}, },
{ {
immediate: true, immediate: true,
deep: false deep: false,
} },
) );
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData option.dataset = newData;
}) });
const clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
const dblclickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
};
const rightclickBtn = (event) => {
event.preventDefault(); //
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
};
const mouseenterBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
};
const mouseleaveBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
};
onMounted(() => {
// eventBus
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
console.log('data', data);
});
// websocket
EventBus.on(props.chartConfig.id + 'websocket', (data) => {
console.log('data', data);
});
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@include go('text-box') { @include go('text-box') {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.n-gradient-text { cursor: pointer;
white-space: initial; .n-gradient-text {
white-space: initial;
}
} }
}
</style> </style>

View File

@ -12,7 +12,7 @@
...getPreviewConfigStyle(item.preview), ...getPreviewConfigStyle(item.preview),
...(getBlendModeStyle(item.styles) as any), ...(getBlendModeStyle(item.styles) as any),
...getSizeStyle(item.attr), ...getSizeStyle(item.attr),
...setMouseEventClose(item.option) ...setMouseEventClose(item.option),
}" }"
> >
<!-- 分组 --> <!-- 分组 -->
@ -24,7 +24,7 @@
:themeColor="themeColor" :themeColor="themeColor"
/> />
<!-- 单组件 --> <!-- 单组件 preview-->
<component <component
v-else v-else
:is="item.chartConfig.chartKey" :is="item.chartConfig.chartKey"