略略略略略略略略略略略略
This commit is contained in:
@@ -287,7 +287,7 @@ const canDeleteComputed = computed(() => {
|
||||
:is-child="isChild"
|
||||
:is-active="layer.id === activeLayerId"
|
||||
:is-selected="isLayerSelected(layer.id)"
|
||||
:is-multi-select-mode="isMultiSelectMode"
|
||||
:is-multi-select-mode="isMultiSelectMode && !layer.specialType"
|
||||
:is-editing="editingLayerId === layer.id"
|
||||
:editing-name="editingLayerName"
|
||||
:can-delete="
|
||||
@@ -296,7 +296,7 @@ const canDeleteComputed = computed(() => {
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
@click="(...args) => forwardEvent('layer-click', ...args)"
|
||||
@double-click="(...args) => forwardEvent('layer-double-click', ...args)"
|
||||
@context-menu="(...args) => forwardEvent('context-menu', ...args)"
|
||||
@context-menu="(...args) => !layer.specialType && forwardEvent('context-menu', ...args)"
|
||||
@checkbox-change="(...args) => forwardEvent('checkbox-change', ...args)"
|
||||
@toggle-visibility="(...args) => forwardEvent('toggle-visibility', ...args)"
|
||||
@toggle-lock="(...args) => forwardEvent('toggle-lock', ...args)"
|
||||
@@ -337,7 +337,7 @@ const canDeleteComputed = computed(() => {
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
:isChild="true"
|
||||
:parentLayerId="layer.id"
|
||||
:group-name="groupName"
|
||||
:group-name="layer.specialType || groupName"
|
||||
@layer-click="(...args) => forwardEvent('layer-click', ...args)"
|
||||
@layer-double-click="(...args) => forwardEvent('layer-double-click', ...args)"
|
||||
@context-menu="(...args) => forwardEvent('context-menu', ...args)"
|
||||
@@ -385,17 +385,10 @@ const canDeleteComputed = computed(() => {
|
||||
<style scoped lang="less">
|
||||
// 从父组件的样式文件中继承相关样式
|
||||
.layers-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
.sortable-layers {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
// .layer-group {
|
||||
// // margin-bottom: 1px;
|
||||
// }
|
||||
|
||||
.child-layers {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
|
||||
@@ -1240,6 +1240,12 @@ async function handleCrossLevelMove(moveData) {
|
||||
}
|
||||
|
||||
try {
|
||||
const layer = findLayerRecursively(layers.value, layerId).layer;
|
||||
const toLayer = findLayerRecursively(layers.value, toParentId).layer;
|
||||
if(layer?.specialType || toLayer?.specialType) {
|
||||
console.warn("当前图层不可移动到外部");
|
||||
return;
|
||||
}
|
||||
// 如果有命令管理器,使用命令模式
|
||||
if (commandManager) {
|
||||
console.log("📝 使用命令模式执行跨层级移动");
|
||||
@@ -1593,46 +1599,48 @@ async function moveGroupToGroup(draggedLayer, fromParentId, toParentId, newIndex
|
||||
<small>{{ $t('Canvas.Hint') }}</small>
|
||||
</div>
|
||||
|
||||
<div class="layers-list-container">
|
||||
<!-- 图层列表组件 -->
|
||||
<LayersList
|
||||
:layers="layers"
|
||||
:active-layer-id="activeLayerId"
|
||||
:sortable-root-layers="sortableRootLayers"
|
||||
:fixed-layers="fixedLayers"
|
||||
:selected-layer-ids="selectedLayerIds"
|
||||
:is-multi-select-mode="isMultiSelectMode"
|
||||
:editing-layer-id="editingLayerId"
|
||||
:editing-layer-name="editingLayerName"
|
||||
:thumbnail-manager="thumbnailManager"
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
:isChild="false"
|
||||
group-name="layers-root"
|
||||
@layer-click="handleLayerClick"
|
||||
@layer-double-click="handleLayerDoubleClick"
|
||||
@context-menu="showContextMenu"
|
||||
@checkbox-change="handleCheckboxClick"
|
||||
@toggle-visibility="toggleLayerVisibility"
|
||||
@toggle-lock="toggleSelectedLayersLockByLayer"
|
||||
@delete="removeLayer"
|
||||
@edit-confirm="confirmEdit"
|
||||
@edit-cancel="cancelEdit"
|
||||
@edit-keydown="handleEditKeydown"
|
||||
@touch-start="handleTouchStart"
|
||||
@touch-move="handleTouchMove"
|
||||
@touch-end="handleTouchEnd"
|
||||
@update:editing-name="editingLayerName = $event"
|
||||
@root-layers-sort="handleRootLayersSort"
|
||||
@child-layers-sort="handleChildLayersSort"
|
||||
@cross-level-move="handleCrossLevelMove"
|
||||
@select-child-layer="selectChildLayer"
|
||||
@start-child-layer-edit="startChildLayerEdit"
|
||||
@child-context-menu="showChildLayerContextMenu"
|
||||
@toggle-group-expanded="toggleGroupExpanded"
|
||||
@toggle-child-visibility="toggleChildLayerVisibility"
|
||||
@toggle-child-lock="toggleChildLayerLock"
|
||||
@delete-child="deleteChildLayer"
|
||||
@rename-child="renameChildLayer"
|
||||
/>
|
||||
<LayersList
|
||||
:layers="layers"
|
||||
:active-layer-id="activeLayerId"
|
||||
:sortable-root-layers="sortableRootLayers"
|
||||
:fixed-layers="fixedLayers"
|
||||
:selected-layer-ids="selectedLayerIds"
|
||||
:is-multi-select-mode="isMultiSelectMode"
|
||||
:editing-layer-id="editingLayerId"
|
||||
:editing-layer-name="editingLayerName"
|
||||
:thumbnail-manager="thumbnailManager"
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
:isChild="false"
|
||||
group-name="layers-root"
|
||||
@layer-click="handleLayerClick"
|
||||
@layer-double-click="handleLayerDoubleClick"
|
||||
@context-menu="showContextMenu"
|
||||
@checkbox-change="handleCheckboxClick"
|
||||
@toggle-visibility="toggleLayerVisibility"
|
||||
@toggle-lock="toggleSelectedLayersLockByLayer"
|
||||
@delete="removeLayer"
|
||||
@edit-confirm="confirmEdit"
|
||||
@edit-cancel="cancelEdit"
|
||||
@edit-keydown="handleEditKeydown"
|
||||
@touch-start="handleTouchStart"
|
||||
@touch-move="handleTouchMove"
|
||||
@touch-end="handleTouchEnd"
|
||||
@update:editing-name="editingLayerName = $event"
|
||||
@root-layers-sort="handleRootLayersSort"
|
||||
@child-layers-sort="handleChildLayersSort"
|
||||
@cross-level-move="handleCrossLevelMove"
|
||||
@select-child-layer="selectChildLayer"
|
||||
@start-child-layer-edit="startChildLayerEdit"
|
||||
@child-context-menu="showChildLayerContextMenu"
|
||||
@toggle-group-expanded="toggleGroupExpanded"
|
||||
@toggle-child-visibility="toggleChildLayerVisibility"
|
||||
@toggle-child-lock="toggleChildLayerLock"
|
||||
@delete-child="deleteChildLayer"
|
||||
@rename-child="renameChildLayer"
|
||||
/>
|
||||
</div>
|
||||
<!-- 固定层(背景层和固定层) -->
|
||||
<div v-if="fixedLayers.length > 0" class="fixed-layers">
|
||||
<!-- 遍历固定层 -->
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
flex-direction: column;
|
||||
user-select: none;
|
||||
z-index: 6;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
// max-height: 70vh;
|
||||
overflow: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
@@ -161,12 +161,12 @@
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.layers-list-container{
|
||||
overflow-y: auto;
|
||||
}
|
||||
// 图层列表
|
||||
.layers-list {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// 图层项样式
|
||||
|
||||
@@ -179,7 +179,11 @@
|
||||
import { ref, onMounted, watch, onUnmounted, reactive } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n();
|
||||
import { OperationType, SpecialLayerId } from "../../utils/layerHelper";
|
||||
import {
|
||||
OperationType,
|
||||
SpecialLayerId,
|
||||
SpecialType,
|
||||
} from "../../utils/layerHelper";
|
||||
import { loadImageUrlToLayer } from "../../utils/imageHelper";
|
||||
import {
|
||||
calculateRotatedTopLeftDeg,
|
||||
@@ -280,6 +284,9 @@
|
||||
const getActiveObject = (e) => {
|
||||
console.log("==========切换激活对象", e, activeObjects);
|
||||
activeObjects.value = [...e.selected];
|
||||
// .filter((v) =>
|
||||
// v.specialType ? v.specialType === SpecialType.REPEAT_O : true
|
||||
// );// 过滤出印花对象
|
||||
activeObjects.value.forEach((v) => {
|
||||
v.layer = props.layerManager.getLayerById(v.layerId);
|
||||
});
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
flex-direction: column;
|
||||
user-select: none;
|
||||
z-index: 6;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.layers-header {
|
||||
@@ -132,10 +132,11 @@
|
||||
color: #666;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
.layers-list-container {
|
||||
overflow-y: auto;
|
||||
}
|
||||
.layers-list {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.layer-item {
|
||||
position: relative;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="angle-tool">
|
||||
<div class="angle-tool" :disabled="disabled">
|
||||
<div
|
||||
ref="dishRef"
|
||||
class="dish"
|
||||
@@ -11,7 +11,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="input">
|
||||
<input type="number" v-model="angle" @input="onInput" @change="onChange" />
|
||||
<input
|
||||
type="number"
|
||||
v-model="angle"
|
||||
@input="onInput"
|
||||
@change="onChange"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -25,14 +31,22 @@
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["change", "input"]);
|
||||
const angle = ref(props.angle);
|
||||
watch(() => props.angle, (value) => {
|
||||
angle.value = value;
|
||||
});
|
||||
watch(
|
||||
() => props.angle,
|
||||
(value) => {
|
||||
angle.value = value;
|
||||
}
|
||||
);
|
||||
const dishRef = ref<HTMLDivElement>();
|
||||
const mousedown = (e: MouseEvent | TouchEvent) => {
|
||||
if (props.disabled) return;
|
||||
const mousemove = (e: MouseEvent | TouchEvent) => {
|
||||
if (!dishRef.value) return;
|
||||
const { left, top, width, height } =
|
||||
@@ -56,9 +70,10 @@
|
||||
document.addEventListener("mouseup", mouseup);
|
||||
document.addEventListener("touchend", mouseup);
|
||||
};
|
||||
const onInput = () => emit("input", angle.value);
|
||||
const onInput = () => !props.disabled && emit("input", angle.value);
|
||||
var changeTime: any = null;
|
||||
const onChange = () => {
|
||||
if (props.disabled) return;
|
||||
clearTimeout(changeTime);
|
||||
changeTime = setTimeout(() => emit("change", angle.value), 500);
|
||||
};
|
||||
@@ -79,10 +94,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
--color: #000;
|
||||
&[disabled="true"] {
|
||||
--color: #b2b2b2;
|
||||
> .dish {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
> .dish {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: 1px solid #000;
|
||||
border: 1px solid var(--color);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
> .pointer {
|
||||
@@ -98,7 +120,7 @@
|
||||
transform: translate(-50%, 0);
|
||||
width: 35%;
|
||||
height: 35%;
|
||||
background-color: #000;
|
||||
background-color: var(--color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
@@ -106,7 +128,7 @@
|
||||
> .input {
|
||||
margin-left: 5px;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
color: var(--color);
|
||||
flex: 1;
|
||||
// min-width: 45px;
|
||||
// max-width: 80px;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@change="change"
|
||||
:defaultValue="defaultValue"
|
||||
@dropdownVisibleChange="dropdownVisibleChange"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="v in list"
|
||||
@@ -21,6 +22,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits, watch } from "vue";
|
||||
const props = defineProps({
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defaultValue: {
|
||||
default: "",
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="slider">
|
||||
<div class="slider" :disabled="disabled">
|
||||
<div class="input-range">
|
||||
<span
|
||||
class="tip"
|
||||
@@ -16,6 +16,7 @@
|
||||
:step="props.step"
|
||||
@input="onInput"
|
||||
@change="onChange"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
<div class="input" v-show="isInput">
|
||||
@@ -27,6 +28,7 @@
|
||||
:step="props.step"
|
||||
@input="onInput"
|
||||
@change="onChange"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -35,6 +37,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits, watch } from "vue";
|
||||
const props = defineProps({
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
@@ -66,9 +72,10 @@
|
||||
() => props.value,
|
||||
(v) => (value.value = v)
|
||||
);
|
||||
const onInput = () => emit("input", Number(value.value));
|
||||
const onInput = () => !props.disabled && emit("input", Number(value.value));
|
||||
var changeTime: any = null;
|
||||
const onChange = () => {
|
||||
if (props.disabled) return;
|
||||
clearTimeout(changeTime);
|
||||
changeTime = setTimeout(() => emit("change", Number(value.value)), 500);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user