画布工具添加滚动条功能

This commit is contained in:
李志鹏
2025-09-24 11:53:25 +08:00
parent 05e9bada5a
commit 0f7e0f2e96
3 changed files with 52 additions and 10 deletions

8
components.d.ts vendored
View File

@@ -9,32 +9,26 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
ABadge: typeof import('ant-design-vue/es')['Badge'] ABadge: typeof import('ant-design-vue/es')['Badge']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox'] ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider'] AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADrawer: typeof import('ant-design-vue/es')['Drawer'] ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AImage: typeof import('ant-design-vue/es')['Image'] AImage: typeof import('ant-design-vue/es')['Image']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber'] AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal'] AModal: typeof import('ant-design-vue/es')['Modal']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopover: typeof import('ant-design-vue/es')['Popover'] APopover: typeof import('ant-design-vue/es')['Popover']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker'] ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select'] ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASlider: typeof import('ant-design-vue/es')['Slider'] ASlider: typeof import('ant-design-vue/es')['Slider']
ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ASwitch: typeof import('ant-design-vue/es')['Switch'] ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table'] ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane'] ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs'] ATabs: typeof import('ant-design-vue/es')['Tabs']
ATimeRangePicker: typeof import('ant-design-vue/es')['TimeRangePicker']
AUpload: typeof import('ant-design-vue/es')['Upload'] AUpload: typeof import('ant-design-vue/es')['Upload']
ElCascader: typeof import('element-plus/es')['ElCascader']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
} }

View File

@@ -173,7 +173,8 @@ const normalToolsList = ref([
icon: { name: "CHelp", size: "30" }, icon: { name: "CHelp", size: "30" },
class: "text-btn", class: "text-btn",
style: { style: {
'margin-top': 'auto', 'position': 'absolute',
'bottom': '0',
}, },
}, },
]); ]);
@@ -369,6 +370,7 @@ const handleToolClick = (tool) => {
:can-undo="canUndo" :can-undo="canUndo"
:can-redo="canRedo" :can-redo="canRedo"
@click="handleToolClick" @click="handleToolClick"
tip-body
/> />
<!-- 自定义工具栏按钮插槽 --> <!-- 自定义工具栏按钮插槽 -->
@@ -389,6 +391,7 @@ const handleToolClick = (tool) => {
min-width: 5.8rem; min-width: 5.8rem;
height: 100%; height: 100%;
padding-top: .5rem; padding-top: .5rem;
padding-bottom: 4rem;
/* overflow-y: auto; */ /* overflow-y: auto; */
/* overflow-x: hidden; */ /* overflow-x: hidden; */
} }
@@ -397,6 +400,8 @@ const handleToolClick = (tool) => {
flex-direction: column; flex-direction: column;
gap: 1.0rem; gap: 1.0rem;
flex: 1; flex: 1;
overflow-y: auto;
overflow-x: hidden;
} }
.red-green-mode { .red-green-mode {
background-color: #fff4f4; background-color: #fff4f4;

View File

@@ -21,6 +21,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
tipBody: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(["click"]); const emit = defineEmits(["click"]);
@@ -47,10 +51,45 @@ const handleClick = () => {
if (isDisabled.value) return; if (isDisabled.value) return;
emit("click", props.tool); emit("click", props.tool);
}; };
const tipId = "tooltip-" + Math.random().toString(36).substring(2);
const el = ref(null);
// 鼠标移入获取位置信息
const handleMouseEnter = (e) => {
const tooltip = el.value;
const rect = tooltip.getBoundingClientRect();
const left = rect.left + rect.width;
const top = rect.top + rect.height / 2;
const tip = document.getElementById(tipId);
tip.style.position = 'fixed';
tip.style.left = `${left}px`;
tip.style.top = `${top}px`;
tip.style.display = 'block';
}
// 鼠标移出隐藏提示
const handleMouseLeave = () => {
const tip = document.getElementById(tipId);
tip.style.display = 'none';
}
onMounted(() => {
if(props.tipBody){
el.value.addEventListener('mouseenter', handleMouseEnter);
el.value.addEventListener('mouseleave', handleMouseLeave);
}
})
onUnmounted(() => {
if(props.tipBody){
el.value.removeEventListener('mouseenter', handleMouseEnter);
el.value.removeEventListener('mouseleave', handleMouseLeave);
}
})
</script> </script>
<template> <template>
<div <div
ref="el"
:class="[ :class="[
'tool-btn', 'tool-btn',
tool.class, tool.class,
@@ -63,7 +102,10 @@ const handleClick = () => {
@click="handleClick" @click="handleClick"
> >
<SvgIcon :name="tool.icon.name" :size="tool.icon.size"></SvgIcon> <SvgIcon :name="tool.icon.name" :size="tool.icon.size"></SvgIcon>
<div class="tool-tooltip">{{ t(tool.title) }}</div> <teleport to="body" v-if="tipBody">
<div class="tool-tooltip" :id="tipId">{{ t(tool.title) }}</div>
</teleport>
<div class="tool-tooltip" v-else>{{ t(tool.title) }}</div>
</div> </div>
</template> </template>
@@ -82,6 +124,7 @@ const handleClick = () => {
font-size: 1.6rem; font-size: 1.6rem;
color: #333; color: #333;
transition: all 0.2s ease; transition: all 0.2s ease;
flex-shrink: 0;
} }
.tool-btn:hover { .tool-btn:hover {
@@ -115,7 +158,7 @@ const handleClick = () => {
margin-left: .8rem; margin-left: .8rem;
white-space: nowrap; white-space: nowrap;
font-size: 1.2rem; font-size: 1.2rem;
z-index: 10; z-index: 9999;
} }
.tool-tooltip:before { .tool-tooltip:before {