链接深度画布

This commit is contained in:
lzp
2026-03-06 17:29:45 +08:00
parent 077f298fe4
commit 7048b3f646
5 changed files with 113 additions and 12 deletions

37
package-lock.json generated
View File

@@ -23,6 +23,7 @@
"pinia-persistedstate-plugin": "^0.1.0",
"pinia-plugin-persistedstate": "^3.1.0",
"vue": "^3.2.47",
"vue-draggable-plus": "^0.6.1",
"vue-i18n": "^11.2.8",
"vue-router": "^4.1.6"
},
@@ -864,6 +865,12 @@
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
"dev": true
},
"node_modules/@types/sortablejs": {
"version": "1.15.9",
"resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.9.tgz",
"integrity": "sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==",
"license": "MIT"
},
"node_modules/@types/svgo": {
"version": "2.6.4",
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
@@ -9372,6 +9379,23 @@
}
}
},
"node_modules/vue-draggable-plus": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/vue-draggable-plus/-/vue-draggable-plus-0.6.1.tgz",
"integrity": "sha512-FbtQ/fuoixiOfTZzG3yoPl4JAo9HJXRHmBQZFB9x2NYCh6pq0TomHf7g5MUmpaDYv+LU2n6BPq2YN9sBO+FbIg==",
"license": "MIT",
"dependencies": {
"@types/sortablejs": "^1.15.8"
},
"peerDependencies": {
"@types/sortablejs": "^1.15.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-eslint-parser": {
"version": "9.1.1",
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
@@ -10318,6 +10342,11 @@
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
"dev": true
},
"@types/sortablejs": {
"version": "1.15.9",
"resolved": "https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.9.tgz",
"integrity": "sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ=="
},
"@types/svgo": {
"version": "2.6.4",
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
@@ -16626,6 +16655,14 @@
"@vue/shared": "3.5.27"
}
},
"vue-draggable-plus": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/vue-draggable-plus/-/vue-draggable-plus-0.6.1.tgz",
"integrity": "sha512-FbtQ/fuoixiOfTZzG3yoPl4JAo9HJXRHmBQZFB9x2NYCh6pq0TomHf7g5MUmpaDYv+LU2n6BPq2YN9sBO+FbIg==",
"requires": {
"@types/sortablejs": "^1.15.8"
}
},
"vue-eslint-parser": {
"version": "9.1.1",
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",

View File

@@ -28,6 +28,7 @@
"pinia-persistedstate-plugin": "^0.1.0",
"pinia-plugin-persistedstate": "^3.1.0",
"vue": "^3.2.47",
"vue-draggable-plus": "^0.6.1",
"vue-i18n": "^11.2.8",
"vue-router": "^4.1.6"
},

View File

@@ -3,8 +3,8 @@
<div class="drag"><svg-icon name="dc-drag" size="18" /></div>
<div class="thumb"></div>
<div class="name">
<div @dblclick="editName = true" v-if="!editName">图层 1</div>
<input type="text" value="图层 1" v-else @blur="editName = false" />
<div @dblclick="editName = true" v-if="!editName">{{ layer.name }}</div>
<input type="text" v-model="layer.name" v-else @blur="editName = false" />
</div>
<div class="icons">
<span><svg-icon name="dc-show" size="15" /></span>
@@ -16,7 +16,12 @@
<script setup lang="ts">
import { ref, inject, computed } from 'vue'
const props = defineProps({})
const props = defineProps({
layer: {
type: Object,
default: () => ({})
}
})
const editName = ref(false)
</script>
@@ -34,10 +39,20 @@
&:last-child {
border-bottom: none;
}
&:not([draging='true']) {
&:hover,
&.active {
background-color: #ededed;
}
}
&.drag {
opacity: 0;
}
&.ghost,
&.chosen {
box-shadow: inset 0 0 5px #aaa;
background-color: #ededed;
}
> .drag {
padding: 0.3rem;
cursor: move;

View File

@@ -10,18 +10,62 @@
</div>
</div>
<div class="content">
<layer-item />
<layer-item />
<layer-item />
<VueDraggable
:model-value="sortableRootLayers"
@start="handleDragStart"
@end="handleDragEnd"
class="sortable-layers"
:data-container-type="'root'"
:data-parent-id="null"
:animation="250"
:disabled="false"
handle=".drag"
ghost-class="ghost"
chosen-class="chosen"
drag-class="drag"
:group="{
name: 'groupName',
pull: true,
put: true
}"
:swap-threshold="0.5"
:empty-insert-threshold="5"
:force-fallback="false"
:fallback-tolerance="3"
:scroll-sensitivity="100"
:scroll-speed="10"
>
<layer-item
v-for="layer in sortableRootLayers"
:key="layer.id"
:layer="layer"
:draging="draging"
/>
</VueDraggable>
</div>
</div>
</template>
<script setup lang="ts">
import { VueDraggable } from 'vue-draggable-plus'
import { ref, inject, computed } from 'vue'
import layerItem from './layer-item.vue'
const props = defineProps({})
const emit = defineEmits(['export', 'import'])
const draging = ref(false)
const sortableRootLayers = ref([
{ id: 1, name: 'layer1' },
{ id: 2, name: 'layer2' },
{ id: 3, name: 'layer3' }
])
const handleDragStart = () => {
draging.value = true
}
const handleDragEnd = (event) => {
draging.value = false
const { from, to, oldIndex, newIndex, item } = event
console.log('🔄 拖拽结束事件:', event)
sortableRootLayers.value.splice(newIndex, 0, sortableRootLayers.value.splice(oldIndex, 1)[0])
}
</script>
<style lang="less" scoped>

View File

@@ -11,7 +11,7 @@
<span class="icon" @click="onDownload">
<svg-icon name="download" size="20" size-unit="px" />
</span>
<button class="edit">
<button class="edit" @click="onEdit">
<span class="icon"><svg-icon name="edit" size="13" /></span>
<span class="text">Edit</span>
</button>
@@ -41,6 +41,7 @@
</template>
<script setup lang="ts">
import myEvent from '@/utils/myEvent'
import { downloadImage } from '../../../tools/tools'
import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch } from 'vue'
const openImagePreview = inject('openImagePreview') as (url: string) => void
@@ -129,6 +130,9 @@
const hideMenu = () => {
showMenu.value = false
}
const onEdit = () => {
myEvent.emit('openDepthCanvas', { url: data.url })
}
document.addEventListener('mousedown', hideMenu)
onBeforeUnmount(() => {
document.removeEventListener('mousedown', hideMenu)
@@ -183,7 +187,7 @@
height: 30px;
border-radius: 4px;
border: none;
background-color: #ED8936;
background-color: #ed8936;
color: #fff;
font-size: 12px;
display: flex;