feat: 动态阴影显示

This commit is contained in:
马军
2026-05-12 15:37:35 +08:00
parent 48bf4aa989
commit 0870598fce
3 changed files with 106 additions and 58 deletions

View File

@@ -37,7 +37,13 @@
</n-tabs>
<!-- 编辑 -->
<n-tabs v-if="selectTarget" v-model:value="tabsSelect" class="tabs-box" size="small" type="segment">
<n-tabs
v-if="selectTarget"
v-model:value="tabsSelect"
class="tabs-box"
size="small"
type="segment"
>
<n-tab-pane
v-for="item in selectTarget.isGroup ? chartsDefaultTabList : chartsTabList"
:key="item.key"
@@ -62,104 +68,107 @@
</template>
<script setup lang="ts">
import { ref, toRefs, watch, computed } from 'vue'
import { icon } from '@/plugins'
import { loadAsyncComponent } from '@/utils'
import { ContentBox } from '../ContentBox/index'
import { TabsEnum } from './index.d'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { ref, toRefs, watch, computed } from "vue";
import { icon } from "@/plugins";
import { loadAsyncComponent } from "@/utils";
import { ContentBox } from "../ContentBox/index";
import { TabsEnum } from "./index.d";
import { useChartLayoutStore } from "@/store/modules/chartLayoutStore/chartLayoutStore";
import { ChartLayoutStoreEnum } from "@/store/modules/chartLayoutStore/chartLayoutStore.d";
import { useChartEditStore } from "@/store/modules/chartEditStore/chartEditStore";
const { getDetails } = toRefs(useChartLayoutStore())
const { setItem } = useChartLayoutStore()
const chartEditStore = useChartEditStore()
const { getDetails } = toRefs(useChartLayoutStore());
const { setItem } = useChartLayoutStore();
const chartEditStore = useChartEditStore();
const { ConstructIcon, FlashIcon, DesktopOutlineIcon, LeafIcon, RocketIcon } = icon.ionicons5
const { ConstructIcon, FlashIcon, DesktopOutlineIcon, LeafIcon, RocketIcon } = icon.ionicons5;
const ContentEdit = loadAsyncComponent(() => import('../ContentEdit/index.vue'))
const CanvasPage = loadAsyncComponent(() => import('./components/CanvasPage/index.vue'))
const ChartSetting = loadAsyncComponent(() => import('./components/ChartSetting/index.vue'))
const ChartData = loadAsyncComponent(() => import('./components/ChartData/index.vue'))
const ChartEvent = loadAsyncComponent(() => import('./components/ChartEvent/index.vue'))
const ChartAnimation = loadAsyncComponent(() => import('./components/ChartAnimation/index.vue'))
const ContentEdit = loadAsyncComponent(() => import("../ContentEdit/index.vue"));
const CanvasPage = loadAsyncComponent(() => import("./components/CanvasPage/index.vue"));
const ChartSetting = loadAsyncComponent(() => import("./components/ChartSetting/index.vue"));
const ChartData = loadAsyncComponent(() => import("./components/ChartData/index.vue"));
const ChartEvent = loadAsyncComponent(() => import("./components/ChartEvent/index.vue"));
const ChartAnimation = loadAsyncComponent(() => import("./components/ChartAnimation/index.vue"));
const collapsed = ref<boolean>(getDetails.value)
const tabsSelect = ref<TabsEnum>(TabsEnum.CHART_SETTING)
const collapsed = ref<boolean>(getDetails.value);
const tabsSelect = ref<TabsEnum>(TabsEnum.CHART_SETTING);
const collapsedHandle = () => {
collapsed.value = true
setItem(ChartLayoutStoreEnum.DETAILS, true)
}
collapsed.value = true;
setItem(ChartLayoutStoreEnum.DETAILS, true);
};
const expandHandle = () => {
collapsed.value = false
setItem(ChartLayoutStoreEnum.DETAILS, false)
}
collapsed.value = false;
setItem(ChartLayoutStoreEnum.DETAILS, false);
};
const selectTarget = computed(() => {
const selectId = chartEditStore.getTargetChart.selectId
const selectId = chartEditStore.getTargetChart.selectId;
// 排除多个
if (selectId.length !== 1) return undefined
const target = chartEditStore.componentList[chartEditStore.fetchTargetIndex()]
if (selectId.length !== 1) return undefined;
const target = chartEditStore.componentList[chartEditStore.fetchTargetIndex()];
if (target?.isGroup) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
tabsSelect.value = TabsEnum.CHART_SETTING
tabsSelect.value = TabsEnum.CHART_SETTING;
}
return target
})
return target;
});
watch(getDetails, newData => {
watch(getDetails, (newData) => {
if (newData) {
collapsedHandle()
collapsedHandle();
} else {
expandHandle()
expandHandle();
}
})
});
// 页面设置
const globalTabList = [
{
key: TabsEnum.PAGE_SETTING,
title: '页面配置',
title: "页面配置",
icon: DesktopOutlineIcon,
render: CanvasPage
}
]
render: CanvasPage,
},
];
const chartsDefaultTabList = [
{
key: TabsEnum.CHART_SETTING,
title: '定制',
title: "定制",
icon: ConstructIcon,
render: ChartSetting
render: ChartSetting,
},
{
key: TabsEnum.CHART_ANIMATION,
title: '动画',
title: "动画",
icon: LeafIcon,
render: ChartAnimation
}
]
render: ChartAnimation,
},
];
const chartsTabList = [
...chartsDefaultTabList,
{
key: TabsEnum.CHART_DATA,
title: '数据',
title: "数据",
icon: FlashIcon,
render: ChartData
render: ChartData,
},
{
key: TabsEnum.CHART_EVENT,
title: '事件',
title: "事件",
icon: RocketIcon,
render: ChartEvent
}
]
render: ChartEvent,
},
];
</script>
<style lang="scss" scoped>
::v-deep .n-layout-toggle-bar {
z-index: 9;
}
@include go(content-configurations) {
overflow: hidden;
.tabs-box {

View File

@@ -30,6 +30,7 @@ import type { CSSProperties } from 'vue'
import { listen } from 'dom-helpers'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { CreateComponentGroupType } from '@/packages/index.d'
import throttle from 'lodash/throttle'
const chartEditStore = useChartEditStore()
@@ -71,7 +72,7 @@ const paletteStyle = computed(() => {
longfgColor: '#4d4d4d',
shortfgColor: '#4d4d4d',
fontColor: '#4d4d4d',
shadowColor: '#18181c',
shadowColor: '#232324',
borderColor: '#18181c',
cornerActiveColor: '#18181c'
}
@@ -89,13 +90,50 @@ const canvasStyle = computed((): CSSProperties => {
height: `${height.value}px`
}
})
// 根据 id 查找组件(含分组内子组件)
const findComponentById = (id: string) => {
for (const item of chartEditStore.getComponentList) {
if (item.id === id) return item
if (item.isGroup) {
const child = (item as CreateComponentGroupType).groupList.find(c => c.id === id)
if (child) return child
}
}
return null
}
// 阴影(画布在标尺坐标系中的位置,从 thick 偏移开始)
const shadow = computed(() => {
const selectIds = chartEditStore.getTargetChart.selectId
if (!selectIds.length) {
return { x: 0, y: 0, width: 0, height: 0 }
}
let minX = Infinity
let minY = Infinity
let maxX = -Infinity
let maxY = -Infinity
for (const id of selectIds) {
const comp = findComponentById(id)
if (comp) {
const { x, y, w, h } = comp.attr
minX = Math.min(minX, x)
minY = Math.min(minY, y)
maxX = Math.max(maxX, x + w)
maxY = Math.max(maxY, y + h)
}
}
if (minX === Infinity) {
return { x: 0, y: 0, width: 0, height: 0 }
}
return {
x: 0,
y: 0,
width: 200,
height: 200
x: minX,
y: minY,
width: maxX - minX,
height: maxY - minY
}
})

View File

@@ -223,6 +223,7 @@ $asideBottom: 70px;
@include go('chart-edit-tools') {
@extend .go-background-filter;
z-index: 9;
position: absolute;
display: flex;
justify-content: space-around;