feat: add background fill functionality for layers

- Implemented FillLayerBackgroundCommand to fill the background of layers with a specified color.
- Introduced BackgroundFillManager to manage background fill operations.
- Updated LayerManager to include fillLayerBackground method.
- Enhanced LayersPanel with a color picker for filling layer backgrounds.
- Modified RasterizeLayerCommand to reflect changes in terminology and functionality.
- Adjusted LayerSort to ensure filled layers are rendered at the correct z-index.
- Updated relevant utility functions and components to support new fill feature.
This commit is contained in:
bighuixiang
2025-07-14 23:42:28 +08:00
parent 24e9ba8ae5
commit fc9a3eddc2
12 changed files with 524 additions and 57 deletions

View File

@@ -69,6 +69,10 @@ const contextMenuPosition = ref({ x: 0, y: 0 });
const contextMenuLayer = ref(null);
const contextMenuItems = ref([]);
// 颜色填充相关
const fillColor = ref("#ffffff"); // 默认填充颜色
const fillColorRef = ref(null);
// 计算属性:可排序的根级图层(排除背景层和固定层)
const sortableRootLayers = computed(() => {
if (!layers) return [];
@@ -644,9 +648,33 @@ function buildContextMenuItems(layer) {
danger: true,
action: () => deleteSelectedLayers(),
},
// 栅格化图层
// 组合图层
{
label: "栅格化图层",
label: "填充图层",
icon: "CThemeColor",
disabled: layer.isBackground || layer.isFixed || !layerManager?.canRasterizeLayer?.(layer.id),
action: () => {
// 调用浏览器原生颜色选择器
fillColorRef.value.click();
// 监听颜色选择器的变化
fillColorRef.value.addEventListener("change", () => {
const selectedColor = fillColor.value;
layerManager
.fillLayerBackground(layer.id, selectedColor)
.then(() => {
console.log(`✅ 已填充图层 ${layer.name} 背景颜色: ${selectedColor}`);
})
.catch((error) => {
console.error(`❌ 填充图层 ${layer.name} 背景颜色失败:`, error);
});
});
// 隐藏右键菜单
hideContextMenu();
},
},
// 组合图层
{
label: "组合图层",
icon: "CPicture",
disabled: layer.isBackground || layer.isFixed || !layerManager?.canRasterizeLayer?.(layer.id),
action: () => {
@@ -654,7 +682,7 @@ function buildContextMenuItems(layer) {
hideContextMenu();
},
},
// 栅格化图层
// 导出图层
{
label: "导出图层",
icon: "CExport",
@@ -689,7 +717,7 @@ function buildContextMenuItems(layer) {
},
},
// {
// label: "合并组", // 不需要了 同栅格化功能一样了
// label: "合并组", // 不需要了 同组合功能一样了
// icon: "CMergeGroup",
// disabled: !isGroupLayer || isMultiple,
// action: () => {
@@ -1058,22 +1086,22 @@ async function handleChildLayersSort(event, childrenLayers, parentId) {
}
}
// 栅格化图层
// 组合图层
async function rasterizeLayer(layerId) {
if (!layerManager?.rasterizeLayer) {
console.warn("栅格化功能不可用");
console.warn("组合功能不可用");
return;
}
try {
const success = await layerManager.rasterizeLayer(layerId);
if (success) {
console.log(`✅ 成功栅格化图层: ${layerId}`);
console.log(`✅ 成功组合图层: ${layerId}`);
} else {
console.warn("栅格化图层失败");
console.warn("组合图层失败");
}
} catch (error) {
console.error("栅格化图层时发生错误:", error);
console.error("组合图层时发生错误:", error);
}
}
@@ -1591,6 +1619,9 @@ async function moveGroupToGroup(draggedLayer, fromParentId, toParentId, newIndex
:items="contextMenuItems"
@close="hideContextMenu"
/>
<!-- 颜色填充选择组件 -->
<input v-model="fillColor" ref="fillColorRef" type="color" style="display: none" />
</div>
</template>