深度画布功能
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="header-tools">
|
||||
<template v-for="(v, i) in tools" :key="i">
|
||||
<span class="line" v-if="v.type === 'line'"></span>
|
||||
<span
|
||||
v-else
|
||||
class="icon"
|
||||
@click="onClickTool(v)"
|
||||
:class="{ active: v.name === tool, disabled: v.disabled }"
|
||||
>
|
||||
<svg-icon :name="v.icon" :size="v.iconSize" />
|
||||
</span>
|
||||
</template>
|
||||
<button class="export" @click="emit('export')">
|
||||
<span class="icon"><svg-icon name="export" size="12" /></span>
|
||||
<span class="text">Export</span>
|
||||
</button>
|
||||
<button class="export" @click="emit('import')">
|
||||
<span class="text">import</span>
|
||||
</button>
|
||||
<button class="workbench">
|
||||
<span class="icon"><svg-icon name="dc-workbench" size="20" /></span>
|
||||
<span class="text">Workbench</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, inject, computed } from 'vue'
|
||||
import { OperationType } from '../tools/layerHelper'
|
||||
const props = defineProps({
|
||||
zoom: { default: 1, type: Number },
|
||||
step: { default: 0.1, type: Number }
|
||||
})
|
||||
const emit = defineEmits(['export', 'import'])
|
||||
const importLocalImage = inject('importLocalImage') as () => void
|
||||
const stateManager = inject('stateManager') as any
|
||||
const toolManager = inject('toolManager') as any
|
||||
const tool = computed(() => toolManager.currentTool.value)
|
||||
const historyIndex = computed(() => stateManager.historyIndex.value)
|
||||
const historyList = computed(() => stateManager.historyList.value)
|
||||
const isUndo = computed(() => !historyList.value[historyIndex.value - 1])
|
||||
const isRedo = computed(() => !historyList.value[historyIndex.value + 1])
|
||||
const tools = ref([
|
||||
{ name: OperationType.SELECT, icon: 'dc-select', iconSize: 16, disabled: ref(false) },
|
||||
{ name: OperationType.PAN, icon: 'dc-move', iconSize: 18, disabled: ref(false) },
|
||||
{ name: OperationType.DRAW, icon: 'dc-brush', iconSize: 18, disabled: ref(false) },
|
||||
{ name: OperationType.ERASER, icon: 'dc-eraser', iconSize: 18, disabled: ref(false) },
|
||||
{
|
||||
name: OperationType.IMAGE,
|
||||
icon: 'dc-image',
|
||||
iconSize: 17,
|
||||
disabled: ref(false),
|
||||
on: () => importLocalImage()
|
||||
},
|
||||
{ name: OperationType.SELECTBOX, icon: 'dc-selectbox', iconSize: 16, disabled: ref(false) },
|
||||
{ name: OperationType.RECTANGLE, icon: 'dc-rectangle', iconSize: 16, disabled: ref(false) },
|
||||
{ type: 'line' },
|
||||
{
|
||||
name: OperationType.UNDO,
|
||||
icon: 'dc-undo',
|
||||
iconSize: 18,
|
||||
disabled: isUndo,
|
||||
on: () => stateManager.undoState()
|
||||
},
|
||||
{
|
||||
name: OperationType.REDO,
|
||||
icon: 'dc-redo',
|
||||
iconSize: 18,
|
||||
disabled: isRedo,
|
||||
on: () => stateManager.redoState()
|
||||
}
|
||||
])
|
||||
const onClickTool = (tool: any) => {
|
||||
if (tool.disabled?.value) return
|
||||
if (tool.on) {
|
||||
tool.on()
|
||||
} else {
|
||||
toolManager.setTool(tool.name)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.header-tools {
|
||||
position: absolute;
|
||||
top: 2.2rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 5rem;
|
||||
padding: 0.7rem 1.8rem;
|
||||
border: 0.2rem solid #ebebeb;
|
||||
background: #ffffff;
|
||||
border-radius: 0.6rem;
|
||||
box-shadow: 0 1.66rem 2.33rem 0 rgba(0, 0, 0, 0.05);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
gap: 1rem;
|
||||
> .line {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-left: 0.2rem solid #d9d9d9;
|
||||
border-radius: 0.2rem;
|
||||
margin: 0 0.6rem;
|
||||
}
|
||||
> .icon {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
--svg-icon-color: #000;
|
||||
border-radius: 0.4rem;
|
||||
&:not(.disabled).active,
|
||||
&:not(.disabled):hover {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
> button {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.8rem;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
> .export {
|
||||
width: 10rem;
|
||||
height: 3rem;
|
||||
background-color: #0d0d0d;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 0.4rem;
|
||||
}
|
||||
> .workbench {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2.4rem;
|
||||
transform: translateX(100%);
|
||||
height: 100%;
|
||||
padding: 0 2.4rem;
|
||||
border: 0.2rem solid #ebebeb;
|
||||
background: #ffffff;
|
||||
border-radius: 0.6rem;
|
||||
box-shadow: 0 1.66rem 2.33rem 0 rgba(0, 0, 0, 0.05);
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user