This commit is contained in:
commit
6c2ac44b33
|
|
@ -12,6 +12,7 @@ export {}
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AIgenerate: typeof import('./src/components/AIgenerate/AIgenerate.vue')['default']
|
AIgenerate: typeof import('./src/components/AIgenerate/AIgenerate.vue')['default']
|
||||||
|
Canvas: typeof import('./src/components/canvas/index.vue')['default']
|
||||||
Collection: typeof import('./src/components/collection/index.vue')['default']
|
Collection: typeof import('./src/components/collection/index.vue')['default']
|
||||||
copy: typeof import('./src/components/ModelDescription copy.vue')['default']
|
copy: typeof import('./src/components/ModelDescription copy.vue')['default']
|
||||||
DeepseekPopover: typeof import('./src/components/AIgenerate/DeepseekPopover.vue')['default']
|
DeepseekPopover: typeof import('./src/components/AIgenerate/DeepseekPopover.vue')['default']
|
||||||
|
|
@ -24,6 +25,7 @@ declare module 'vue' {
|
||||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
|
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,510 @@
|
||||||
|
<template>
|
||||||
|
<Teleport to="body">
|
||||||
|
<div v-if="visible" class="canvas-modal">
|
||||||
|
<div class="canvas-container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="preview-area">
|
||||||
|
<span class="preview-text">图片预览</span>
|
||||||
|
</div>
|
||||||
|
<div class="close-btn" @click="handleClose">
|
||||||
|
<svg viewBox="0 0 1024 1024" width="24" height="24">
|
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66 0.3L512 563.4l-99.3 119-66.1-0.3c-4.4 0-8-3.6-8-8 0-1.9 0.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1 0.3L512 464.6l99.3-118.4 66-0.3c4.4 0 8 3.6 8 8 0 1.9-0.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="canvas-area">
|
||||||
|
<canvas
|
||||||
|
ref="canvasRef"
|
||||||
|
@mousedown="handleMouseDown"
|
||||||
|
@mousemove="handleMouseMove"
|
||||||
|
@mouseup="handleMouseUp"
|
||||||
|
@mouseleave="handleMouseUp"
|
||||||
|
></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<div class="input-area">
|
||||||
|
<el-input
|
||||||
|
v-model="inputText"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入描述..."
|
||||||
|
resize="none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="control-area">
|
||||||
|
<div class="shape-selector">
|
||||||
|
<div
|
||||||
|
class="shape-btn"
|
||||||
|
:class="{ active: currentShape === 'rectangle' }"
|
||||||
|
@click="currentShape = 'rectangle'"
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
||||||
|
<path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H184V184h656v656z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
<span>矩形</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="shape-btn"
|
||||||
|
:class="{ active: currentShape === 'circle' }"
|
||||||
|
@click="currentShape = 'circle'"
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
||||||
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
<span>圆形</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="action-btns">
|
||||||
|
<div class="shape-btn" @click="undo">
|
||||||
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
||||||
|
<path d="M384 512c0-70.7 57.3-128 128-128s128 57.3 128 128v192h-64v-192c0-35.3-28.7-64-64-64s-64 28.7-64 64v192h-64v-192z" fill="#333"/>
|
||||||
|
<path d="M704 256H192c-35.3 0-64 28.7-64 64v256c0 35.3 28.7 64 64 64h512c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64z m0 320H192V320h512v256z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
<span>上一步</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="shape-btn" @click="redo">
|
||||||
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
||||||
|
<path d="M640 512c0 70.7-57.3 128-128 128s-128-57.3-128-128v-192h64v192c0 35.3 28.7 64 64 64s64-28.7 64-64v-192h64v192z" fill="#333"/>
|
||||||
|
<path d="M320 256H832c35.3 0 64 28.7 64 64v256c0 35.3-28.7 64-64 64H320c-35.3 0-64-28.7-64-64V320c0-35.3 28.7-64 64-64z m0 320V320h512v256H320z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
<span>下一步</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="shape-btn" @click="deleteShape">
|
||||||
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
||||||
|
<path d="M416 256h192v512H416V256z m128 640h-64v-448h64v448z m-192 0h-64v-448h64v448z m384-640v512h-192V256h192z m-128 640h-64v-448h64v448z" fill="#333"/>
|
||||||
|
<path d="M864 192H640v-64c0-35.2-28.8-64-64-64H448c-35.2 0-64 28.8-64 64v64H160c-35.2 0-64 28.8-64 64v32h768v-32c0-35.2-28.8-64-64-64z" fill="#333"/>
|
||||||
|
</svg>
|
||||||
|
<span>删除</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="handleSend">发送</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, nextTick } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:visible', 'send'])
|
||||||
|
|
||||||
|
const canvasRef = ref(null)
|
||||||
|
const currentImage = ref('')
|
||||||
|
const bgImage = ref(null)
|
||||||
|
const scale = ref(1)
|
||||||
|
const inputText = ref('')
|
||||||
|
const currentShape = ref('rectangle')
|
||||||
|
const isDrawing = ref(false)
|
||||||
|
const startX = ref(0)
|
||||||
|
const startY = ref(0)
|
||||||
|
const shapes = ref([])
|
||||||
|
const history = ref([])
|
||||||
|
const historyIndex = ref(-1)
|
||||||
|
const shapeColors = ['#ff0000', '#ff7f00', '#00ff00', '#0000ff', '#8b00ff']
|
||||||
|
const maxShapes = 5
|
||||||
|
|
||||||
|
watch(() => props.visible, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
currentImage.value = props.image
|
||||||
|
bgImage.value = null
|
||||||
|
history.value = []
|
||||||
|
historyIndex.value = -1
|
||||||
|
nextTick(() => {
|
||||||
|
initCanvas()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const initCanvas = () => {
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
const container = canvas.parentElement
|
||||||
|
const containerWidth = container.clientWidth
|
||||||
|
const containerHeight = container.clientHeight
|
||||||
|
|
||||||
|
if (currentImage.value) {
|
||||||
|
if (currentImage.value.startsWith('data:')) {
|
||||||
|
const img = new Image()
|
||||||
|
img.onload = () => {
|
||||||
|
const imgScale = Math.min(containerWidth / img.width, containerHeight / img.height)
|
||||||
|
canvas.width = img.width
|
||||||
|
canvas.height = img.height
|
||||||
|
ctx.drawImage(img, 0, 0)
|
||||||
|
bgImage.value = img
|
||||||
|
scale.value = imgScale
|
||||||
|
}
|
||||||
|
img.src = currentImage.value
|
||||||
|
} else {
|
||||||
|
fetch(currentImage.value)
|
||||||
|
.then(res => res.blob())
|
||||||
|
.then(blob => {
|
||||||
|
const img = new Image()
|
||||||
|
img.onload = () => {
|
||||||
|
const imgScale = Math.min(containerWidth / img.width, containerHeight / img.height)
|
||||||
|
canvas.width = img.width
|
||||||
|
canvas.height = img.height
|
||||||
|
ctx.drawImage(img, 0, 0)
|
||||||
|
bgImage.value = img
|
||||||
|
scale.value = imgScale
|
||||||
|
}
|
||||||
|
img.src = URL.createObjectURL(blob)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage.error('图片加载失败')
|
||||||
|
canvas.width = containerWidth
|
||||||
|
canvas.height = containerHeight
|
||||||
|
ctx.fillStyle = '#f5f5f5'
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||||
|
ctx.fillStyle = '#999'
|
||||||
|
ctx.font = '20px Microsoft YaHei'
|
||||||
|
ctx.textAlign = 'center'
|
||||||
|
ctx.fillText('图片加载失败', canvas.width / 2, canvas.height / 2)
|
||||||
|
scale.value = 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
canvas.width = containerWidth
|
||||||
|
canvas.height = containerHeight
|
||||||
|
ctx.fillStyle = '#fff'
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||||
|
scale.value = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMouseDown = (e) => {
|
||||||
|
if (shapes.value.length >= maxShapes) {
|
||||||
|
ElMessage.warning('最多只能画5笔')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isDrawing.value = true
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
const ratio = canvas.width / canvas.offsetWidth
|
||||||
|
startX.value = e.offsetX * ratio
|
||||||
|
startY.value = e.offsetY * ratio
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMouseMove = (e) => {
|
||||||
|
if (!isDrawing.value) return
|
||||||
|
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
const ratio = canvas.width / canvas.offsetWidth
|
||||||
|
const currentX = e.offsetX * ratio
|
||||||
|
const currentY = e.offsetY * ratio
|
||||||
|
const savedStartX = startX.value
|
||||||
|
const savedStartY = startY.value
|
||||||
|
const savedCurrentX = currentX
|
||||||
|
const savedCurrentY = currentY
|
||||||
|
|
||||||
|
if (bgImage.value) {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
ctx.drawImage(bgImage.value, 0, 0)
|
||||||
|
|
||||||
|
shapes.value.forEach(shape => {
|
||||||
|
drawShape(ctx, shape)
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentShapeData = {
|
||||||
|
type: currentShape.value,
|
||||||
|
startX: savedStartX,
|
||||||
|
startY: savedStartY,
|
||||||
|
endX: savedCurrentX,
|
||||||
|
endY: savedCurrentY,
|
||||||
|
color: shapeColors[shapes.value.length] || '#ff0000'
|
||||||
|
}
|
||||||
|
drawShape(ctx, currentShapeData)
|
||||||
|
} else {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
ctx.fillStyle = '#fff'
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||||
|
|
||||||
|
shapes.value.forEach(shape => {
|
||||||
|
drawShape(ctx, shape)
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentShapeData = {
|
||||||
|
type: currentShape.value,
|
||||||
|
startX: startX.value,
|
||||||
|
startY: startY.value,
|
||||||
|
endX: currentX,
|
||||||
|
endY: currentY,
|
||||||
|
color: shapeColors[shapes.value.length] || '#ff0000'
|
||||||
|
}
|
||||||
|
drawShape(ctx, currentShapeData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMouseUp = (e) => {
|
||||||
|
if (!isDrawing.value) return
|
||||||
|
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
const ratio = canvas.width / canvas.offsetWidth
|
||||||
|
const endX = e.offsetX * ratio
|
||||||
|
const endY = e.offsetY * ratio
|
||||||
|
|
||||||
|
if (shapes.value.length >= maxShapes) {
|
||||||
|
ElMessage.warning('最多只能画5笔')
|
||||||
|
isDrawing.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorIndex = shapes.value.length
|
||||||
|
shapes.value.push({
|
||||||
|
type: currentShape.value,
|
||||||
|
startX: startX.value,
|
||||||
|
startY: startY.value,
|
||||||
|
endX: endX,
|
||||||
|
endY: endY,
|
||||||
|
color: shapeColors[colorIndex]
|
||||||
|
})
|
||||||
|
|
||||||
|
saveHistory()
|
||||||
|
isDrawing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveHistory = () => {
|
||||||
|
history.value = history.value.slice(0, historyIndex.value + 1)
|
||||||
|
history.value.push([...shapes.value])
|
||||||
|
historyIndex.value = history.value.length - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const undo = () => {
|
||||||
|
if (historyIndex.value >= 0) {
|
||||||
|
const newIndex = historyIndex.value - 1
|
||||||
|
historyIndex.value = newIndex
|
||||||
|
shapes.value = newIndex >= 0 ? [...history.value[newIndex]] : []
|
||||||
|
redrawCanvas()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const redo = () => {
|
||||||
|
if (historyIndex.value < history.value.length - 1) {
|
||||||
|
historyIndex.value++
|
||||||
|
shapes.value = [...history.value[historyIndex.value]]
|
||||||
|
redrawCanvas()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteShape = () => {
|
||||||
|
shapes.value = []
|
||||||
|
saveHistory()
|
||||||
|
redrawCanvas()
|
||||||
|
}
|
||||||
|
|
||||||
|
const redrawCanvas = () => {
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
if (!canvas) return
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
|
||||||
|
if (bgImage.value) {
|
||||||
|
ctx.drawImage(bgImage.value, 0, 0)
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = '#fff'
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
shapes.value.forEach(shape => {
|
||||||
|
drawShape(ctx, shape)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawShape = (ctx, shape) => {
|
||||||
|
ctx.strokeStyle = shape.color || '#ff0000'
|
||||||
|
ctx.lineWidth = 2
|
||||||
|
|
||||||
|
if (shape.type === 'rectangle') {
|
||||||
|
const width = shape.endX - shape.startX
|
||||||
|
const height = shape.endY - shape.startY
|
||||||
|
ctx.strokeRect(shape.startX, shape.startY, width, height)
|
||||||
|
} else if (shape.type === 'circle') {
|
||||||
|
const radius = Math.sqrt(
|
||||||
|
Math.pow(shape.endX - shape.startX, 2) + Math.pow(shape.endY - shape.startY, 2)
|
||||||
|
)
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(shape.startX, shape.startY, radius, 0, Math.PI * 2)
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
shapes.value = []
|
||||||
|
inputText.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSend = () => {
|
||||||
|
const canvas = canvasRef.value
|
||||||
|
const imageData = canvas.toDataURL('image/png')
|
||||||
|
emit('send', {
|
||||||
|
image: imageData,
|
||||||
|
text: inputText.value,
|
||||||
|
shapes: shapes.value
|
||||||
|
})
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.canvas-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container {
|
||||||
|
width: 40vw;
|
||||||
|
height: 70vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
|
||||||
|
.preview-area {
|
||||||
|
.preview-text {
|
||||||
|
color: #333;
|
||||||
|
font-family: "Microsoft YaHei";
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-area {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f3f4f5;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1px solid #e4e7ed;
|
||||||
|
padding: 15px 20px;
|
||||||
|
|
||||||
|
.input-area {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-area {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shape-selector {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.shape-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #409eff;
|
||||||
|
border-color: #409eff;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btns {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-left: 20px;
|
||||||
|
|
||||||
|
.shape-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -75,6 +75,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
import brush from '@/assets/display/brush.svg'
|
import brush from '@/assets/display/brush.svg'
|
||||||
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
|
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
|
||||||
import { downloadImage } from '@/utils/downloadImage.js'
|
import { downloadImage } from '@/utils/downloadImage.js'
|
||||||
|
|
@ -88,10 +89,17 @@ const props = defineProps({
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['open-canvas'])
|
||||||
|
|
||||||
const useDisplay = useDisplayStore()
|
const useDisplay = useDisplayStore()
|
||||||
const useParams = useParamStore()
|
const useParams = useParamStore()
|
||||||
const useUser = useUserStore()
|
const useUser = useUserStore()
|
||||||
|
|
||||||
|
const AIvideo = (file, index) => {
|
||||||
|
emit('open-canvas', file)
|
||||||
|
}
|
||||||
|
|
||||||
const reEdit = (url, number) => {
|
const reEdit = (url, number) => {
|
||||||
console.log(number)
|
console.log(number)
|
||||||
// const index = String(number + 1)
|
// const index = String(number + 1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue