|
|
|
@ -20,42 +20,71 @@ |
|
|
|
|
<template #item="{ element: group, index: groupIndex }"> |
|
|
|
|
<el-row :span="24"> |
|
|
|
|
<div> |
|
|
|
|
<div style="display: flex; justify-content: flex-end;" data-html2canvas-ignore="true"> |
|
|
|
|
<el-button class="drag-handle" type="primary" icon="Rank" circle></el-button> |
|
|
|
|
<el-button type="danger" icon="Delete" circle @click="removeGroup(groupIndex)"></el-button> |
|
|
|
|
<el-button type="primary" icon="Plus" circle @click="addGroup"></el-button> |
|
|
|
|
<div> |
|
|
|
|
<div style="display: flex; justify-content: space-between;" data-html2canvas-ignore="true"> |
|
|
|
|
<div> |
|
|
|
|
<el-button type="primary" icon="CopyDocument" @click="copy(group.shortDescription)">{{ t('Copy') }} |
|
|
|
|
</el-button> |
|
|
|
|
<el-button type="primary" icon="Document" @click="paste(groupIndex,'shortDescription')">{{ |
|
|
|
|
t('Paste') |
|
|
|
|
}} |
|
|
|
|
</el-button> |
|
|
|
|
</div> |
|
|
|
|
<div> |
|
|
|
|
<el-button class="drag-handle" type="primary" icon="Rank" circle></el-button> |
|
|
|
|
<el-button type="primary" icon="Plus" circle @click="addGroup"></el-button> |
|
|
|
|
<el-button type="danger" icon="Delete" circle @click="removeGroup(groupIndex)"></el-button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<QuillEditor v-model:content="group.shortDescription" contentType="html" theme="snow" |
|
|
|
|
:toolbar="toolbarOptions"/> |
|
|
|
|
</div> |
|
|
|
|
<!-- <div style="display: flex; justify-content: flex-end;" data-html2canvas-ignore="true">--> |
|
|
|
|
<!-- <el-button class="drag-handle" type="primary" icon="Rank" circle></el-button>--> |
|
|
|
|
<!-- <el-button type="danger" icon="Delete" circle @click="removeGroup(groupIndex)"></el-button>--> |
|
|
|
|
<!-- <el-button type="primary" icon="Plus" circle @click="addGroup"></el-button>--> |
|
|
|
|
<!-- </div>--> |
|
|
|
|
<div> |
|
|
|
|
<draggable :list="group" item-key="name" style="display: flex; flex-direction: row; width: 20%;"> |
|
|
|
|
<draggable :list="group.groupInfo" item-key="name" style="display: flex; flex-direction: row; width: 20%;"> |
|
|
|
|
<template #item="{element : position, index:positionIndex}"> |
|
|
|
|
<div> |
|
|
|
|
<el-col> |
|
|
|
|
<el-card :body-style="{ padding: '0px' } "> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Add delete button here --> |
|
|
|
|
<el-button type="danger" icon="Delete" circle @click="removeGroupElement(groupIndex, positionIndex)" data-html2canvas-ignore="true"></el-button> |
|
|
|
|
<el-button type="primary" icon="Plus" circle @click="addGroupElement(groupIndex)" data-html2canvas-ignore="true"></el-button> |
|
|
|
|
<img :src="position.avatar || '/assets/Shikigami/default.png'" class="image" |
|
|
|
|
@click="editShikigami(groupIndex,positionIndex)"/> |
|
|
|
|
<el-card :body-style="{ padding: '0px', display: 'flex', 'flex-direction': 'column', 'justify-content': 'center', 'align-items': 'center' }"> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<!-- Add delete button here --> |
|
|
|
|
<el-button type="danger" icon="Delete" circle |
|
|
|
|
@click="removeGroupElement(groupIndex, positionIndex)" |
|
|
|
|
data-html2canvas-ignore="true"></el-button> |
|
|
|
|
<el-button type="primary" icon="Plus" circle @click="addGroupElement(groupIndex)" |
|
|
|
|
data-html2canvas-ignore="true"></el-button> |
|
|
|
|
</div> |
|
|
|
|
<div class="avatar-wrapper"> |
|
|
|
|
<img :src="position.avatar || '/assets/Shikigami/default.png'" |
|
|
|
|
class="avatar-image" |
|
|
|
|
@click="editShikigami(groupIndex,positionIndex)"/> |
|
|
|
|
</div> |
|
|
|
|
<div style="padding: 14px; width: 95px"> |
|
|
|
|
|
|
|
|
|
<span>{{ position.name || "" }}</span> |
|
|
|
|
<div class="bottom" data-html2canvas-ignore="true"> |
|
|
|
|
<el-button @click="editProperties(groupIndex,positionIndex)">配置属性</el-button> |
|
|
|
|
<el-button @click="editProperty(groupIndex,positionIndex)">{{ t('editProperties') }} |
|
|
|
|
</el-button> |
|
|
|
|
</div> |
|
|
|
|
<!-- properties--> |
|
|
|
|
<!-- {"edit":true,"yuhun":{"yuhunSetEffect":[{"name":"狰","type":"attack","avatar":"/assets/Yuhun/狰.png"}],"target":"伤害输出","property2":["Attack"],"property4":["Attack"],"property6":["Crit","CritDamage"]},"levelRequired":"40","speed":"","skillRequiredMode":"all","skillRequired":["技能一","技能二","技能三"]}--> |
|
|
|
|
<div v-if="position.properties"> |
|
|
|
|
<div> |
|
|
|
|
<span style="display: inline-block; width: 100px; height: 25px; background-color: #666; border-top-left-radius: 5px; border-top-right-radius: 5px; margin-right: 5px; color: white; text-align: center; white-space: pre-wrap "> |
|
|
|
|
<span |
|
|
|
|
style="display: inline-block; width: 100px; height: 25px; background-color: #666; border-top-left-radius: 5px; border-top-right-radius: 5px; margin-right: 5px; color: white; text-align: center; white-space: pre-wrap "> |
|
|
|
|
{{ position.properties.yuhun.yuhunSetEffect.map(item => item.name).join(' ') }} |
|
|
|
|
</span> |
|
|
|
|
<span style="display: inline-block; width: 100px; height: 25px; background-color: #666; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; margin-right: 5px; color: white; text-align: center; white-space: pre-wrap "> |
|
|
|
|
{{ t('yuhun_target.' + position.properties.yuhun.target)}}· |
|
|
|
|
<span |
|
|
|
|
style="display: inline-block; width: 100px; height: 25px; background-color: #666; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; margin-right: 5px; color: white; text-align: center; white-space: pre-wrap "> |
|
|
|
|
{{ t('yuhun_target.' + position.properties.yuhun.target) }}· |
|
|
|
|
</span> |
|
|
|
|
</div> |
|
|
|
|
<div v-for="(value, key, index) in position.properties"> |
|
|
|
|
<div v-for="(value, key, index) in position.properties" data-html2canvas-ignore="true"> |
|
|
|
|
<span>{{ key }}</span> : <span>{{ value || '-' }}</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
@ -68,7 +97,14 @@ |
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
<div> |
|
|
|
|
<QuillEditor v-model:content="content" contentType="html" theme="snow" :toolbar="toolbarOptions"/> |
|
|
|
|
<div data-html2canvas-ignore="true"> |
|
|
|
|
<el-button type="primary" icon="CopyDocument" @click="copy(group.details)">{{ t('Copy') }}</el-button> |
|
|
|
|
<el-button type="primary" icon="Document" @click="paste(groupIndex,'details')">{{ |
|
|
|
|
t('Paste') |
|
|
|
|
}} |
|
|
|
|
</el-button> |
|
|
|
|
</div> |
|
|
|
|
<QuillEditor v-model:content="group.details" contentType="html" theme="snow" :toolbar="toolbarOptions"/> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
@ -84,15 +120,15 @@ |
|
|
|
|
<!-- 现有的代码 --> |
|
|
|
|
<div style="margin: 20px" data-html2canvas-ignore="true"> |
|
|
|
|
<!-- 触发截图的按钮 --> |
|
|
|
|
<button @click="prepareCapture">生成截图</button> |
|
|
|
|
<el-button type="primary" @click="prepareCapture">{{ t('prepareCapture') }}</el-button> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<!-- 预览弹窗 --> |
|
|
|
|
<el-dialog id="preview-container" v-model="state.previewVisible" width="80%" :before-close="handleClose"> |
|
|
|
|
<div style="max-height: 500px; overflow-y: auto;"> |
|
|
|
|
<img v-if="state.previewImage" :src="state.previewImage" alt="Preview" style="width: 100%; display: block;" /> |
|
|
|
|
<img v-if="state.previewImage" :src="state.previewImage" alt="Preview" style="width: 100%; display: block;"/> |
|
|
|
|
</div> |
|
|
|
|
<!-- <img v-if="state.previewImage" :src="state.previewImage" alt="Preview" style="width: 100%; height: auto;" />--> |
|
|
|
|
<!-- <img v-if="state.previewImage" :src="state.previewImage" alt="Preview" style="width: 100%; height: auto;" />--> |
|
|
|
|
<span slot="footer" class="dialog-footer"> |
|
|
|
|
<el-button @click="state.previewVisible = false">取 消</el-button> |
|
|
|
|
<el-button type="primary" @click="downloadImage">下 载</el-button> |
|
|
|
@ -103,13 +139,13 @@ |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<script setup> |
|
|
|
|
import { ref, reactive, toRefs } from 'vue'; |
|
|
|
|
import {ref, reactive, toRefs} from 'vue'; |
|
|
|
|
import draggable from 'vuedraggable'; |
|
|
|
|
import ShikigamiSelect from './ShikigamiSelect.vue'; |
|
|
|
|
import ShikigamiProperty from './ShikigamiProperty.vue'; |
|
|
|
|
import html2canvas from 'html2canvas'; |
|
|
|
|
import { useI18n } from 'vue-i18n' |
|
|
|
|
import { QuillEditor } from '@vueup/vue-quill' |
|
|
|
|
import {useI18n} from 'vue-i18n' |
|
|
|
|
import {QuillEditor} from '@vueup/vue-quill' |
|
|
|
|
import '@vueup/vue-quill/dist/vue-quill.snow.css' // 引入样式文件 |
|
|
|
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue' |
|
|
|
|
import shikigamiData from '../data/Shikigami.json'; |
|
|
|
@ -120,8 +156,16 @@ const state = reactive({ |
|
|
|
|
showSelectShikigami: false, |
|
|
|
|
showProperty: false, |
|
|
|
|
groups: [ |
|
|
|
|
[{}, {}, {}, {}, {}], |
|
|
|
|
[{}, {}, {}, {}, {}] |
|
|
|
|
{ |
|
|
|
|
shortDescription: '', |
|
|
|
|
groupInfo: [{}, {}, {}, {}, {}], |
|
|
|
|
details: '' |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
shortDescription: '', |
|
|
|
|
groupInfo: [{}, {}, {}, {}, {}], |
|
|
|
|
details: '' |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
groupIndex: 0, |
|
|
|
|
positionIndex: 0, |
|
|
|
@ -130,31 +174,40 @@ const state = reactive({ |
|
|
|
|
previewVisible: false, // 控制预览弹窗的显示状态 |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const clipboard = ref(''); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前的 i18n 实例 |
|
|
|
|
const { t } = useI18n() |
|
|
|
|
// 初始化内容 |
|
|
|
|
const content = ref('<p>初始内容</p>') |
|
|
|
|
const content1 = ref('<p>初始内容1</p>') |
|
|
|
|
const {t} = useI18n() |
|
|
|
|
|
|
|
|
|
const copy = (str) => { |
|
|
|
|
clipboard.value = str |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const paste = (groupIndex, type) => { |
|
|
|
|
if ('shortDescription' == type) |
|
|
|
|
state.groups[groupIndex].shortDescription = clipboard.value |
|
|
|
|
else if ('details' == type) |
|
|
|
|
state.groups[groupIndex].details = clipboard.value |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 定义工具栏选项 |
|
|
|
|
const toolbarOptions = [ |
|
|
|
|
|
|
|
|
|
[{ 'color': [] }, { 'background': [] }], |
|
|
|
|
[{'color': []}, {'background': []}], |
|
|
|
|
['bold', 'italic', 'underline', 'strike'], |
|
|
|
|
['blockquote', 'code-block'], |
|
|
|
|
['link', 'image', 'video', 'formula'], |
|
|
|
|
[{ 'header': 1 }, { 'header': 2 }], |
|
|
|
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }], |
|
|
|
|
[{ 'script': 'sub'}, { 'script': 'super' }], |
|
|
|
|
[{ 'indent': '-1'}, { 'indent': '+1' }], |
|
|
|
|
[{ 'direction': 'rtl' }], |
|
|
|
|
[{ 'size': ['small', false, 'large', 'huge'] }], |
|
|
|
|
[{ 'header': [1, 2, 3, 4, 5, 6, false] }], |
|
|
|
|
[{ 'color': [] }, { 'background': [] }], |
|
|
|
|
[{ 'font': [] }], |
|
|
|
|
[{ 'align': [] }], |
|
|
|
|
['clean'] |
|
|
|
|
// ['blockquote', 'code-block'], |
|
|
|
|
// ['link', 'image', 'video', 'formula'], |
|
|
|
|
[{'header': 1}, {'header': 2}], |
|
|
|
|
[{'list': 'ordered'}, {'list': 'bullet'}, {'list': 'check'}], |
|
|
|
|
// [{ 'script': 'sub'}, { 'script': 'super' }], |
|
|
|
|
[{'indent': '-1'}, {'indent': '+1'}], |
|
|
|
|
// [{ 'size': ['small', false, 'large', 'huge'] }], |
|
|
|
|
// [{ 'header': [1, 2, 3, 4, 5, 6, false] }], |
|
|
|
|
// [{ 'font': [] }], |
|
|
|
|
[{'align': []}], |
|
|
|
|
[{'direction': 'rtl'}], |
|
|
|
|
// ['clean'] |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
// 定义方法 |
|
|
|
@ -175,32 +228,32 @@ const updateShikigami = (shikigami) => { |
|
|
|
|
console.log("parent====> ", shikigami); |
|
|
|
|
state.showSelectShikigami = false; |
|
|
|
|
|
|
|
|
|
const oldProperties = state.groups[state.groupIndex][state.positionIndex].properties; |
|
|
|
|
state.groups[state.groupIndex][state.positionIndex] = shikigami; |
|
|
|
|
state.groups[state.groupIndex][state.positionIndex].properties = oldProperties; |
|
|
|
|
const oldProperties = state.groups[state.groupIndex].groupInfo[state.positionIndex].properties; |
|
|
|
|
state.groups[state.groupIndex].groupInfo[state.positionIndex] = shikigami; |
|
|
|
|
state.groups[state.groupIndex].groupInfo[state.positionIndex].properties = oldProperties; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const editProperties = (groupIndex, positionIndex) => { |
|
|
|
|
const editProperty = (groupIndex, positionIndex) => { |
|
|
|
|
state.showProperty = true; |
|
|
|
|
state.groupIndex = groupIndex; |
|
|
|
|
state.positionIndex = positionIndex; |
|
|
|
|
state.currentShikigami = state.groups[groupIndex][positionIndex]; |
|
|
|
|
state.currentShikigami = state.groups[groupIndex].groupInfo[positionIndex]; |
|
|
|
|
console.log("currentShikigami", JSON.stringify(state.currentShikigami)); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const closeProperty = () => { |
|
|
|
|
state.showProperty = false; |
|
|
|
|
state.currentShikigami = state.groups[state.groupIndex][state.positionIndex]; |
|
|
|
|
state.currentShikigami = {}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const updateProperty = (property) => { |
|
|
|
|
state.showProperty = false; |
|
|
|
|
state.currentShikigami = {}; |
|
|
|
|
state.groups[state.groupIndex][state.positionIndex].properties = property; |
|
|
|
|
state.groups[state.groupIndex].groupInfo[state.positionIndex].properties = property; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const removeGroupElement = (groupIndex, positionIndex) => { |
|
|
|
|
state.groups[groupIndex].splice(positionIndex, 1); |
|
|
|
|
state.groups[groupIndex].groupInfo.splice(positionIndex, 1); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const removeGroup = (groupIndex) => { |
|
|
|
@ -208,11 +261,15 @@ const removeGroup = (groupIndex) => { |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const addGroup = () => { |
|
|
|
|
state.groups.push([{}, {}, {}, {}, {}]); |
|
|
|
|
state.groups.push({ |
|
|
|
|
shortDescription: '', |
|
|
|
|
groupInfo: [{}, {}, {}, {}, {}], |
|
|
|
|
details: '' |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const addGroupElement = (groupIndex) => { |
|
|
|
|
state.groups[groupIndex].push({}); |
|
|
|
|
state.groups[groupIndex].groupInfo.push({}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const ignoreElements = (element) => { |
|
|
|
@ -231,10 +288,10 @@ const prepareCapture = async () => { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const canvas = await html2canvas(element,{ |
|
|
|
|
ignoreElements:ignoreElements, |
|
|
|
|
height:element.scrollHeight |
|
|
|
|
} |
|
|
|
|
const canvas = await html2canvas(element, { |
|
|
|
|
ignoreElements: ignoreElements, |
|
|
|
|
height: element.scrollHeight |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
state.previewImage = canvas.toDataURL(); |
|
|
|
|
if (!state.previewImage) { |
|
|
|
@ -275,4 +332,27 @@ const handleClose = (done) => { |
|
|
|
|
.ql-toolbar { |
|
|
|
|
display: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 正方形容器 */ |
|
|
|
|
.avatar-wrapper { |
|
|
|
|
width: 100px; /* 正方形边长 */ |
|
|
|
|
height: 100px; /* 与宽度相同 */ |
|
|
|
|
position: relative; |
|
|
|
|
overflow: hidden; /* 隐藏超出部分 */ |
|
|
|
|
border-radius: 50%; /* 圆形裁剪 */ |
|
|
|
|
//border: 2px solid #fff; /* 可选:添加边框 */ |
|
|
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* 可选:添加阴影 */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 图片样式 */ |
|
|
|
|
.avatar-image { |
|
|
|
|
width: 100%; |
|
|
|
|
height: 100%; |
|
|
|
|
object-fit: cover; /* 关键属性:保持比例填充容器 */ |
|
|
|
|
object-position: center; /* 居中显示 */ |
|
|
|
|
display: block; |
|
|
|
|
cursor: pointer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</style> |
|
|
|
|