合并画布
This commit is contained in:
@@ -148,7 +148,6 @@ import { BrushStore } from "../store/BrushStore";
|
||||
import { OperationType } from "../utils/layerHelper";
|
||||
import { inject } from "vue";
|
||||
import VerticalSlider from "./VerticalSlider.vue";
|
||||
import SvgIcon from "@/component/Canvas/SvgIcon/index.vue"
|
||||
|
||||
const props = defineProps({
|
||||
activeTool: {
|
||||
|
||||
@@ -11,8 +11,6 @@ import {
|
||||
import { OperationType } from "../utils/layerHelper";
|
||||
import BrushPanel from "./BrushPanel.vue";
|
||||
import { BrushStore } from "../store/BrushStore";
|
||||
import SvgIcon from "@/component/Canvas/SvgIcon/index.vue"
|
||||
|
||||
// 提供brushStore给子组件
|
||||
provide("brushStore", BrushStore);
|
||||
|
||||
@@ -47,30 +45,34 @@ const brushPanelRef = ref(null);
|
||||
// return props.activeTool === OperationType.DRAW;
|
||||
// });
|
||||
|
||||
function updateCanvasSize() {
|
||||
function updateCanvasSize(
|
||||
{ width, height } = { width: props.width, height: props.height }
|
||||
) {
|
||||
if (!layerManager) {
|
||||
console.warn("LayerManager 未初始化,无法调整背景层尺寸");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查画布上是否有除了背景层的其他元素
|
||||
const hasOtherElements = layerManager.layers.value.some((layer) => {
|
||||
if (layer.isBackground) return false;
|
||||
// 检查普通图层是否有对象
|
||||
if (layer.fabricObjects && layer.fabricObjects.length > 0) return true;
|
||||
// 检查固定图层是否有对象
|
||||
if (layer.isFixed && layer.fabricObjects && layer.fabricObjects.length > 0)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
layerManager.resizeCanvas(width, height);
|
||||
|
||||
if (hasOtherElements) {
|
||||
// 有其他元素时使用等比缩放命令
|
||||
layerManager.resizeCanvasWithScale(props.canvasWidth, props.canvasHeight);
|
||||
} else {
|
||||
// 只有背景层时使用普通调整命令
|
||||
layerManager.resizeCanvas(props.canvasWidth, props.canvasHeight);
|
||||
}
|
||||
// // 检查画布上是否有除了背景层的其他元素
|
||||
// const hasOtherElements = layerManager.layers.value.some((layer) => {
|
||||
// if (layer.isBackground) return false;
|
||||
// // 检查普通图层是否有对象
|
||||
// if (layer.fabricObjects && layer.fabricObjects.length > 0) return true;
|
||||
// // 检查固定图层是否有对象
|
||||
// if (layer.isFixed && layer.fabricObjects && layer.fabricObjects.length > 0)
|
||||
// return true;
|
||||
// return false;
|
||||
// });
|
||||
|
||||
// if (hasOtherElements) {
|
||||
// // 有其他元素时使用等比缩放命令
|
||||
// layerManager.resizeCanvasWithScale(width, height);
|
||||
// } else {
|
||||
// // 只有背景层时使用普通调整命令
|
||||
// layerManager.resizeCanvas(width, height);
|
||||
// }
|
||||
|
||||
emit("canvas-size-change");
|
||||
}
|
||||
@@ -268,27 +270,39 @@ onMounted(() => {
|
||||
" -->
|
||||
<div class="canvas-settings" v-if="!props.enabledRedGreenMode">
|
||||
<div class="setting-group">
|
||||
<span class="setting-label">Width</span>
|
||||
<input
|
||||
type="text"
|
||||
<span class="setting-label">{{ $t("宽度") }}</span>
|
||||
<a-input-number
|
||||
:value="canvasWidth"
|
||||
class="setting-input"
|
||||
@input="$emit('update:canvasWidth', Number($event.target.value))"
|
||||
@change="updateCanvasSize"
|
||||
:min="1"
|
||||
:max="9999"
|
||||
:step="1"
|
||||
@change="
|
||||
(value) => {
|
||||
$emit('update:canvasWidth', value);
|
||||
updateCanvasSize({ width: value, height: canvasHeight });
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<span class="setting-label">Height</span>
|
||||
<input
|
||||
type="text"
|
||||
<span class="setting-label">{{ $t("高度") }}</span>
|
||||
<a-input-number
|
||||
:value="canvasHeight"
|
||||
class="setting-input"
|
||||
@input="$emit('update:canvasHeight', Number($event.target.value))"
|
||||
@change="updateCanvasSize"
|
||||
:min="1"
|
||||
:max="9999"
|
||||
:step="1"
|
||||
@change="
|
||||
(value) => {
|
||||
$emit('update:canvasHeight', value);
|
||||
updateCanvasSize({ width: canvasWidth, height: value });
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<span class="setting-label">Color</span>
|
||||
<span class="setting-label">{{ $t("颜色") }}</span>
|
||||
<div class="color-picker-wrapper">
|
||||
<input
|
||||
type="color"
|
||||
@@ -323,11 +337,12 @@ onMounted(() => {
|
||||
</div> -->
|
||||
|
||||
<!-- 绘图工具设置 -->
|
||||
<div class="canvas-settings gap-20" v-if="!props.enabledRedGreenMode">
|
||||
<div class="canvas-settings gap-20">
|
||||
<div
|
||||
class="btn"
|
||||
:class="{ active: showBrushPanel }"
|
||||
@click="toggleBrushPanel"
|
||||
v-if="!props.enabledRedGreenMode"
|
||||
>
|
||||
<!-- <span class="setting-label">笔刷:</span>/ -->
|
||||
<div class="brush-selector">
|
||||
@@ -439,10 +454,11 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.setting-input {
|
||||
width: 60px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.setting-input :deep(.ant-input-number-input) {
|
||||
padding: 4px 8px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -494,15 +510,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.brush-selector {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// border: 1px solid #ddd;
|
||||
// border-radius: 4px;
|
||||
// padding: 5px;
|
||||
// cursor: pointer;
|
||||
// background-color: white;
|
||||
// width: 80px;
|
||||
// justify-content: space-between;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.brush-preview {
|
||||
|
||||
@@ -43,10 +43,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
thumbnailUrl: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
// thumbnailUrl: {
|
||||
// type: String,
|
||||
// default: null,
|
||||
// },
|
||||
isHidenDragHandle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -404,14 +404,11 @@ function findParentLayerId() {
|
||||
<!-- 图层预览图标 -->
|
||||
<div class="layer-review">
|
||||
<img
|
||||
v-if="thumbnailUrl"
|
||||
:src="thumbnailUrl"
|
||||
v-if="layer.thumbnailUrl"
|
||||
:src="layer.thumbnailUrl"
|
||||
class="layer-thumbnail"
|
||||
:alt="$t('图层预览')"
|
||||
/>
|
||||
<span v-else class="layer-type-icon">{{
|
||||
getLayerTypeIcon(layer)
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<!-- 图层名称 -->
|
||||
|
||||
@@ -119,6 +119,8 @@ const canDeleteComputed = computed(() => {
|
||||
<template v-for="(layer, index) in sortableRootLayers" :key="layer.id">
|
||||
<div class="layer-group">
|
||||
<!-- 使用 LayerItem 子组件 -->
|
||||
<!-- :thumbnail-url="getLayerThumbnail(layer.id)" -->
|
||||
|
||||
<LayerItem
|
||||
:layer="layer"
|
||||
:is-child="isChild"
|
||||
@@ -133,7 +135,6 @@ const canDeleteComputed = computed(() => {
|
||||
!layer.isFixed &&
|
||||
!layer.locked
|
||||
"
|
||||
:thumbnail-url="getLayerThumbnail(layer.id)"
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
@click="(...args) => forwardEvent('layer-click', ...args)"
|
||||
@double-click="
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { computed, ref, nextTick, inject } from "vue";
|
||||
import { isGroupLayer } from "../../utils/layerHelper";
|
||||
import { findLayerRecursively, isGroupLayer } from "../../utils/layerHelper";
|
||||
import SvgIcon from "../../../SvgIcon/index.vue";
|
||||
import ContextMenu from "./ContextMenu.vue";
|
||||
import LayerItem from "./LayerItem.vue";
|
||||
@@ -691,15 +691,15 @@ function buildContextMenuItems(layer) {
|
||||
hideContextMenu();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "合并组",
|
||||
icon: "CMergeGroup",
|
||||
disabled: !isGroupLayer || isMultiple,
|
||||
action: () => {
|
||||
mergeGroupLayer(layer.id);
|
||||
hideContextMenu();
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: "合并组", // 不需要了 同栅格化功能一样了
|
||||
// icon: "CMergeGroup",
|
||||
// disabled: !isGroupLayer || isMultiple,
|
||||
// action: () => {
|
||||
// mergeGroupLayer(layer.id);
|
||||
// hideContextMenu();
|
||||
// },
|
||||
// },
|
||||
],
|
||||
},
|
||||
// 图层操作 - 带子菜单
|
||||
@@ -1099,8 +1099,7 @@ async function rasterizeLayer(layerId) {
|
||||
try {
|
||||
const success = await layerManager.rasterizeLayer(layerId);
|
||||
if (success) {
|
||||
const layer = layers.value.find((l) => l.id === layerId);
|
||||
console.log(`✅ 成功栅格化图层: ${layer?.name || layerId}`);
|
||||
console.log(`✅ 成功栅格化图层: ${layerId}`);
|
||||
} else {
|
||||
console.warn("栅格化图层失败");
|
||||
}
|
||||
@@ -1164,6 +1163,11 @@ function moveLayerToBottom(layerId) {
|
||||
console.warn("置底图层失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 事件转发方法
|
||||
const forwardEvent = (eventName, ...args) => {
|
||||
emit(eventName, ...args);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -1281,6 +1285,8 @@ function moveLayerToBottom(layerId) {
|
||||
<!-- 固定层(背景层和固定层) -->
|
||||
<div v-if="fixedLayers.length > 0" class="fixed-layers">
|
||||
<!-- 遍历固定层 -->
|
||||
<!-- :thumbnail-url="getLayerThumbnail(layer.id)" -->
|
||||
|
||||
<LayerItem
|
||||
v-for="layer in fixedLayers"
|
||||
:key="layer.id"
|
||||
@@ -1292,10 +1298,9 @@ function moveLayerToBottom(layerId) {
|
||||
:is-editing="editingLayerId === layer.id"
|
||||
:editing-name="editingLayerName"
|
||||
:can-delete="false"
|
||||
:thumbnail-url="getLayerThumbnail(layer.id)"
|
||||
:isHidenDragHandle="true"
|
||||
@toggle-visibility="
|
||||
(...args) => forwardEvent('toggle-visibility', ...args)
|
||||
(...args) => forwardEvent('toggle-layer-visibility', ...args)
|
||||
"
|
||||
@edit-confirm="(...args) => forwardEvent('edit-confirm', ...args)"
|
||||
@edit-cancel="(...args) => forwardEvent('edit-cancel', ...args)"
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
border-bottom: 1px solid #f5f2f2;
|
||||
padding-left: 30px;
|
||||
padding-right: 10px;
|
||||
color: #333;
|
||||
|
||||
&.group-layer {
|
||||
background-color: rgba(240, 248, 255, 0.3);
|
||||
@@ -677,6 +678,7 @@
|
||||
border-radius: 2px;
|
||||
transition: all 0.2s ease;
|
||||
margin-right: 4px;
|
||||
color: #333;
|
||||
|
||||
// &:hover {
|
||||
// background-color: rgba(0, 0, 0, 0.1);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, inject, computed, onMounted, onUnmounted } from "vue";
|
||||
import { OperationType } from "../utils/layerHelper";
|
||||
import SvgIcon from "@/component/Canvas/SvgIcon/index.vue"
|
||||
|
||||
const props = defineProps({
|
||||
activeTool: String,
|
||||
|
||||
Reference in New Issue
Block a user