链接深度画布
This commit is contained in:
37
package-lock.json
generated
37
package-lock.json
generated
@@ -23,6 +23,7 @@
|
|||||||
"pinia-persistedstate-plugin": "^0.1.0",
|
"pinia-persistedstate-plugin": "^0.1.0",
|
||||||
"pinia-plugin-persistedstate": "^3.1.0",
|
"pinia-plugin-persistedstate": "^3.1.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
|
"vue-draggable-plus": "^0.6.1",
|
||||||
"vue-i18n": "^11.2.8",
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6"
|
||||||
},
|
},
|
||||||
@@ -864,6 +865,12 @@
|
|||||||
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/@types/svgo": {
|
||||||
"version": "2.6.4",
|
"version": "2.6.4",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
|
"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": {
|
"node_modules/vue-eslint-parser": {
|
||||||
"version": "9.1.1",
|
"version": "9.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
|
"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==",
|
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
||||||
"dev": true
|
"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": {
|
"@types/svgo": {
|
||||||
"version": "2.6.4",
|
"version": "2.6.4",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
|
||||||
@@ -16626,6 +16655,14 @@
|
|||||||
"@vue/shared": "3.5.27"
|
"@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": {
|
"vue-eslint-parser": {
|
||||||
"version": "9.1.1",
|
"version": "9.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"pinia-persistedstate-plugin": "^0.1.0",
|
"pinia-persistedstate-plugin": "^0.1.0",
|
||||||
"pinia-plugin-persistedstate": "^3.1.0",
|
"pinia-plugin-persistedstate": "^3.1.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
|
"vue-draggable-plus": "^0.6.1",
|
||||||
"vue-i18n": "^11.2.8",
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<div class="drag"><svg-icon name="dc-drag" size="18" /></div>
|
<div class="drag"><svg-icon name="dc-drag" size="18" /></div>
|
||||||
<div class="thumb"></div>
|
<div class="thumb"></div>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<div @dblclick="editName = true" v-if="!editName">图层 1</div>
|
<div @dblclick="editName = true" v-if="!editName">{{ layer.name }}</div>
|
||||||
<input type="text" value="图层 1" v-else @blur="editName = false" />
|
<input type="text" v-model="layer.name" v-else @blur="editName = false" />
|
||||||
</div>
|
</div>
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
<span><svg-icon name="dc-show" size="15" /></span>
|
<span><svg-icon name="dc-show" size="15" /></span>
|
||||||
@@ -16,7 +16,12 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, inject, computed } from 'vue'
|
import { ref, inject, computed } from 'vue'
|
||||||
const props = defineProps({})
|
const props = defineProps({
|
||||||
|
layer: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
const editName = ref(false)
|
const editName = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -34,8 +39,18 @@
|
|||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
&:hover,
|
&:not([draging='true']) {
|
||||||
&.active {
|
&:hover,
|
||||||
|
&.active {
|
||||||
|
background-color: #ededed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.drag {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
&.ghost,
|
||||||
|
&.chosen {
|
||||||
|
box-shadow: inset 0 0 5px #aaa;
|
||||||
background-color: #ededed;
|
background-color: #ededed;
|
||||||
}
|
}
|
||||||
> .drag {
|
> .drag {
|
||||||
|
|||||||
@@ -10,18 +10,62 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<layer-item />
|
<VueDraggable
|
||||||
<layer-item />
|
:model-value="sortableRootLayers"
|
||||||
<layer-item />
|
@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>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { VueDraggable } from 'vue-draggable-plus'
|
||||||
import { ref, inject, computed } from 'vue'
|
import { ref, inject, computed } from 'vue'
|
||||||
import layerItem from './layer-item.vue'
|
import layerItem from './layer-item.vue'
|
||||||
const props = defineProps({})
|
const draging = ref(false)
|
||||||
const emit = defineEmits(['export', 'import'])
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<span class="icon" @click="onDownload">
|
<span class="icon" @click="onDownload">
|
||||||
<svg-icon name="download" size="20" size-unit="px" />
|
<svg-icon name="download" size="20" size-unit="px" />
|
||||||
</span>
|
</span>
|
||||||
<button class="edit">
|
<button class="edit" @click="onEdit">
|
||||||
<span class="icon"><svg-icon name="edit" size="13" /></span>
|
<span class="icon"><svg-icon name="edit" size="13" /></span>
|
||||||
<span class="text">Edit</span>
|
<span class="text">Edit</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import myEvent from '@/utils/myEvent'
|
||||||
import { downloadImage } from '../../../tools/tools'
|
import { downloadImage } from '../../../tools/tools'
|
||||||
import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch } from 'vue'
|
import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch } from 'vue'
|
||||||
const openImagePreview = inject('openImagePreview') as (url: string) => void
|
const openImagePreview = inject('openImagePreview') as (url: string) => void
|
||||||
@@ -129,6 +130,9 @@
|
|||||||
const hideMenu = () => {
|
const hideMenu = () => {
|
||||||
showMenu.value = false
|
showMenu.value = false
|
||||||
}
|
}
|
||||||
|
const onEdit = () => {
|
||||||
|
myEvent.emit('openDepthCanvas', { url: data.url })
|
||||||
|
}
|
||||||
document.addEventListener('mousedown', hideMenu)
|
document.addEventListener('mousedown', hideMenu)
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener('mousedown', hideMenu)
|
document.removeEventListener('mousedown', hideMenu)
|
||||||
@@ -183,7 +187,7 @@
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: #ED8936;
|
background-color: #ed8936;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user