Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/FiDA_Front
This commit is contained in:
@@ -96,3 +96,10 @@ body,
|
|||||||
--el-color-primary-dark-2: #565656;
|
--el-color-primary-dark-2: #565656;
|
||||||
/* 深灰色(加深20%) */
|
/* 深灰色(加深20%) */
|
||||||
}
|
}
|
||||||
|
.mini-scrollbar::-webkit-scrollbar {
|
||||||
|
width: 0.4rem;
|
||||||
|
}
|
||||||
|
.mini-scrollbar::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,3 +105,15 @@ body,
|
|||||||
--el-color-primary-light-9: #e3e3e3; /* 极浅的灰色(混合60%白) */
|
--el-color-primary-light-9: #e3e3e3; /* 极浅的灰色(混合60%白) */
|
||||||
--el-color-primary-dark-2: #565656; /* 深灰色(加深20%) */
|
--el-color-primary-dark-2: #565656; /* 深灰色(加深20%) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 迷你滚动条
|
||||||
|
.mini-scrollbar {
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0.4rem;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<span class="label">{{ item.label }}</span>
|
<span class="label">{{ item.label }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button @click="onCreate">创建</button>
|
<button @click="onCreate">创建</button>
|
||||||
|
<button @click="onReset">重置</button>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<brush-control-panel v-if="show" :currentTool="currentTool2" style="top: 14rem" />
|
<brush-control-panel v-if="show" :currentTool="currentTool2" style="top: 14rem" />
|
||||||
@@ -21,6 +22,8 @@
|
|||||||
import depthSlider from './tools/depth-slider.vue'
|
import depthSlider from './tools/depth-slider.vue'
|
||||||
import { OperationType } from '../tools/layerHelper'
|
import { OperationType } from '../tools/layerHelper'
|
||||||
import brushControlPanel from './brush-control-panel.vue'
|
import brushControlPanel from './brush-control-panel.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentTool: { required: true, type: [String, null] }
|
currentTool: { required: true, type: [String, null] }
|
||||||
@@ -37,22 +40,22 @@
|
|||||||
{
|
{
|
||||||
type: OperationType.AISELECT_ADD,
|
type: OperationType.AISELECT_ADD,
|
||||||
name: 'dc-add_sb',
|
name: 'dc-add_sb',
|
||||||
label: 'Add'
|
label: t('DepthCanvas.add')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: OperationType.AISELECT_REMOVE,
|
type: OperationType.AISELECT_REMOVE,
|
||||||
name: 'dc-remove_sb',
|
name: 'dc-remove_sb',
|
||||||
label: 'Remove'
|
label: t('DepthCanvas.remove')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: OperationType.AISELECT_DRAW,
|
type: OperationType.AISELECT_DRAW,
|
||||||
name: 'dc-brush_sb',
|
name: 'dc-brush_sb',
|
||||||
label: 'Brush'
|
label: t('DepthCanvas.brush')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: OperationType.AISELECT_ERASER,
|
type: OperationType.AISELECT_ERASER,
|
||||||
name: 'dc-erase_sb',
|
name: 'dc-erase_sb',
|
||||||
label: 'Erase'
|
label: t('DepthCanvas.erase')
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const onClickItem = (type: string) => {
|
const onClickItem = (type: string) => {
|
||||||
@@ -61,6 +64,9 @@
|
|||||||
const onCreate = () => {
|
const onCreate = () => {
|
||||||
stateManager.aiSelectboxToolManager.createSelectbox()
|
stateManager.aiSelectboxToolManager.createSelectbox()
|
||||||
}
|
}
|
||||||
|
const onReset = () => {
|
||||||
|
stateManager.aiSelectboxToolManager.resetDemoObject()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
// 淡入淡出动画
|
// 淡入淡出动画
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<button class="export" @click="emit('export')">
|
<button class="export" @click="emit('export')">
|
||||||
<span class="icon"><svg-icon name="export" size="12" /></span>
|
<span class="icon"><svg-icon name="export" size="12" /></span>
|
||||||
<span class="text">Export</span>
|
<span class="text">{{ $t('DepthCanvas.export') }}</span>
|
||||||
</button>
|
</button>
|
||||||
<!-- <button class="export" @click="emit('export-local')">
|
<!-- <button class="export" @click="emit('export-local')">
|
||||||
<span class="text">保存本地</span>
|
<span class="text">保存本地</span>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
</button> -->
|
</button> -->
|
||||||
<button class="workbench" @click="onWorkbench">
|
<button class="workbench" @click="onWorkbench">
|
||||||
<span class="icon"><svg-icon name="dc-workbench" size="20" /></span>
|
<span class="icon"><svg-icon name="dc-workbench" size="20" /></span>
|
||||||
<span class="text">Workbench</span>
|
<span class="text">{{ $t('DepthCanvas.save') }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
import { ref, inject, computed } from 'vue'
|
import { ref, inject, computed } from 'vue'
|
||||||
import { exportCanvasToImage } from '../tools/exportMethod'
|
import { exportCanvasToImage } from '../tools/exportMethod'
|
||||||
import { OperationType, BlendMode } from '../tools/layerHelper'
|
import { OperationType, BlendMode } from '../tools/layerHelper'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
zoom: { default: 1, type: Number },
|
zoom: { default: 1, type: Number },
|
||||||
step: { default: 0.1, type: Number }
|
step: { default: 0.1, type: Number }
|
||||||
@@ -86,37 +88,37 @@
|
|||||||
child: [
|
child: [
|
||||||
{
|
{
|
||||||
name: OperationType.RECTANGLE,
|
name: OperationType.RECTANGLE,
|
||||||
label: 'Rectangle',
|
label: t('DepthCanvas.rectangle'),
|
||||||
icon: 'dc-rectangle',
|
icon: 'dc-rectangle',
|
||||||
iconSize: 13
|
iconSize: 13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: OperationType.LINE,
|
name: OperationType.LINE,
|
||||||
label: 'Line',
|
label: t('DepthCanvas.line'),
|
||||||
icon: 'dc-line',
|
icon: 'dc-line',
|
||||||
iconSize: 10
|
iconSize: 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: OperationType.ARROW,
|
name: OperationType.ARROW,
|
||||||
label: 'Arrow',
|
label: t('DepthCanvas.arrow'),
|
||||||
icon: 'dc-arrow',
|
icon: 'dc-arrow',
|
||||||
iconSize: 11
|
iconSize: 11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: OperationType.ELLIPSE,
|
name: OperationType.ELLIPSE,
|
||||||
label: 'Ellipse',
|
label: t('DepthCanvas.ellipse'),
|
||||||
icon: 'dc-ellipse',
|
icon: 'dc-ellipse',
|
||||||
iconSize: 15
|
iconSize: 15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: OperationType.TRIANGLE,
|
name: OperationType.TRIANGLE,
|
||||||
label: 'Polygon',
|
label: t('DepthCanvas.triangle'),
|
||||||
icon: 'dc-triangle',
|
icon: 'dc-triangle',
|
||||||
iconSize: 14
|
iconSize: 14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: OperationType.STAR,
|
name: OperationType.STAR,
|
||||||
label: 'Star',
|
label: t('DepthCanvas.star'),
|
||||||
icon: 'dc-star',
|
icon: 'dc-star',
|
||||||
iconSize: 15
|
iconSize: 15
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,153 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="basic-info">
|
<div class="basic-info h">
|
||||||
<div>
|
<div>
|
||||||
<span class="label">X:</span>
|
<div class="title">{{ $t('DepthCanvas.position') }}</div>
|
||||||
<span class="value">{{ object.left }}</span>
|
<div class="content">
|
||||||
|
<div>
|
||||||
|
<depth-input
|
||||||
|
before="X"
|
||||||
|
type="number"
|
||||||
|
v-model="data.left"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<depth-input
|
||||||
|
before="Y"
|
||||||
|
type="number"
|
||||||
|
v-model="data.top"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div>
|
||||||
|
<depth-input
|
||||||
|
before="W"
|
||||||
|
type="number"
|
||||||
|
v-model="data.width"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<depth-input
|
||||||
|
before="H"
|
||||||
|
type="number"
|
||||||
|
v-model="data.height"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="label">Y:</span>
|
<div class="title">{{ $t('DepthCanvas.scale') }}</div>
|
||||||
<span class="value">{{ object.top }}</span>
|
<div class="content">
|
||||||
</div>
|
<div>
|
||||||
<div>
|
<depth-input
|
||||||
<span class="label">Width:</span>
|
type="number"
|
||||||
<span class="value">{{ object.width }}</span>
|
before="X"
|
||||||
</div>
|
after="%"
|
||||||
<div>
|
v-model="data.scaleX"
|
||||||
<span class="label">Height:</span>
|
@input="onInpot"
|
||||||
<span class="value">{{ object.height }}</span>
|
@change="onChange"
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<span class="label">缩放X:</span>
|
<div>
|
||||||
<span class="value">{{ object.scaleX }}</span>
|
<depth-input
|
||||||
</div>
|
type="number"
|
||||||
<div>
|
before="Y"
|
||||||
<span class="label">缩放Y:</span>
|
after="%"
|
||||||
<span class="value">{{ object.scaleY }}</span>
|
v-model="data.scaleY"
|
||||||
</div>
|
@input="onInpot"
|
||||||
<div>
|
@change="onChange"
|
||||||
<span class="label">Angle:</span>
|
/>
|
||||||
<span class="value">{{ object.angle }}</span>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, inject, computed, watch, onMounted } from 'vue'
|
import { ref, inject, computed, nextTick, onBeforeUnmount, reactive, watch } from 'vue'
|
||||||
|
import DepthInput from '../tools/depth-input.vue'
|
||||||
|
const objectManager = inject('objectManager') as any
|
||||||
|
const stateManager = inject('stateManager') as any
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
object: {
|
object: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
onMounted(() => {})
|
const id = computed(() => props.object.info.id)
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
scaleX: 1,
|
||||||
|
scaleY: 1
|
||||||
|
})
|
||||||
|
const updateData = async () => {
|
||||||
|
await nextTick()
|
||||||
|
data.top = Math.round(props.object.top)
|
||||||
|
data.left = Math.round(props.object.left)
|
||||||
|
data.width = Math.round(props.object.width)
|
||||||
|
data.height = Math.round(props.object.height)
|
||||||
|
data.scaleX = Math.round(props.object.scaleX * 100)
|
||||||
|
data.scaleY = Math.round(props.object.scaleY * 100)
|
||||||
|
}
|
||||||
|
updateData()
|
||||||
|
watch(() => props.object, updateData)
|
||||||
|
|
||||||
|
const onInpot = () => setPriority(false)
|
||||||
|
const onChange = () => setPriority(true)
|
||||||
|
const setPriority = (isRecord: boolean) => {
|
||||||
|
const options = {
|
||||||
|
...data,
|
||||||
|
scaleX: data.scaleX / 100,
|
||||||
|
scaleY: data.scaleY / 100
|
||||||
|
}
|
||||||
|
objectManager.updateProperty(id.value, options, isRecord)
|
||||||
|
}
|
||||||
|
|
||||||
|
stateManager.event.add('canvas:undo', updateData)
|
||||||
|
stateManager.event.add('canvas:redo', updateData)
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
stateManager.event.remove('canvas:undo', updateData)
|
||||||
|
stateManager.event.remove('canvas:redo', updateData)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.basic-info {
|
.basic-info {
|
||||||
|
--details-item-margin-bottom: 1.6rem;
|
||||||
> div {
|
> div {
|
||||||
padding: 0.8rem 0;
|
> .content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
> .label {
|
justify-content: center;
|
||||||
font-size: 1.6rem;
|
> div {
|
||||||
color: #000;
|
flex: 1;
|
||||||
font-weight: bold;
|
margin-right: 3rem;
|
||||||
min-width: 7rem;
|
display: flex;
|
||||||
text-align: right;
|
flex-direction: column;
|
||||||
margin-right: 0.8rem;
|
--depth-input-height: 2.4rem;
|
||||||
}
|
--depth-input-bg-color: rgba(249, 249, 250, 1);
|
||||||
> .value {
|
--depth-input-border-color: rgba(230, 230, 231, 1);
|
||||||
font-size: 1.6rem;
|
--depth-input-decorate-color: rgba(69, 71, 84, 0.1);
|
||||||
color: #333;
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
> .label {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fill-repeat h">
|
<div class="fill-repeat h">
|
||||||
<div>
|
<div>
|
||||||
<div class="title">Image</div>
|
<div class="title">{{ $t('DepthCanvas.image') }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<img :src="object.info.fill.source" alt="" />
|
<img :src="object.info.fill.source" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="title">Sttings</div>
|
<div class="title">{{ $t('DepthCanvas.settings') }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Rotation</div>
|
<div class="label">{{ $t('DepthCanvas.rotation') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-input
|
<depth-input
|
||||||
icon="dc-angle"
|
icon="dc-angle"
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Scale</div>
|
<div class="label">{{ $t('DepthCanvas.scale') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-slider
|
<depth-slider
|
||||||
v-model="scale"
|
v-model="scale"
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Opacity</div>
|
<div class="label">{{ $t('DepthCanvas.opacity') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-slider
|
<depth-slider
|
||||||
v-model="opacity"
|
v-model="opacity"
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Gap X</div>
|
<div class="label">{{ $t('DepthCanvas.gapX') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-slider
|
<depth-slider
|
||||||
v-model="gapX"
|
v-model="gapX"
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Gap Y</div>
|
<div class="label">{{ $t('DepthCanvas.gapY') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-slider
|
<depth-slider
|
||||||
v-model="gapY"
|
v-model="gapY"
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">Offset</div>
|
<div class="label">{{ $t('DepthCanvas.offset') }}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<depth-offset-tool
|
<depth-offset-tool
|
||||||
v-model="offset"
|
v-model="offset"
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, inject, computed, nextTick, onBeforeUnmount } from 'vue'
|
import { ref, inject, computed, nextTick, onBeforeUnmount, watch } from 'vue'
|
||||||
import DepthOffsetTool from '../tools/depth-offset-tool.vue'
|
import DepthOffsetTool from '../tools/depth-offset-tool.vue'
|
||||||
import DepthSlider from '../tools/depth-slider.vue'
|
import DepthSlider from '../tools/depth-slider.vue'
|
||||||
import DepthInput from '../tools/depth-input.vue'
|
import DepthInput from '../tools/depth-input.vue'
|
||||||
@@ -134,6 +134,7 @@
|
|||||||
opacity.value = Math.round(props.object.opacity * 100)
|
opacity.value = Math.round(props.object.opacity * 100)
|
||||||
}
|
}
|
||||||
updateData()
|
updateData()
|
||||||
|
watch(() => props.object, updateData)
|
||||||
|
|
||||||
const inputFillTransform = () => setFillTransform(false)
|
const inputFillTransform = () => setFillTransform(false)
|
||||||
const changeFillTransform = () => setFillTransform(true)
|
const changeFillTransform = () => setFillTransform(true)
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
<div class="details-panel">
|
<div class="details-panel">
|
||||||
<div class="header" @click="show = !show">
|
<div class="header" @click="show = !show">
|
||||||
<span class="icon"><svg-icon name="dc-details_edit" size="17" /></span>
|
<span class="icon"><svg-icon name="dc-details_edit" size="17" /></span>
|
||||||
<span class="title">Edit Details</span>
|
<span class="title">{{ $t('DepthCanvas.editDetails') }}</span>
|
||||||
<span class="arrow" :class="{ show }">
|
<span class="arrow" :class="{ show }">
|
||||||
<svg-icon name="dc-down_arrow2" size="10" />
|
<svg-icon name="dc-down_arrow2" size="10" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" v-if="isShow" v-show="show">
|
<div class="content mini-scrollbar" v-if="isShow" v-show="show">
|
||||||
<!-- <basic-info :object="activeObject" /> -->
|
<basic-info :object="activeObject" />
|
||||||
<fill-repeat :object="activeObject" v-if="isRepeat" />
|
<fill-repeat :object="activeObject" v-if="isRepeat" />
|
||||||
<shape-setting :object="activeObject" v-if="isShape && !isRepeat" />
|
<shape-setting :object="activeObject" v-if="isShape && !isRepeat" />
|
||||||
</div>
|
</div>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, inject, computed, watch, onMounted } from 'vue'
|
import { ref, inject, computed, watch, onMounted } from 'vue'
|
||||||
|
import BasicInfo from './basic-info.vue'
|
||||||
import FillRepeat from './fill-repeat.vue'
|
import FillRepeat from './fill-repeat.vue'
|
||||||
import ShapeSetting from './shape-setting.vue'
|
import ShapeSetting from './shape-setting.vue'
|
||||||
const props = defineProps({})
|
const props = defineProps({})
|
||||||
@@ -27,10 +28,11 @@
|
|||||||
const layers = computed(() => layerManager.layers.value)
|
const layers = computed(() => layerManager.layers.value)
|
||||||
const activeObject = ref(null)
|
const activeObject = ref(null)
|
||||||
|
|
||||||
const shapes = ['rect', 'line', 'path', 'triangle', 'polygon', 'ellipse']
|
const shapes = ['rect', 'path', 'triangle', 'polygon', 'ellipse']
|
||||||
|
const isImage = computed(() => activeObject.value?.type === 'image')
|
||||||
const isShape = computed(() => shapes.includes(activeObject.value?.type))
|
const isShape = computed(() => shapes.includes(activeObject.value?.type))
|
||||||
const isRepeat = computed(() => activeObject.value?.fill?.repeat === 'repeat')
|
const isRepeat = computed(() => activeObject.value?.fill?.repeat === 'repeat')
|
||||||
const isShow = computed(() => isRepeat.value || isShape.value)
|
const isShow = computed(() => isImage.value || isRepeat.value || isShape.value)
|
||||||
|
|
||||||
const updateActiveObject = () => {
|
const updateActiveObject = () => {
|
||||||
const layer = layerManager.getActiveLayer()
|
const layer = layerManager.getActiveLayer()
|
||||||
@@ -49,7 +51,7 @@
|
|||||||
top: 2.2rem;
|
top: 2.2rem;
|
||||||
right: 3rem;
|
right: 3rem;
|
||||||
width: 28.8rem;
|
width: 28.8rem;
|
||||||
max-height: 80%;
|
max-height: 90%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.6rem;
|
gap: 1.6rem;
|
||||||
@@ -87,6 +89,12 @@
|
|||||||
padding: 1.6rem;
|
padding: 1.6rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
> * {
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
&:deep(> div) {
|
&:deep(> div) {
|
||||||
> div {
|
> div {
|
||||||
margin-bottom: var(--details-item-margin-bottom, 1.6rem);
|
margin-bottom: var(--details-item-margin-bottom, 1.6rem);
|
||||||
|
|||||||
@@ -1,79 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="shape-setting h">
|
<div class="shape-setting h">
|
||||||
<div>
|
<div>
|
||||||
<div class="title">Position</div>
|
<div class="title">{{ $t('DepthCanvas.appearance') }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<depth-input
|
<span class="label">{{ $t('DepthCanvas.opacity') }}</span>
|
||||||
before="X"
|
|
||||||
type="number"
|
|
||||||
v-model="data.left"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<depth-input
|
|
||||||
before="Y"
|
|
||||||
type="number"
|
|
||||||
v-model="data.top"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div>
|
|
||||||
<depth-input
|
|
||||||
before="W"
|
|
||||||
type="number"
|
|
||||||
v-model="data.width"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<depth-input
|
|
||||||
before="H"
|
|
||||||
type="number"
|
|
||||||
v-model="data.height"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="title">Scale</div>
|
|
||||||
<div class="content">
|
|
||||||
<div>
|
|
||||||
<depth-input
|
|
||||||
type="number"
|
|
||||||
before="X"
|
|
||||||
after="%"
|
|
||||||
v-model="data.scaleX"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<depth-input
|
|
||||||
type="number"
|
|
||||||
before="Y"
|
|
||||||
after="%"
|
|
||||||
v-model="data.scaleY"
|
|
||||||
@input="onInpot"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="title">Appearance</div>
|
|
||||||
<div class="content">
|
|
||||||
<div>
|
|
||||||
<span class="label">Opacity</span>
|
|
||||||
<depth-input
|
<depth-input
|
||||||
type="number"
|
type="number"
|
||||||
after="%"
|
after="%"
|
||||||
@@ -86,7 +17,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="object.type === 'rect'">
|
<div v-if="object.type === 'rect'">
|
||||||
<span class="label">Corner Radius</span>
|
<span class="label">{{ $t('DepthCanvas.cornerRadius') }}</span>
|
||||||
<depth-input
|
<depth-input
|
||||||
type="number"
|
type="number"
|
||||||
v-model="data.radius"
|
v-model="data.radius"
|
||||||
@@ -96,12 +27,32 @@
|
|||||||
@change="onChange"
|
@change="onChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="object.type === 'path'">
|
||||||
|
<span class="label">{{ $t('DepthCanvas.strokeWidth') }}</span>
|
||||||
|
<depth-input
|
||||||
|
type="number"
|
||||||
|
v-model="data.strokeWidth"
|
||||||
|
min="0"
|
||||||
|
step="1"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div v-else></div>
|
<div v-else></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<span class="label">Color</span>
|
<span class="label">{{ $t('DepthCanvas.color') }}</span>
|
||||||
<depth-input
|
<depth-input
|
||||||
|
v-if="object.type === 'path'"
|
||||||
|
type="color"
|
||||||
|
v-model="data.stroke"
|
||||||
|
after="%"
|
||||||
|
@input="onInpot"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
<depth-input
|
||||||
|
v-else
|
||||||
type="color"
|
type="color"
|
||||||
v-model="data.fill"
|
v-model="data.fill"
|
||||||
after="%"
|
after="%"
|
||||||
@@ -116,10 +67,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, inject, computed, nextTick, onBeforeUnmount, reactive, watch } from 'vue'
|
import { ref, inject, computed, nextTick, onBeforeUnmount, reactive, watch } from 'vue'
|
||||||
import { ElColorPicker } from 'element-plus'
|
|
||||||
import { getTransformScaleAngle } from '../../manager/ObjectManager'
|
|
||||||
import DepthOffsetTool from '../tools/depth-offset-tool.vue'
|
|
||||||
import DepthSlider from '../tools/depth-slider.vue'
|
|
||||||
import DepthInput from '../tools/depth-input.vue'
|
import DepthInput from '../tools/depth-input.vue'
|
||||||
const objectManager = inject('objectManager') as any
|
const objectManager = inject('objectManager') as any
|
||||||
const stateManager = inject('stateManager') as any
|
const stateManager = inject('stateManager') as any
|
||||||
@@ -132,32 +79,20 @@
|
|||||||
const id = computed(() => props.object.info.id)
|
const id = computed(() => props.object.info.id)
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
scaleX: 1,
|
|
||||||
scaleY: 1,
|
|
||||||
opacity: 100,
|
opacity: 100,
|
||||||
radius: 0,
|
radius: 0,
|
||||||
|
|
||||||
fill: ''
|
fill: '',
|
||||||
// stroke: '',
|
stroke: '',
|
||||||
// strokeWidth: 0
|
strokeWidth: 0
|
||||||
})
|
})
|
||||||
const updateData = async () => {
|
const updateData = async () => {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
data.top = Math.round(props.object.top)
|
|
||||||
data.left = Math.round(props.object.left)
|
|
||||||
data.width = Math.round(props.object.width)
|
|
||||||
data.height = Math.round(props.object.height)
|
|
||||||
data.scaleX = Math.round(props.object.scaleX * 100)
|
|
||||||
data.scaleY = Math.round(props.object.scaleY * 100)
|
|
||||||
data.opacity = Math.round(props.object.opacity * 100)
|
data.opacity = Math.round(props.object.opacity * 100)
|
||||||
data.radius = Math.round(props.object.rx)
|
data.radius = Math.round(props.object.rx)
|
||||||
data.fill = props.object.fill
|
data.fill = props.object.fill
|
||||||
// data.stroke = props.object.stroke
|
data.stroke = props.object.stroke
|
||||||
// data.strokeWidth = props.object.strokeWidth
|
data.strokeWidth = props.object.strokeWidth
|
||||||
}
|
}
|
||||||
updateData()
|
updateData()
|
||||||
watch(() => props.object, updateData)
|
watch(() => props.object, updateData)
|
||||||
@@ -167,14 +102,16 @@
|
|||||||
const setPriority = (isRecord: boolean) => {
|
const setPriority = (isRecord: boolean) => {
|
||||||
const options = {
|
const options = {
|
||||||
...data,
|
...data,
|
||||||
opacity: data.opacity / 100,
|
opacity: data.opacity / 100
|
||||||
scaleX: data.scaleX / 100,
|
|
||||||
scaleY: data.scaleY / 100
|
|
||||||
}
|
}
|
||||||
if (props.object.type === 'rect') {
|
if (props.object.type === 'rect') {
|
||||||
options['rx'] = data.radius
|
options['rx'] = data.radius
|
||||||
options['ry'] = data.radius
|
options['ry'] = data.radius
|
||||||
}
|
}
|
||||||
|
if (props.object.type !== 'path') {
|
||||||
|
delete options.stroke
|
||||||
|
delete options.strokeWidth
|
||||||
|
}
|
||||||
delete options.radius
|
delete options.radius
|
||||||
objectManager.updateProperty(id.value, options, isRecord)
|
objectManager.updateProperty(id.value, options, isRecord)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
width: 0;
|
width: 0;
|
||||||
top: 2.2rem;
|
top: 2.2rem;
|
||||||
left: 3rem;
|
left: 3rem;
|
||||||
max-height: 80%;
|
max-height: 90%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.6rem;
|
gap: 1.6rem;
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span class="icon"><svg-icon name="dc-layer" size="16" /></span>
|
<span class="icon"><svg-icon name="dc-layer" size="16" /></span>
|
||||||
<span class="title">Layer</span>
|
<span class="title">{{ $t('DepthCanvas.layer') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span class="icon" @click="addLayer"><svg-icon name="add" size="14" /></span>
|
<span class="icon" @click="addLayer"><svg-icon name="add" size="14" /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content mini-scrollbar">
|
||||||
<VueDraggable
|
<VueDraggable
|
||||||
:model-value="list"
|
:model-value="list"
|
||||||
@start="(e) => handleDragStart(e)"
|
@start="(e) => handleDragStart(e)"
|
||||||
@@ -173,13 +173,6 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
min-height: 20rem;
|
min-height: 20rem;
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 4px;
|
|
||||||
}
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 4px;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sortable-layers-child {
|
.sortable-layers-child {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="depth-input" :class="{ color: isColor }">
|
<div class="depth-input" :class="{ color: isColor }">
|
||||||
<span class="decorate"></span>
|
<span class="decorate"></span>
|
||||||
<span v-show="icon" class="icon">
|
<span v-show="icon" class="icon">
|
||||||
<svg-icon :name="icon" :size="iconSize" size-unit="px" />
|
<svg-icon :name="icon" :size="iconSize" />
|
||||||
</span>
|
</span>
|
||||||
<span v-show="before" class="before">{{ before }}</span>
|
<span v-show="before" class="before">{{ before }}</span>
|
||||||
<input
|
<input
|
||||||
@@ -220,45 +220,45 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid var(--depth-input-border-color, rgba(230, 230, 231, 1));
|
border: 0.1rem solid var(--depth-input-border-color, rgba(230, 230, 231, 1));
|
||||||
border-radius: 2px;
|
border-radius: 0.2rem;
|
||||||
height: var(--depth-input-height, 20px);
|
height: var(--depth-input-height, 2rem);
|
||||||
background-color: var(--depth-input-bg-color, #fff);
|
background-color: var(--depth-input-bg-color, #fff);
|
||||||
padding: 0 4px 0 2px;
|
padding: 0 0.4rem 0 0.2rem;
|
||||||
&.color {
|
&.color {
|
||||||
--depth-input-decorate-margin-right: 10px;
|
--depth-input-decorate-margin-right: 1rem;
|
||||||
--depth-input-input-margin-right: 10px;
|
--depth-input-input-margin-right: 1rem;
|
||||||
--depth-input-input-font-align: left;
|
--depth-input-input-font-align: left;
|
||||||
--depth-input-after-color: rgba(181, 181, 181, 1);
|
--depth-input-after-color: rgba(181, 181, 181, 1);
|
||||||
}
|
}
|
||||||
> .decorate {
|
> .decorate {
|
||||||
width: 2px;
|
width: 0.2rem;
|
||||||
background-color: var(--depth-input-decorate-color, rgba(230, 230, 231, 1));
|
background-color: var(--depth-input-decorate-color, rgba(230, 230, 231, 1));
|
||||||
border-radius: 2px;
|
border-radius: 0.2rem;
|
||||||
height: 75%;
|
height: 75%;
|
||||||
margin-right: var(--depth-input-decorate-margin-right, 4px);
|
margin-right: var(--depth-input-decorate-margin-right, 0.4rem);
|
||||||
}
|
}
|
||||||
> .iconfont {
|
> .iconfont {
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
color: #000;
|
color: #000;
|
||||||
margin-right: 4px;
|
margin-right: 0.4rem;
|
||||||
}
|
}
|
||||||
> .before {
|
> .before {
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
color: #000;
|
color: #000;
|
||||||
margin-right: 4px;
|
margin-right: 0.4rem;
|
||||||
}
|
}
|
||||||
> .after {
|
> .after {
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
color: var(--depth-input-after-color, #000);
|
color: var(--depth-input-after-color, #000);
|
||||||
margin-left: 2px;
|
margin-left: 0.2rem;
|
||||||
}
|
}
|
||||||
> input {
|
> input {
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-right: var(--depth-input-input-margin-right, 0);
|
margin-right: var(--depth-input-input-margin-right, 0rem);
|
||||||
text-align: var(--depth-input-input-font-align, right);
|
text-align: var(--depth-input-input-font-align, right);
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -277,9 +277,9 @@
|
|||||||
}
|
}
|
||||||
&[type='color'] {
|
&[type='color'] {
|
||||||
flex: 0.5;
|
flex: 0.5;
|
||||||
border-radius: 2px;
|
border-radius: 0.2rem;
|
||||||
height: 70%;
|
height: 70%;
|
||||||
border: 1px solid rgb(42, 42, 42);
|
border: 0.1rem solid rgb(42, 42, 42);
|
||||||
display: block;
|
display: block;
|
||||||
&::-webkit-color-swatch-wrapper {
|
&::-webkit-color-swatch-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -152,52 +152,52 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
> * {
|
> * {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-right: 10px;
|
margin-right: 1rem;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
> .dish {
|
> .dish {
|
||||||
width: 115px;
|
width: 11.5rem;
|
||||||
height: 115px;
|
height: 11.5rem;
|
||||||
border: 1px solid #eaeaea;
|
border: 0.1rem solid #eaeaea;
|
||||||
border-radius: 3.4px;
|
border-radius: 0.4rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
margin-top: 20px;
|
margin-top: 2rem;
|
||||||
> * {
|
> * {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
> img {
|
> img {
|
||||||
width: 12px;
|
width: 1.2rem;
|
||||||
height: 12px;
|
height: 1.2rem;
|
||||||
bottom: 3.5px;
|
bottom: 0.35rem;
|
||||||
right: 3.5px;
|
right: 0.35rem;
|
||||||
}
|
}
|
||||||
> .ball {
|
> .ball {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
width: 8.5px;
|
width: 0.85rem;
|
||||||
height: 8.5px;
|
height: 0.85rem;
|
||||||
border: 1px solid #fff;
|
border: 0.1rem solid #fff;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
box-shadow: 0px 0.68px 0.17px 0px rgba(0, 0, 0, 0.26);
|
box-shadow: 9 0.07rem 0.02rem 0 rgba(0, 0, 0, 0.26);
|
||||||
}
|
}
|
||||||
> .tip {
|
> .tip {
|
||||||
font-size: 8.5px;
|
font-size: 0.85rem;
|
||||||
color: #000;
|
color: #000;
|
||||||
line-height: 24px;
|
line-height: 2.4rem;
|
||||||
&.x {
|
&.x {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: 0%;
|
right: 0%;
|
||||||
transform: translate(100%, -50%);
|
transform: translate(100%, -50%);
|
||||||
padding-left: 6px;
|
padding-left: 0.6rem;
|
||||||
}
|
}
|
||||||
&.y {
|
&.y {
|
||||||
top: 0%;
|
top: 0%;
|
||||||
@@ -216,15 +216,15 @@
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
&.x {
|
&.x {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-top-width: 1px;
|
border-top-width: 0.1rem;
|
||||||
}
|
}
|
||||||
&.y {
|
&.y {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-left-width: 1px;
|
border-left-width: 0.1rem;
|
||||||
}
|
}
|
||||||
&.z {
|
&.z {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
border-top-width: 1px;
|
border-top-width: 0.1rem;
|
||||||
border-color: #454754;
|
border-color: #454754;
|
||||||
transform: translate(0%, -50%) rotateZ(var(--rotateZ));
|
transform: translate(0%, -50%) rotateZ(var(--rotateZ));
|
||||||
transform-origin: left center;
|
transform-origin: left center;
|
||||||
|
|||||||
@@ -22,12 +22,12 @@
|
|||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.depth-select {
|
.depth-select {
|
||||||
&:deep(.el-select) {
|
&:deep(.el-select) {
|
||||||
--el-select-input-font-size: 12px;
|
--el-select-input-font-size: 1.2rem;
|
||||||
.el-select__wrapper {
|
.el-select__wrapper {
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
height: 28px;
|
height: 2.8rem;
|
||||||
padding: 0 8px;
|
padding: 0 0.8rem;
|
||||||
}
|
}
|
||||||
.el-select__selected-item,
|
.el-select__selected-item,
|
||||||
.el-select__input-wrapper,
|
.el-select__input-wrapper,
|
||||||
@@ -35,17 +35,17 @@
|
|||||||
line-height: normal;
|
line-height: normal;
|
||||||
}
|
}
|
||||||
.el-select__input {
|
.el-select__input {
|
||||||
height: 24px;
|
height: 2.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-popper {
|
.el-popper {
|
||||||
.el-select-dropdown {
|
.el-select-dropdown {
|
||||||
li {
|
li {
|
||||||
padding-left: 8px;
|
padding-left: 0.8rem;
|
||||||
height: 30px;
|
height: 3rem;
|
||||||
line-height: 30px;
|
line-height: 3rem;
|
||||||
font-size: 12px;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
--input-thumb-size: 1.4rem;
|
--input-thumb-size: 1.2rem;
|
||||||
--backcolor1: var(--depth-slider-thumb-color1, #000);
|
--backcolor1: var(--depth-slider-thumb-color1, #000);
|
||||||
--backcolor2: var(--depth-slider-thumb-color2, #d3d3d3);
|
--backcolor2: var(--depth-slider-thumb-color2, #d3d3d3);
|
||||||
&:hover {
|
&:hover {
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
background: var(--backcolor1); /* 蓝色滑块 */
|
background: var(--backcolor1); /* 蓝色滑块 */
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
&::-webkit-slider-thumb:hover {
|
&::-webkit-slider-thumb:hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
@@ -153,9 +153,9 @@
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-left: 5px solid transparent;
|
border-left: 0.5rem solid transparent;
|
||||||
border-right: 5px solid transparent;
|
border-right: 0.5rem solid transparent;
|
||||||
border-top: 5px solid rgba(0, 0, 0, 0.8);
|
border-top: 0.5rem solid rgba(0, 0, 0, 0.8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export class AISelectboxToolManager {
|
|||||||
if (!oldIsAAA && newIsAAA) {
|
if (!oldIsAAA && newIsAAA) {
|
||||||
// 普通工具切换到智能框选工具
|
// 普通工具切换到智能框选工具
|
||||||
this.init()
|
this.init()
|
||||||
|
this.canvasManager.discardActiveObject()
|
||||||
} else if (oldIsAAA && !newIsAAA) {
|
} else if (oldIsAAA && !newIsAAA) {
|
||||||
// 智能框选工具切换到普通工具
|
// 智能框选工具切换到普通工具
|
||||||
this.clear()
|
this.clear()
|
||||||
@@ -101,6 +102,10 @@ export class AISelectboxToolManager {
|
|||||||
this.canvasManager.canvas.remove(this.indicatorObject)
|
this.canvasManager.canvas.remove(this.indicatorObject)
|
||||||
this.indicatorObject = null
|
this.indicatorObject = null
|
||||||
}
|
}
|
||||||
|
resetDemoObject() {
|
||||||
|
this.clearDemoObject()
|
||||||
|
this.createDemoObject()
|
||||||
|
}
|
||||||
// 创建临时画布对象
|
// 创建临时画布对象
|
||||||
async createStaticCanvas(object: fabric.Object) {
|
async createStaticCanvas(object: fabric.Object) {
|
||||||
if (!this.demoObject) this.createDemoObject()
|
if (!this.demoObject) this.createDemoObject()
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ import { fabric } from 'fabric-with-all'
|
|||||||
import { createId } from '../../tools/tools'
|
import { createId } from '../../tools/tools'
|
||||||
import { exportObjectsToImage, exportObjectToThumbnail } from '../tools/exportMethod'
|
import { exportObjectsToImage, exportObjectToThumbnail } from '../tools/exportMethod'
|
||||||
import { OperationType, BlendMode } from '../tools/layerHelper'
|
import { OperationType, BlendMode } from '../tools/layerHelper'
|
||||||
import { getArrowPath, cloneObjects, getStarArr } from '../tools/canvasMethod'
|
import { getArrowPath, getLinePath, cloneObjects, getStarArr } from '../tools/canvasMethod'
|
||||||
|
import i18n from '@/lang/index'
|
||||||
|
const t = i18n.global.t
|
||||||
|
|
||||||
export class LayerManager {
|
export class LayerManager {
|
||||||
stateManager: any
|
stateManager: any
|
||||||
@@ -206,7 +208,7 @@ export class LayerManager {
|
|||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
info: {
|
info: {
|
||||||
id: createId("image"),
|
id: createId("image"),
|
||||||
name: '空图层',
|
name: t('DepthCanvas.emptyLayer'),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.setLayerPosition(emptyObject)
|
this.setLayerPosition(emptyObject)
|
||||||
@@ -226,7 +228,7 @@ export class LayerManager {
|
|||||||
evented: false,
|
evented: false,
|
||||||
info: {
|
info: {
|
||||||
id: createId("group"),
|
id: createId("group"),
|
||||||
name: '智能选区组',
|
name: t('DepthCanvas.aiGroupLayer'),
|
||||||
showChildren: true,
|
showChildren: true,
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
@@ -245,7 +247,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("text"),
|
id: createId("text"),
|
||||||
name: '文本图层',
|
name: t('DepthCanvas.textLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -263,7 +265,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("rect"),
|
id: createId("rect"),
|
||||||
name: '矩形图层',
|
name: t('DepthCanvas.rectLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -274,25 +276,27 @@ export class LayerManager {
|
|||||||
}
|
}
|
||||||
/** 创建直线图层 */
|
/** 创建直线图层 */
|
||||||
async createLineLayer(options?: any, isRecord = true, isActive = true) {
|
async createLineLayer(options?: any, isRecord = true, isActive = true) {
|
||||||
const line = [options?.x1 || 0, options?.y1 || 0, options?.x2 || 100, options?.y2 || 0]
|
const width = options?.width || 100
|
||||||
delete options.x1
|
const height = options?.height || 2
|
||||||
delete options.y1
|
delete options.width
|
||||||
delete options.x2
|
delete options.height
|
||||||
delete options.y2
|
const arrowObject = new fabric.Path(getLinePath(width, height), {
|
||||||
const lineObject = new fabric.Line(line, {
|
stroke: '#000', // 只设置边框颜色
|
||||||
stroke: 'black', // 线条颜色
|
strokeWidth: 2, // 边框宽度
|
||||||
strokeWidth: 2, // 线条粗细
|
fill: 'transparent', // 不填充
|
||||||
|
strokeLineCap: 'round',
|
||||||
|
strokeLineJoin: 'round',
|
||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("line"),
|
id: createId("line"),
|
||||||
name: '直线图层',
|
name: t('DepthCanvas.lineLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
this.setLayerPosition(lineObject, options)
|
this.setLayerPosition(arrowObject, options)
|
||||||
await this.canvasManager.add(lineObject, isRecord)
|
await this.canvasManager.add(arrowObject, isRecord)
|
||||||
if (isActive) this.setActiveID(lineObject.info.id)
|
if (isActive) this.setActiveID(arrowObject.info.id)
|
||||||
return lineObject
|
return arrowObject
|
||||||
}
|
}
|
||||||
/** 创建椭圆图层 */
|
/** 创建椭圆图层 */
|
||||||
async createEllipseLayer(options?: any, isRecord = true, isActive = true) {
|
async createEllipseLayer(options?: any, isRecord = true, isActive = true) {
|
||||||
@@ -302,7 +306,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("ellipse"),
|
id: createId("ellipse"),
|
||||||
name: '椭圆图层',
|
name: t('DepthCanvas.ellipseLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -321,7 +325,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("triangle"),
|
id: createId("triangle"),
|
||||||
name: '三角形图层',
|
name: t('DepthCanvas.triangleLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -341,7 +345,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("star"),
|
id: createId("star"),
|
||||||
name: '五角星图层',
|
name: t('DepthCanvas.starLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -353,19 +357,19 @@ export class LayerManager {
|
|||||||
/** 创建箭头图层 */
|
/** 创建箭头图层 */
|
||||||
async createArrowLayer(options?: any, isRecord = true, isActive = true) {
|
async createArrowLayer(options?: any, isRecord = true, isActive = true) {
|
||||||
const width = options?.width || 100
|
const width = options?.width || 100
|
||||||
const height = options?.height || 10
|
const strokeWidth = options?.strokeWidth || 4
|
||||||
delete options.width
|
delete options.width
|
||||||
delete options.height
|
delete options.strokeWidth
|
||||||
const arrowObject = new fabric.Path(getArrowPath(width, height), {
|
const arrowObject = new fabric.Path(getArrowPath(width, strokeWidth), {
|
||||||
stroke: '#000', // 只设置边框颜色
|
stroke: '#000', // 只设置边框颜色
|
||||||
strokeWidth: 3, // 边框宽度
|
strokeWidth, // 边框宽度
|
||||||
fill: 'transparent', // 不填充
|
fill: 'transparent', // 不填充
|
||||||
strokeLineCap: 'round',
|
strokeLineCap: 'round',
|
||||||
strokeLineJoin: 'round',
|
strokeLineJoin: 'round',
|
||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("star"),
|
id: createId("arrow"),
|
||||||
name: '箭头图层',
|
name: t('DepthCanvas.arrowLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -395,7 +399,7 @@ export class LayerManager {
|
|||||||
...(options || {}),
|
...(options || {}),
|
||||||
info: {
|
info: {
|
||||||
id: createId("image"),
|
id: createId("image"),
|
||||||
name: "图片图层",
|
name: t('DepthCanvas.imageLayer'),
|
||||||
...(options?.info || {}),
|
...(options?.info || {}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -419,7 +423,7 @@ export class LayerManager {
|
|||||||
info: {
|
info: {
|
||||||
...(targetLayer?.info || {}),
|
...(targetLayer?.info || {}),
|
||||||
id: createId("image"),
|
id: createId("image"),
|
||||||
name: targetLayer?.info?.name || "合并图层",
|
name: targetLayer?.info?.name || t('DepthCanvas.mergeLayer'),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
resolve(img)
|
resolve(img)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { OperationType, OperationTypes } from "../tools/layerHelper";
|
import { OperationType, OperationTypes } from "../tools/layerHelper";
|
||||||
import { getStarArr, getArrowPath, distance, angleBetweenPointsDegrees } from "../tools/canvasMethod";
|
import { getStarArr, getArrowPath, getLinePath, distance, angleBetweenPointsDegrees } from "../tools/canvasMethod";
|
||||||
import { fabric } from 'fabric-with-all'
|
import { fabric } from 'fabric-with-all'
|
||||||
/** 形状管理器 */
|
/** 形状管理器 */
|
||||||
export class ShapeToolManager {
|
export class ShapeToolManager {
|
||||||
@@ -136,22 +136,47 @@ export class ShapeToolManager {
|
|||||||
|
|
||||||
/** 绘制直线 */
|
/** 绘制直线 */
|
||||||
downLine() {
|
downLine() {
|
||||||
const line = new fabric.Line([this.startX, this.startY, this.startX, this.startY], {
|
// const line = new fabric.Line([this.startX, this.startY, this.startX, this.startY], {
|
||||||
stroke: 'black', // 线条颜色
|
// stroke: 'black', // 线条颜色
|
||||||
strokeWidth: 2 // 线条粗细
|
// strokeWidth: 2 // 线条粗细
|
||||||
})
|
// })
|
||||||
return line
|
// return line
|
||||||
|
return new fabric.Path();
|
||||||
}
|
}
|
||||||
moveLine({ x, y }) {
|
moveLine({ x, y }) {
|
||||||
this.demoObject.set({
|
// this.demoObject.set({
|
||||||
x1: this.startX,
|
// x1: this.startX,
|
||||||
y1: this.startY,
|
// y1: this.startY,
|
||||||
x2: x,
|
// x2: x,
|
||||||
y2: y,
|
// y2: y,
|
||||||
})
|
// })
|
||||||
|
const width = distance(this.startX, this.startY, x, y)
|
||||||
|
const angle = angleBetweenPointsDegrees(this.startX, this.startY, x, y)
|
||||||
|
this.canvasManager.canvas.remove(this.demoObject)
|
||||||
|
const arrow = new fabric.Path(getLinePath(width, 2), {
|
||||||
|
left: this.startX,
|
||||||
|
top: this.startY,
|
||||||
|
stroke: '#000', // 只设置边框颜色
|
||||||
|
strokeWidth: 2, // 边框宽度
|
||||||
|
fill: 'transparent', // 不填充
|
||||||
|
strokeLineCap: 'round',
|
||||||
|
strokeLineJoin: 'round',
|
||||||
|
originY: 'center',
|
||||||
|
angle: angle,
|
||||||
|
});
|
||||||
|
this.canvasManager.canvas.add(arrow)
|
||||||
|
this.demoObject = arrow
|
||||||
}
|
}
|
||||||
upLine(object) {
|
upLine(object) {
|
||||||
this.layerManager.createLineLayer(object)
|
if (object.originY !== "center") {
|
||||||
|
this.layerManager.createLineLayer({
|
||||||
|
left: this.startX,
|
||||||
|
top: this.startY,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.layerManager.createLineLayer(object)
|
||||||
|
}
|
||||||
|
// this.layerManager.createLineLayer(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 绘制椭圆 */
|
/** 绘制椭圆 */
|
||||||
@@ -228,11 +253,11 @@ export class ShapeToolManager {
|
|||||||
const width = distance(this.startX, this.startY, x, y)
|
const width = distance(this.startX, this.startY, x, y)
|
||||||
const angle = angleBetweenPointsDegrees(this.startX, this.startY, x, y)
|
const angle = angleBetweenPointsDegrees(this.startX, this.startY, x, y)
|
||||||
this.canvasManager.canvas.remove(this.demoObject)
|
this.canvasManager.canvas.remove(this.demoObject)
|
||||||
const arrow = new fabric.Path(getArrowPath(width, 10), {
|
const arrow = new fabric.Path(getArrowPath(width, 4), {
|
||||||
left: this.startX,
|
left: this.startX,
|
||||||
top: this.startY,
|
top: this.startY,
|
||||||
stroke: '#000', // 只设置边框颜色
|
stroke: '#000', // 只设置边框颜色
|
||||||
strokeWidth: 3, // 边框宽度
|
strokeWidth: 4, // 边框宽度
|
||||||
fill: 'transparent', // 不填充
|
fill: 'transparent', // 不填充
|
||||||
strokeLineCap: 'round',
|
strokeLineCap: 'round',
|
||||||
strokeLineJoin: 'round',
|
strokeLineJoin: 'round',
|
||||||
@@ -247,7 +272,7 @@ export class ShapeToolManager {
|
|||||||
this.layerManager.createArrowLayer({
|
this.layerManager.createArrowLayer({
|
||||||
left: this.startX,
|
left: this.startX,
|
||||||
top: this.startY,
|
top: this.startY,
|
||||||
}, true)
|
})
|
||||||
} else {
|
} else {
|
||||||
this.layerManager.createArrowLayer(object)
|
this.layerManager.createArrowLayer(object)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ export class StateManager {
|
|||||||
/** 记录状态 */
|
/** 记录状态 */
|
||||||
recordState() {
|
recordState() {
|
||||||
if (this.running.value) return
|
if (this.running.value) return
|
||||||
console.log("recordState")
|
|
||||||
this.running.value = true
|
this.running.value = true
|
||||||
if (this.historyIndex.value < this.historyList.value.length - 1) {
|
if (this.historyIndex.value < this.historyList.value.length - 1) {
|
||||||
this.historyList.value.splice(this.historyIndex.value + 1)
|
this.historyList.value.splice(this.historyIndex.value + 1)
|
||||||
|
|||||||
@@ -61,13 +61,26 @@ export function getStarArr(width = 0, height = 0) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
/** 获取箭头路径 */
|
/** 获取箭头路径 */
|
||||||
export function getArrowPath(width = 0, height = 0) {
|
export function getArrowPath(width = 0, strokeWidth = 4) {
|
||||||
|
const height = strokeWidth * 4
|
||||||
const arr = [
|
const arr = [
|
||||||
["M", 0, height / 2],
|
["M", 0, height / 2],
|
||||||
["L", width, height / 2],
|
["L", width, height / 2],
|
||||||
["M", width - 8, 0],
|
["M", width - height, 0],
|
||||||
|
["L", width, height / 2],
|
||||||
|
["L", width - height, height],
|
||||||
|
]
|
||||||
|
var path = ""
|
||||||
|
arr.forEach(item => {
|
||||||
|
path += item.join(" ") + " "
|
||||||
|
})
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
/** 获取直线路径 */
|
||||||
|
export function getLinePath(width = 0, height = 0) {
|
||||||
|
const arr = [
|
||||||
|
["M", 0, height / 2],
|
||||||
["L", width, height / 2],
|
["L", width, height / 2],
|
||||||
["L", width - 8, height],
|
|
||||||
]
|
]
|
||||||
var path = ""
|
var path = ""
|
||||||
arr.forEach(item => {
|
arr.forEach(item => {
|
||||||
|
|||||||
@@ -200,5 +200,47 @@ export default {
|
|||||||
threeModel: {
|
threeModel: {
|
||||||
loading: 'Loading',
|
loading: 'Loading',
|
||||||
download: 'Download'
|
download: 'Download'
|
||||||
|
},
|
||||||
|
DepthCanvas: {
|
||||||
|
layer: "Layer",
|
||||||
|
editDetails: "Edit Details",
|
||||||
|
export: "Export",
|
||||||
|
save: "Save",
|
||||||
|
workbench: "Workbench",
|
||||||
|
position: "Position",
|
||||||
|
size: "Size",
|
||||||
|
appearance: "Appearance",
|
||||||
|
opacity: "Opacity",
|
||||||
|
cornerRadius: "Cor Radius",
|
||||||
|
strokeWidth: "Stroke Width",
|
||||||
|
color: "Color",
|
||||||
|
image: "Image",
|
||||||
|
settings: "Settings",
|
||||||
|
rotation: "Rotation",
|
||||||
|
scale: "Scale",
|
||||||
|
gapX: "Gap X",
|
||||||
|
gapY: "Gap Y",
|
||||||
|
offset: "Offset",
|
||||||
|
emptyLayer: "Empty Layer",
|
||||||
|
aiGroupLayer: "AI Group Layer",
|
||||||
|
textLayer: "Text Layer",
|
||||||
|
rectLayer: "Rect Layer",
|
||||||
|
lineLayer: "Line Layer",
|
||||||
|
ellipseLayer: "Ellipse Layer",
|
||||||
|
triangleLayer: "Triangle Layer",
|
||||||
|
starLayer: "Star Layer",
|
||||||
|
arrowLayer: "Arrow Layer",
|
||||||
|
imageLayer: "Image Layer",
|
||||||
|
mergeLayer: "Merge Layer",
|
||||||
|
rectangle: "Rectangle",
|
||||||
|
line: "Line",
|
||||||
|
arrow: "Arrow",
|
||||||
|
ellipse: "Ellipse",
|
||||||
|
triangle: "Triangle",
|
||||||
|
star: "Star",
|
||||||
|
add: "Add",
|
||||||
|
remove: "Remove",
|
||||||
|
brush: "Brush",
|
||||||
|
erase: "Erase",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ export default {
|
|||||||
quote: '引用',
|
quote: '引用',
|
||||||
delete: '删除',
|
delete: '删除',
|
||||||
edit: '编辑',
|
edit: '编辑',
|
||||||
generatingReport:'正在为您生成报告,可能需要几分钟时间,生成期间你可以继续进行其他任务'
|
generatingReport: '正在为您生成报告,可能需要几分钟时间,生成期间你可以继续进行其他任务'
|
||||||
},
|
},
|
||||||
|
|
||||||
// Version Tree
|
// Version Tree
|
||||||
@@ -197,5 +197,47 @@ export default {
|
|||||||
threeModel: {
|
threeModel: {
|
||||||
loading: '加载中',
|
loading: '加载中',
|
||||||
download: '下载'
|
download: '下载'
|
||||||
|
},
|
||||||
|
DepthCanvas: {
|
||||||
|
layer: "图层",
|
||||||
|
editDetails: "编辑详情",
|
||||||
|
export: "导出",
|
||||||
|
save: "保存",
|
||||||
|
workbench: "工作台",
|
||||||
|
position: "位置",
|
||||||
|
size: "大小",
|
||||||
|
appearance: "外观",
|
||||||
|
opacity: "透明度",
|
||||||
|
cornerRadius: "圆角半径",
|
||||||
|
strokeWidth: "边框宽度",
|
||||||
|
color: "颜色",
|
||||||
|
image: "图片",
|
||||||
|
settings: "设置",
|
||||||
|
rotation: "旋转角度",
|
||||||
|
scale: "缩放",
|
||||||
|
gapX: "水平间距",
|
||||||
|
gapY: "垂直间距",
|
||||||
|
offset: "偏移量",
|
||||||
|
emptyLayer: "空图层",
|
||||||
|
aiGroupLayer: "智能选区组",
|
||||||
|
textLayer: "文本图层",
|
||||||
|
rectLayer: "矩形图层",
|
||||||
|
lineLayer: "直线图层",
|
||||||
|
ellipseLayer: "椭圆图层",
|
||||||
|
triangleLayer: "三角形图层",
|
||||||
|
starLayer: "五角星图层",
|
||||||
|
arrowLayer: "箭头图层",
|
||||||
|
imageLayer: "图片图层",
|
||||||
|
mergeLayer: "合并图层",
|
||||||
|
rectangle: "矩形",
|
||||||
|
line: "直线",
|
||||||
|
arrow: "箭头",
|
||||||
|
ellipse: "椭圆",
|
||||||
|
triangle: "三角形",
|
||||||
|
star: "五角星",
|
||||||
|
add: "添加",
|
||||||
|
remove: "删除",
|
||||||
|
brush: "画笔",
|
||||||
|
erase: "擦除",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
><svg-icon name="arrow-right" size="14" />
|
><svg-icon name="arrow-right" size="14" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="history-list" v-show="!isCollapse && showHistory">
|
<div class="history-list mini-scrollbar" v-show="!isCollapse && showHistory">
|
||||||
<div v-for="item in list" :key="item.name" class="history-item">
|
<div v-for="item in list" :key="item.name" class="history-item">
|
||||||
<div v-if="item.title" class="title">{{ item.name }}</div>
|
<div v-if="item.title" class="title">{{ item.name }}</div>
|
||||||
<div
|
<div
|
||||||
@@ -307,7 +307,8 @@
|
|||||||
> .history-list {
|
> .history-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
width: 23.2rem;
|
width: 26.4rem;
|
||||||
|
padding: 0 1.5rem;
|
||||||
margin: 1rem auto 0;
|
margin: 1rem auto 0;
|
||||||
> .history-item {
|
> .history-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user