mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-28 04:10:31 +08:00
feat: add watermark & canvas size modification
This commit is contained in:
parent
2859efd0e7
commit
f6903eee7c
75
src/assets/data/PageSizeData.ts
Normal file
75
src/assets/data/PageSizeData.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-07 17:49:06
|
||||||
|
* @Description:
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-10 00:37:33
|
||||||
|
*/
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
name: '手机海报',
|
||||||
|
width: 1242,
|
||||||
|
height: 2208,
|
||||||
|
icon: 'sd-shouji'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '横版海报',
|
||||||
|
width: 900,
|
||||||
|
height: 500,
|
||||||
|
icon: 'sd-wangye'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '公众号首图',
|
||||||
|
width: 900,
|
||||||
|
height: 383,
|
||||||
|
icon: 'sd-weixin'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '公众号次图',
|
||||||
|
width: 500,
|
||||||
|
height: 500,
|
||||||
|
icon: 'sd-weixin'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '小红书配图',
|
||||||
|
width: 1242,
|
||||||
|
height: 1660,
|
||||||
|
icon: 'sd-shouji'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '商品主图',
|
||||||
|
width: 800,
|
||||||
|
height: 800,
|
||||||
|
icon: 'sd-wangye'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '电商详情页',
|
||||||
|
width: 750,
|
||||||
|
height: 1000,
|
||||||
|
icon: 'sd-wangye'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '电商竖版海报',
|
||||||
|
width: 750,
|
||||||
|
height: 950,
|
||||||
|
icon: 'sd-shouji'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '电商横版海报',
|
||||||
|
width: 750,
|
||||||
|
height: 390,
|
||||||
|
icon: 'sd-wangye'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '小程序封面',
|
||||||
|
width: 520,
|
||||||
|
height: 416,
|
||||||
|
icon: 'sd-weixin'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '壁纸 / PPT(16:9)',
|
||||||
|
width: 1920,
|
||||||
|
height: 1080,
|
||||||
|
icon: 'sd-wangye'
|
||||||
|
}
|
||||||
|
]
|
@ -1,8 +1,8 @@
|
|||||||
// element UI fix
|
// element UI fix
|
||||||
.el-collapse-item__header {
|
.el-collapse-item__header {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 14px;
|
font-size: 14px !important;
|
||||||
color: #666666;
|
color: #666666 !important;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
.el-collapse-item__wrap {
|
.el-collapse-item__wrap {
|
||||||
|
@ -61,6 +61,9 @@
|
|||||||
// font-size: 18px;
|
// font-size: 18px;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
.iconfont {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
.text {
|
.text {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-left: .4rem;
|
margin-left: .4rem;
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2022-02-03 16:30:18
|
* @Date: 2022-02-03 16:30:18
|
||||||
* @Description: Type: success / info / warning / error
|
* @Description: Type: success / info / warning / error
|
||||||
* @LastEditors: ShawnPhang <site: book.palxp.com>, Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-02 11:50:00
|
* @LastEditTime: 2024-04-08 18:55:12
|
||||||
*/
|
*/
|
||||||
import { ElMessageBox, messageType } from 'element-plus'
|
import { ElMessageBox, messageType } from 'element-plus'
|
||||||
export default (title: string = '提示', message: string = '', type: messageType = 'success') => {
|
export default (title: string = '提示', message: string = '', type: messageType = 'success', extra?: any) => {
|
||||||
return new Promise((resolve: Function) => {
|
return new Promise((resolve: Function) => {
|
||||||
ElMessageBox.confirm(message, title, {
|
ElMessageBox.confirm(message, title, Object.assign({
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type,
|
type,
|
||||||
})
|
}, extra))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolve(true)
|
resolve(true)
|
||||||
})
|
})
|
||||||
|
112
src/components/business/create-design/createDesign.vue
Normal file
112
src/components/business/create-design/createDesign.vue
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-09 11:24:57
|
||||||
|
* @Description: 创建/编辑画布尺寸
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-10 17:29:15
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog v-model="dialogVisible" center destroy-on-close :align-center="false" :title="params ? '编辑尺寸' : '新建空白设计'" width="380" draggable>
|
||||||
|
<!-- <el-divider content-position="left">自定义尺寸</el-divider> -->
|
||||||
|
<el-checkbox v-if="params" v-model="isAdaptive" label="自动调整元素大小位置" size="large" />
|
||||||
|
<sizeEditor :params="page" :class="params ? 'editor-mode' : 'add-mode'">
|
||||||
|
<el-button @click="finish" plain size="large" type="primary">{{ params ? '应用' : '创建' }}</el-button>
|
||||||
|
</sizeEditor>
|
||||||
|
<el-divider content-position="left">使用推荐尺寸</el-divider>
|
||||||
|
<ul class="pre-list">
|
||||||
|
<li @click="applySize(s)" class="item" v-for="(s, si) in sizes" :key="'s' + si">
|
||||||
|
<i :class="['icon', s.icon]" /> {{ s.name }} <span class="info">{{ s.width }} × {{ s.height }} px</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- <template #footer>
|
||||||
|
<el-button type="primary" @click="dialogVisible = false"> Confirm </el-button>
|
||||||
|
</template> -->
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, Ref } from 'vue'
|
||||||
|
import { ElCheckbox } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import sizeEditor from './sizeEditor.vue'
|
||||||
|
import sizes from '@/assets/data/PageSizeData'
|
||||||
|
import { useWidgetStore } from '@/store';
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
params?: any
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
params: undefined,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
const dialogVisible: Ref<boolean> = ref(false)
|
||||||
|
const isAdaptive: Ref<boolean> = ref(true)
|
||||||
|
const page: any = ref({ width: 100, height: 100 })
|
||||||
|
|
||||||
|
const applySize = ({ width, height }: any) => {
|
||||||
|
page.value.width = width
|
||||||
|
page.value.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
if (props.params) {
|
||||||
|
page.value.width = props.params.width
|
||||||
|
page.value.height = props.params.height
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
const { width, height } = page.value
|
||||||
|
if (props.params) {
|
||||||
|
const lastPageData = JSON.parse(JSON.stringify(props.params))
|
||||||
|
props.params.width = width
|
||||||
|
props.params.height = height
|
||||||
|
isAdaptive.value && widgetStore.autoResizeAll(lastPageData)
|
||||||
|
} else window.open(router.resolve(`/home?mode=create&w_h=${width}*${height}`).href, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.el-dialog__header) {
|
||||||
|
padding-bottom: 7px !important;
|
||||||
|
}
|
||||||
|
.editor-mode {
|
||||||
|
padding: 0 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
.add-mode {
|
||||||
|
padding: 1rem 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
.pre-list {
|
||||||
|
margin: 1rem 0;
|
||||||
|
height: 245px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
.item {
|
||||||
|
padding: 10px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
.icon {
|
||||||
|
margin-right: 0.2rem;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
margin-left: 0.4rem;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #b4b8bf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item:hover {
|
||||||
|
background-color: #f6f7f9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
2
src/components/business/create-design/index.ts
Normal file
2
src/components/business/create-design/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import v from './createDesign.vue'
|
||||||
|
export default v
|
101
src/components/business/create-design/sizeEditor.vue
Normal file
101
src/components/business/create-design/sizeEditor.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-08 21:33:59
|
||||||
|
* @Description: 尺寸编辑
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-09 15:55:33
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div class="position-size">
|
||||||
|
<number-input v-model="params.width" label="宽" :maxValue="5000" />
|
||||||
|
<el-tooltip :show-after="300" :hide-after="0" effect="dark" :content="lockRatio ? '锁定宽高比' : '自由改变'" placement="top">
|
||||||
|
<i @click="changeRatio" :class="['icon', lockRatio ? 'sd-db' : 'sd-fdb']" />
|
||||||
|
</el-tooltip>
|
||||||
|
<number-input v-model="params.height" label="高" :maxValue="5000" />
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import numberInput from '@/components/modules/settings/numberInput.vue'
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
params: any
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<TProps>(), {
|
||||||
|
params: {},
|
||||||
|
})
|
||||||
|
|
||||||
|
const lockRatio = ref(false) // 锁定比例缩放画布
|
||||||
|
let scale = 0,
|
||||||
|
temp = { width: 0, height: 0 }
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.params.width,
|
||||||
|
(val, old) => {
|
||||||
|
if (scale && isNumber(val) && isNumber(old)) {
|
||||||
|
temp.width === 0 && (temp.width = props.params.width)
|
||||||
|
setChange()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.params.height,
|
||||||
|
(val, old) => {
|
||||||
|
if (scale && isNumber(val) && isNumber(old)) {
|
||||||
|
temp.height === 0 && (temp.height = props.params.height)
|
||||||
|
setChange()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// 锁定宽高比
|
||||||
|
function changeRatio() {
|
||||||
|
lockRatio.value = !lockRatio.value
|
||||||
|
if (lockRatio.value) {
|
||||||
|
scale = props.params.width / props.params.height
|
||||||
|
} else scale = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用更改
|
||||||
|
let timer: any = null
|
||||||
|
function setChange() {
|
||||||
|
clearTimeout(timer)
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
temp.width > 0 && temp.height === 0 && (props.params.height = props.params.width / scale)
|
||||||
|
temp.height > 0 && temp.width === 0 && (props.params.width = props.params.height * scale)
|
||||||
|
if (temp.width > 0 && temp.height > 0) {
|
||||||
|
temp = { width: 0, height: 0 }
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNumber(val: any) {
|
||||||
|
return typeof val === 'number'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.position-size {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
.number-input {
|
||||||
|
flex: 0.2;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 19px;
|
||||||
|
}
|
||||||
|
.sd-fdb,
|
||||||
|
.sd-db {
|
||||||
|
color: #999999;
|
||||||
|
margin: 0 6px 0 -4px;
|
||||||
|
}
|
||||||
|
.sd-db {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-04 11:46:39
|
* @Date: 2021-08-04 11:46:39
|
||||||
* @Description: 原版movable插件
|
* @Description: 原版movable插件
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-11-14 11:41:23
|
* @LastEditTime: 2024-04-06 14:56:35
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div id="empty" class="moveable__remove-item zk-moveable-style"></div>
|
<div id="empty" class="moveable__remove-item zk-moveable-style"></div>
|
||||||
@ -275,7 +275,9 @@ onMounted(() => {
|
|||||||
triggerAblesSimultaneously: true,
|
triggerAblesSimultaneously: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
moveable = new Moveable(document.body, moveableOptions)
|
// moveable = new Moveable(document.body, moveableOptions)
|
||||||
|
const containerEl = document.querySelector('#main') as HTMLElement | SVGElement;
|
||||||
|
moveable = new Moveable(containerEl, moveableOptions)
|
||||||
|
|
||||||
const helper = new MoveableHelper()
|
const helper = new MoveableHelper()
|
||||||
|
|
||||||
@ -578,12 +580,6 @@ onMounted(() => {
|
|||||||
key: 'left',
|
key: 'left',
|
||||||
value: item.left,
|
value: item.left,
|
||||||
})
|
})
|
||||||
// store.dispatch("updateWidgetData", {
|
|
||||||
// uuid: key,
|
|
||||||
// key: 'left',
|
|
||||||
// value: item.left,
|
|
||||||
// })
|
|
||||||
|
|
||||||
widgetStore.updateWidgetData({
|
widgetStore.updateWidgetData({
|
||||||
uuid: key,
|
uuid: key,
|
||||||
key: 'top',
|
key: 'top',
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-07-13 22:51:29
|
* @Date: 2021-07-13 22:51:29
|
||||||
* @Description: require.context自动引用
|
* @Description: Widgets、panel中所有组件将会自动全局引入
|
||||||
* @LastEditors: ShawnPhang
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2022-04-08 10:28:47
|
* @LastEditTime: 2024-04-09 22:31:08
|
||||||
*/
|
*/
|
||||||
import { App } from "vue"
|
import { App } from "vue"
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-08 19:19:17
|
||||||
|
* @Description: 水印组件封装
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-08 21:30:12
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<slot v-if="isDrawPage" />
|
||||||
|
<el-watermark v-else :style="props.customStyle" :gap="[140, 120]" :content="watermark">
|
||||||
|
<slot />
|
||||||
|
</el-watermark>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { ElWatermark } from 'element-plus'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useBaseStore } from '@/store'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
customStyle: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<TProps>(), {
|
||||||
|
customStyle: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isDrawPage = computed(() => route.name === 'Draw')
|
||||||
|
const baseStore = useBaseStore()
|
||||||
|
const { watermark } = storeToRefs(baseStore)
|
||||||
|
</script>
|
133
src/components/modules/layout/designBoard/comps/resize.vue
Normal file
133
src/components/modules/layout/designBoard/comps/resize.vue
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-06 15:17:03
|
||||||
|
* @Description: 画布尺寸操作柄
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-08 12:28:15
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div v-show="show" class="page-resize" :style="{ width: Math.floor(pw) + 'px', height: Math.floor(ph) + 'px' }">
|
||||||
|
<div @mousedown="handlemousedown($event, 'ns', true)" class="resize__bar resize__bar-top"></div>
|
||||||
|
<div @mousedown="handlemousedown($event, 'ew')" class="resize__bar resize__bar-right"></div>
|
||||||
|
<div @mousedown="handlemousedown($event, 'ns')" class="resize__bar resize__bar-bottom"></div>
|
||||||
|
<div @mousedown="handlemousedown($event, 'ew', true)" class="resize__bar resize__bar-left"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWidgetStore, useCanvasStore } from '@/store'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}>()
|
||||||
|
|
||||||
|
type Direction = 'ns' | 'ew' // 上下 | 左右
|
||||||
|
|
||||||
|
const { dActiveElement } = storeToRefs(widgetStore)
|
||||||
|
const show = computed(() => dActiveElement.value?.uuid === '-1')
|
||||||
|
|
||||||
|
let initData = { x: 0, y: 0, w: 0, h: 0 }
|
||||||
|
let moveDir = ''
|
||||||
|
let moveRev: any = undefined
|
||||||
|
|
||||||
|
const handlemousedown = (e: any, dir: Direction, isReverse?: boolean) => {
|
||||||
|
moveDir = dir
|
||||||
|
moveRev = isReverse
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
initData = { x: e.pageX, y: e.pageY, w: canvasStore.dPage.width, h: canvasStore.dPage.height }
|
||||||
|
document.addEventListener('mousemove', handlemousemove, true)
|
||||||
|
document.addEventListener('mouseup', stopMove, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopMove = () => {
|
||||||
|
document.removeEventListener('mousemove', handlemousemove, true)
|
||||||
|
document.removeEventListener('mouseup', stopMove, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlemousemove(e: any) {
|
||||||
|
const { x, y, w, h } = initData
|
||||||
|
if (moveDir === 'ew') {
|
||||||
|
const dx = e.pageX - x
|
||||||
|
const moveX = Math.floor((dx * 100) / canvasStore.dZoom)
|
||||||
|
const result = moveRev ? w - moveX * 2 : w + moveX * 2
|
||||||
|
result <= 5000 && result > 0 && (canvasStore.dPage.width = result)
|
||||||
|
} else {
|
||||||
|
const dy = e.pageY - y
|
||||||
|
const moveY = Math.floor((dy * 100) / canvasStore.dZoom)
|
||||||
|
const result = moveRev ? h - moveY * 2 : h + moveY * 2
|
||||||
|
result <= 5000 && result > 0 && (canvasStore.dPage.height = result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pw = computed(() => props.width)
|
||||||
|
const ph = computed(() => props.height)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@bar-color: rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
|
.page-resize {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
.resize__bar {
|
||||||
|
pointer-events: auto;
|
||||||
|
position: absolute;
|
||||||
|
&-left {
|
||||||
|
left: -14px;
|
||||||
|
}
|
||||||
|
&-right {
|
||||||
|
right: -14px;
|
||||||
|
}
|
||||||
|
&-left,
|
||||||
|
&-right {
|
||||||
|
position: reactive;
|
||||||
|
cursor: ew-resize;
|
||||||
|
width: 10px;
|
||||||
|
height: 24px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-12px);
|
||||||
|
}
|
||||||
|
&-left:after,
|
||||||
|
&-right:after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
left: 3px;
|
||||||
|
width: 4px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: @bar-color;
|
||||||
|
}
|
||||||
|
&-top {
|
||||||
|
top: -14px;
|
||||||
|
}
|
||||||
|
&-bottom {
|
||||||
|
bottom: -12px;
|
||||||
|
}
|
||||||
|
&-top,
|
||||||
|
&-bottom {
|
||||||
|
cursor: ns-resize;
|
||||||
|
width: 24px;
|
||||||
|
height: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-12px);
|
||||||
|
}
|
||||||
|
&-top:after,
|
||||||
|
&-bottom:after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
top: 4px;
|
||||||
|
width: 24px;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: @bar-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -10,7 +10,9 @@
|
|||||||
opacity: 1 - (dZoom < 100 ? dPage.tag : 0),
|
opacity: 1 - (dZoom < 100 ? dPage.tag : 0),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
<resize-page :width="(dPage.width * dZoom) / 100" :height="(dPage.height * dZoom) / 100" />
|
||||||
|
<watermark :customStyle="{ height: (dPage.height * dZoom) / 100 + 'px'}">
|
||||||
<div
|
<div
|
||||||
:id="pageDesignCanvasId"
|
:id="pageDesignCanvasId"
|
||||||
class="design-canvas"
|
class="design-canvas"
|
||||||
@ -33,12 +35,6 @@
|
|||||||
@mouseup="drop($event)"
|
@mouseup="drop($event)"
|
||||||
>
|
>
|
||||||
<!-- <grid-size /> -->
|
<!-- <grid-size /> -->
|
||||||
|
|
||||||
<!-- :class="{
|
|
||||||
layer: true,
|
|
||||||
'layer-active': getIsActive(layer.uuid),
|
|
||||||
'layer-hover': layer.uuid === dHoverUuid || dActiveElement.parent === layer.uuid,
|
|
||||||
}" -->
|
|
||||||
<component
|
<component
|
||||||
:is="layer.type"
|
:is="layer.type"
|
||||||
v-for="layer in getlayers()"
|
v-for="layer in getlayers()"
|
||||||
@ -69,6 +65,7 @@
|
|||||||
<!-- <ref-line v-if="dSelectWidgets.length === 0" /> -->
|
<!-- <ref-line v-if="dSelectWidgets.length === 0" /> -->
|
||||||
<!-- <size-control v-if="dSelectWidgets.length === 0" /> -->
|
<!-- <size-control v-if="dSelectWidgets.length === 0" /> -->
|
||||||
</div>
|
</div>
|
||||||
|
</watermark>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,9 +79,11 @@ import PointImg from '@/utils/plugins/pointImg'
|
|||||||
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
||||||
import { debounce } from 'throttle-debounce'
|
import { debounce } from 'throttle-debounce'
|
||||||
import { move, moveInit } from '@/mixins/move'
|
import { move, moveInit } from '@/mixins/move'
|
||||||
import { useCanvasStore, useControlStore, useGroupStore, useWidgetStore } from '@/store'
|
import { useCanvasStore, useControlStore, useWidgetStore } from '@/store'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { TPageState } from '@/store/design/canvas/d'
|
import { TPageState } from '@/store/design/canvas/d'
|
||||||
|
import resizePage from './comps/resize.vue'
|
||||||
|
import watermark from './comps/pageWatermark.vue'
|
||||||
// 页面设计组件
|
// 页面设计组件
|
||||||
type TProps = {
|
type TProps = {
|
||||||
pageDesignCanvasId: string
|
pageDesignCanvasId: string
|
||||||
|
@ -8,10 +8,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-collapse v-else v-model="state.activeNames">
|
<el-collapse v-else v-model="state.activeNames">
|
||||||
<el-collapse-item title="画布尺寸" name="1">
|
<el-collapse-item title="画布尺寸" name="1">
|
||||||
<div class="position-size">
|
<sizeEditor :params="state.innerElement">
|
||||||
<number-input v-model="state.innerElement.width" label="宽" :maxValue="5000" @finish="(value) => finish('width', value)" />
|
<i @click="openSizeEdit" class="icon sd-edit"></i>
|
||||||
<number-input v-model="state.innerElement.height" label="高" :maxValue="5000" @finish="(value) => finish('height', value)" />
|
</sizeEditor>
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
<el-collapse-item title="背景设置" name="2">
|
<el-collapse-item title="背景设置" name="2">
|
||||||
<el-button style="width: 100%; margin: 0 0 1rem 0;" type="primary" link @click="state.showBgLib = true">在背景库中选择</el-button>
|
<el-button style="width: 100%; margin: 0 0 1rem 0;" type="primary" link @click="state.showBgLib = true">在背景库中选择</el-button>
|
||||||
@ -49,29 +48,27 @@
|
|||||||
<el-button v-show="state.mode === '图片' && state.innerElement.backgroundImage" class="btn-wrap" @click="shiftOut">将背景分离为图层</el-button>
|
<el-button v-show="state.mode === '图片' && state.innerElement.backgroundImage" class="btn-wrap" @click="shiftOut">将背景分离为图层</el-button>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
|
<createDesign ref="sizeEditRef" :params="state.innerElement" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// 画布组件样式
|
// 画布组件样式
|
||||||
// const NAME = 'page-style'
|
// const NAME = 'page-style'
|
||||||
import { nextTick, onMounted, reactive, watch } from 'vue'
|
import { nextTick, onMounted, reactive, watch, ref, Ref } from 'vue'
|
||||||
|
import colorSelect, { colorChangeData } from '@/components/modules/settings/colorSelect.vue'
|
||||||
import numberInput from '../settings/numberInput.vue'
|
|
||||||
import colorSelect, { colorChangeData } from '../settings/colorSelect.vue'
|
|
||||||
import uploader, { TUploadDoneData } from '@/components/common/Uploader/index.vue'
|
import uploader, { TUploadDoneData } from '@/components/common/Uploader/index.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import _dl from '@/common/methods/download'
|
import _dl from '@/common/methods/download'
|
||||||
// import ColorPipette from '@/utils/plugins/color-pipette'
|
|
||||||
import Tabs from '@palxp/color-picker/comps/Tabs.vue'
|
import Tabs from '@palxp/color-picker/comps/Tabs.vue'
|
||||||
import TabPanel from '@palxp/color-picker/comps/TabPanel.vue'
|
import TabPanel from '@palxp/color-picker/comps/TabPanel.vue'
|
||||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
|
||||||
import { useCanvasStore, useWidgetStore } from '@/store'
|
import { useCanvasStore, useWidgetStore } from '@/store'
|
||||||
import { TPageState } from '@/store/design/canvas/d'
|
import { TPageState } from '@/store/design/canvas/d'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { Delete as iconDelete, Download as iconDownload } from '@element-plus/icons-vue'
|
import { Delete as iconDelete, Download as iconDownload } from '@element-plus/icons-vue'
|
||||||
import wImageSetting from '@/components/modules/widgets/wImage/wImageSetting'
|
import wImageSetting from '@/components/modules/widgets/wImage/wImageSetting'
|
||||||
// import setImageData from '@/common/methods/DesignFeatures/setImage'
|
import sizeEditor from '@/components/business/create-design/sizeEditor.vue'
|
||||||
|
import createDesign from '@/components/business/create-design'
|
||||||
|
|
||||||
type TState = {
|
type TState = {
|
||||||
activeNames: string[]
|
activeNames: string[]
|
||||||
@ -84,7 +81,6 @@ type TState = {
|
|||||||
showBgLib: boolean
|
showBgLib: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const pageStore = useCanvasStore()
|
const pageStore = useCanvasStore()
|
||||||
const widgetStore = useWidgetStore()
|
const widgetStore = useWidgetStore()
|
||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
@ -97,6 +93,7 @@ const state = reactive<TState>({
|
|||||||
modes: ['颜色', '图片'],
|
modes: ['颜色', '图片'],
|
||||||
showBgLib: false
|
showBgLib: false
|
||||||
})
|
})
|
||||||
|
const sizeEditRef: Ref<typeof createDesign | null> = ref(null)
|
||||||
// const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
// const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
||||||
const { dActiveElement } = storeToRefs(widgetStore)
|
const { dActiveElement } = storeToRefs(widgetStore)
|
||||||
let _localTempBG: string | null = null
|
let _localTempBG: string | null = null
|
||||||
@ -164,8 +161,6 @@ function changeValue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function finish(key: keyof TPageState, value: string | number) {
|
function finish(key: keyof TPageState, value: string | number) {
|
||||||
console.log('111');
|
|
||||||
|
|
||||||
pageStore.updatePageData({
|
pageStore.updatePageData({
|
||||||
key: key,
|
key: key,
|
||||||
value: value,
|
value: value,
|
||||||
@ -202,30 +197,32 @@ async function shiftOut() {
|
|||||||
setting.width = state.innerElement.width
|
setting.width = state.innerElement.width
|
||||||
setting.height = state.innerElement.height
|
setting.height = state.innerElement.height
|
||||||
setting.imgUrl = state.innerElement.backgroundImage
|
setting.imgUrl = state.innerElement.backgroundImage
|
||||||
// store.dispatch('addWidget', setting)
|
|
||||||
setting.uuid = `bg-${(new Date()).getTime()}`
|
setting.uuid = `bg-${(new Date()).getTime()}`
|
||||||
widgetStore.dWidgets.unshift(setting)
|
widgetStore.dWidgets.unshift(setting)
|
||||||
widgetStore.selectWidget({
|
widgetStore.selectWidget({
|
||||||
uuid: widgetStore.dWidgets[0].uuid,
|
uuid: widgetStore.dWidgets[0].uuid,
|
||||||
})
|
})
|
||||||
// store.dispatch('selectWidget', {
|
|
||||||
// uuid: store.getters.dWidgets[0].uuid,
|
|
||||||
// })
|
|
||||||
deleteBg()
|
deleteBg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打开
|
||||||
|
function openSizeEdit() {
|
||||||
|
sizeEditRef.value?.open()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
#page-style {
|
#page-style {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
.sd-edit {
|
||||||
.position-size {
|
cursor: pointer;
|
||||||
display: flex;
|
color: #666666;
|
||||||
// justify-content: space-between;
|
font-size: 22px;
|
||||||
width: 100%;
|
}
|
||||||
.number-input {
|
.sd-edit:hover {
|
||||||
flex: 0.25;
|
color: #333333;
|
||||||
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.select {
|
.select {
|
@ -68,38 +68,12 @@ function alignAction(item: TIconItemSelectData) {
|
|||||||
uuid: element.uuid,
|
uuid: element.uuid,
|
||||||
group,
|
group,
|
||||||
})
|
})
|
||||||
// store.dispatch('updateAlign', {
|
|
||||||
// align: item.value,
|
|
||||||
// uuid: element.uuid,
|
|
||||||
// group,
|
|
||||||
// })
|
|
||||||
});
|
});
|
||||||
historyStore.pushHistory()
|
historyStore.pushHistory()
|
||||||
// store.dispatch('pushHistory')
|
|
||||||
// pushHistory()
|
|
||||||
})
|
})
|
||||||
// store.dispatch('getCombined').then((group) => {
|
|
||||||
// sWidgets.forEach((element: Record<string, any>) => {
|
|
||||||
// store.dispatch('updateAlign', {
|
|
||||||
// align: item.value,
|
|
||||||
// uuid: element.uuid,
|
|
||||||
// group,
|
|
||||||
// })
|
|
||||||
// // updateAlign({
|
|
||||||
// // align: item.value,
|
|
||||||
// // uuid: element.uuid,
|
|
||||||
// // group,
|
|
||||||
// // })
|
|
||||||
// });
|
|
||||||
// store.dispatch('pushHistory')
|
|
||||||
// // pushHistory()
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
function layerChange(newLayer: TdWidgetData[]) {
|
function layerChange(newLayer: TdWidgetData[]) {
|
||||||
widgetStore.setDWidgets(newLayer.toReversed())
|
widgetStore.setDWidgets(newLayer.toReversed())
|
||||||
// store.commit('setDWidgets', newLayer.toReversed())
|
|
||||||
|
|
||||||
// store.commit('setShowMoveable', false)
|
|
||||||
controlStore.setShowMoveable(false)
|
controlStore.setShowMoveable(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-27 15:16:07
|
* @Date: 2021-08-27 15:16:07
|
||||||
* @Description: 背景图
|
* @Description: 背景图
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-11 01:42:36
|
* @LastEditTime: 2024-04-09 22:29:51
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
@ -50,13 +50,10 @@ type TState = {
|
|||||||
bgList: TGetImageListResult[]
|
bgList: TGetImageListResult[]
|
||||||
showList: boolean
|
showList: boolean
|
||||||
colors: string[]
|
colors: string[]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { model } = defineProps<TProps>()
|
const { model } = defineProps<TProps>()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const pageStore = useCanvasStore()
|
const pageStore = useCanvasStore()
|
||||||
const widgetStore = useWidgetStore()
|
const widgetStore = useWidgetStore()
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-27 15:16:07
|
* @Date: 2021-08-27 15:16:07
|
||||||
* @Description: 素材列表,主要用于文字组合列表
|
* @Description: 素材列表,主要用于文字组合列表
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-02-29 16:54:28
|
* @LastEditTime: 2024-04-09 22:30:10
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
@ -55,7 +55,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, onMounted } from 'vue'
|
import { reactive, onMounted } from 'vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
||||||
import DragHelper from '@/common/hooks/dragHelper'
|
import DragHelper from '@/common/hooks/dragHelper'
|
||||||
import setItem2Data from '@/common/methods/DesignFeatures/setImage'
|
import setItem2Data from '@/common/methods/DesignFeatures/setImage'
|
||||||
|
@ -118,13 +118,14 @@ function checkHeight() {
|
|||||||
isLess && load()
|
isLess && load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hideReplacePrompt: any = localStorage.getItem('hide_replace_prompt')
|
||||||
async function selectItem(item: IGetTempListData) {
|
async function selectItem(item: IGetTempListData) {
|
||||||
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
if (!hideReplacePrompt && dHistoryParams.value.length > 0) {
|
||||||
if (dHistoryParams.value.length > 0) {
|
const doNotPrompt = await useConfirm('添加到作品', '模板内容将替换页面内容', 'warning', {confirmButtonText: '知道了',cancelButtonText: '不再提示'})
|
||||||
const isPass = await useConfirm('提示', '使用模板后,当前页面将会被替换,是否继续', 'warning')
|
if (!doNotPrompt) {
|
||||||
if (!isPass) {
|
localStorage.setItem('hide_replace_prompt', '1')
|
||||||
return false
|
hideReplacePrompt = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
userStore.managerEdit(false)
|
userStore.managerEdit(false)
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-07-29 18:31:27
|
* @Date: 2021-07-29 18:31:27
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2022-04-07 23:26:51
|
* @LastEditTime: 2024-04-10 07:36:58
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="icon-item-select">
|
<div class="icon-item-select">
|
||||||
<span v-if="label" class="label">{{ label }}</span>
|
<span v-if="label" class="label">{{ label }}</span>
|
||||||
<ul class="list btn__bar flex">
|
<ul class="list btn__bar flex">
|
||||||
<el-tooltip v-for="(item, index) in data" :key="index" class="item" effect="dark" :content="item.tip" placement="top" :auto-close="400">
|
<el-tooltip v-for="(item, index) in data" :key="index" class="item" effect="dark" :content="item.tip" placement="top" :show-after="300" >
|
||||||
<li :class="{ 'list-item': true, active: item.select }" @click="selectItem(item)">
|
<li :class="{ 'list-item': true, active: item.select }" @click="selectItem(item)">
|
||||||
<i :class="`${item.extraIcon ? 'icon' : 'iconfont'} ${item.icon}`"></i>
|
<i :class="`${item.extraIcon ? 'icon' : 'iconfont'} ${item.icon}`"></i>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-05 07:31:45
|
||||||
|
* @Description:
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-10 00:34:21
|
||||||
|
*/
|
||||||
// const prefix = import.meta.env
|
// const prefix = import.meta.env
|
||||||
const prefix = process.env
|
const prefix = process.env
|
||||||
|
|
||||||
@ -16,7 +23,7 @@ export default {
|
|||||||
IMG_URL: 'https://store.palxp.cn/', // 七牛云资源地址
|
IMG_URL: 'https://store.palxp.cn/', // 七牛云资源地址
|
||||||
// ICONFONT_URL: '//at.alicdn.com/t/font_3223711_74mlzj4jdue.css',
|
// ICONFONT_URL: '//at.alicdn.com/t/font_3223711_74mlzj4jdue.css',
|
||||||
ICONFONT_URL: '//at.alicdn.com/t/font_2717063_ypy8vprc3b.css?display=swap',
|
ICONFONT_URL: '//at.alicdn.com/t/font_2717063_ypy8vprc3b.css?display=swap',
|
||||||
ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_8r5ffak8d5q.css',
|
ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_ljv2tbkwgqp.css',
|
||||||
QINIUYUN_PLUGIN: 'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/qiniu-js/2.5.5/qiniu.min.js',
|
QINIUYUN_PLUGIN: 'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/qiniu-js/2.5.5/qiniu.min.js',
|
||||||
supportSubFont: true, // 是否开启服务端字体压缩
|
supportSubFont: true, // 是否开启服务端字体压缩
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2022-03-03 14:13:16
|
* @Date: 2022-03-03 14:13:16
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>, Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-02-26 17:54:00
|
* @LastEditTime: 2024-04-08 18:19:35
|
||||||
*/
|
*/
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
// import store from './store'
|
|
||||||
import utils from './utils'
|
import utils from './utils'
|
||||||
import 'normalize.css/normalize.css'
|
import 'normalize.css/normalize.css'
|
||||||
import '@/assets/styles/index.less'
|
import '@/assets/styles/index.less'
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-17 15:00:00
|
* @Date: 2024-03-17 15:00:00
|
||||||
* @Description: Base全局状态管理
|
* @Description: Base全局状态管理
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-18 21:00:00
|
* @LastEditTime: 2024-04-08 17:00:12
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Store, defineStore } from 'pinia'
|
import { Store, defineStore } from 'pinia'
|
||||||
@ -13,7 +13,7 @@ import { Store, defineStore } from 'pinia'
|
|||||||
|
|
||||||
type TStoreBaseState = {
|
type TStoreBaseState = {
|
||||||
loading: boolean | null
|
loading: boolean | null
|
||||||
scroll: boolean
|
watermark: string | string[]
|
||||||
/** fonts */
|
/** fonts */
|
||||||
fonts: string[]
|
fonts: string[]
|
||||||
}
|
}
|
||||||
@ -21,13 +21,14 @@ type TStoreBaseState = {
|
|||||||
type TUserAction = {
|
type TUserAction = {
|
||||||
hideLoading: () => void
|
hideLoading: () => void
|
||||||
setFonts: (list: string[]) => void
|
setFonts: (list: string[]) => void
|
||||||
|
changeWatermark: (e: string[] | string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base全局状态管理 */
|
/** Base全局状态管理 */
|
||||||
const useBaseStore = defineStore<'base', TStoreBaseState, {}, TUserAction>('base', {
|
const useBaseStore = defineStore<'base', TStoreBaseState, {}, TUserAction>('base', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
loading: null,
|
loading: null,
|
||||||
scroll: true,
|
watermark: ['迅排设计', 'poster-design'],
|
||||||
fonts: [], // 缓存字体列表
|
fonts: [], // 缓存字体列表
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
@ -40,6 +41,9 @@ const useBaseStore = defineStore<'base', TStoreBaseState, {}, TUserAction>('base
|
|||||||
setFonts(list: string[]) {
|
setFonts(list: string[]) {
|
||||||
this.fonts = list
|
this.fonts = list
|
||||||
},
|
},
|
||||||
|
changeWatermark(wm: any) {
|
||||||
|
this.watermark = wm
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* @Date: 2024-03-18 21:00:00
|
* @Date: 2024-03-18 21:00:00
|
||||||
* @Description: 画布全局配置
|
* @Description: 画布全局配置
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-05 14:52:06
|
* @LastEditTime: 2024-04-08 21:23:38
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Store, defineStore } from 'pinia'
|
import { Store, defineStore } from 'pinia'
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-18 21:00:00
|
* @Date: 2024-03-18 21:00:00
|
||||||
* @Description: Store方法export
|
* @Description: Store方法export
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-28 14:00:00
|
* @LastEditTime: 2024-04-10 18:01:14
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCanvasStore, useControlStore } from "@/store"
|
import { useCanvasStore, useControlStore } from '@/store'
|
||||||
import { TWidgetStore } from ".."
|
import { TWidgetStore } from '..'
|
||||||
import { updateGroupSize } from "."
|
import { updateGroupSize } from '.'
|
||||||
|
|
||||||
export type TInitResize = {
|
export type TInitResize = {
|
||||||
startX: number
|
startX: number
|
||||||
@ -19,6 +19,18 @@ export type TInitResize = {
|
|||||||
height: number
|
height: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TSize = {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TdResizePayload = {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
/** 方向 */
|
||||||
|
dirs: 'top' | 'left' | 'bottom' | 'right'
|
||||||
|
}
|
||||||
|
|
||||||
/** 设置 resize 操作的初始值 */
|
/** 设置 resize 操作的初始值 */
|
||||||
export function initDResize(store: TWidgetStore, payload: TInitResize) {
|
export function initDResize(store: TWidgetStore, payload: TInitResize) {
|
||||||
const mouseXY = store.dMouseXY
|
const mouseXY = store.dMouseXY
|
||||||
@ -32,24 +44,14 @@ export function initDResize(store: TWidgetStore, payload: TInitResize) {
|
|||||||
resizeWH.height = payload.height
|
resizeWH.height = payload.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export type TdResizePayload = {
|
|
||||||
x: number
|
|
||||||
y: number
|
|
||||||
/** 方向 */
|
|
||||||
dirs: "top" | "left" | "bottom" | "right"
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新组件宽高 */
|
/** 更新组件宽高 */
|
||||||
export function dResize(store: TWidgetStore, { x, y, dirs }: TdResizePayload) {
|
export function dResize(store: TWidgetStore, { x, y, dirs }: TdResizePayload) {
|
||||||
const pageStore = useCanvasStore()
|
|
||||||
const canvasStore = useCanvasStore()
|
const canvasStore = useCanvasStore()
|
||||||
const controlStore = useControlStore()
|
const controlStore = useControlStore()
|
||||||
|
|
||||||
controlStore.setdResizeing(true)
|
controlStore.setdResizeing(true)
|
||||||
// store.state.dResizeing = true
|
|
||||||
|
|
||||||
const page = pageStore.dPage
|
const page = canvasStore.dPage
|
||||||
const target = store.dActiveElement
|
const target = store.dActiveElement
|
||||||
const mouseXY = store.dMouseXY
|
const mouseXY = store.dMouseXY
|
||||||
const widgetXY = store.dActiveWidgetXY
|
const widgetXY = store.dActiveWidgetXY
|
||||||
@ -105,22 +107,39 @@ export function dResize(store: TWidgetStore, { x, y, dirs }: TdResizePayload) {
|
|||||||
}
|
}
|
||||||
if (parent.uuid !== '-1') {
|
if (parent.uuid !== '-1') {
|
||||||
updateGroupSize(store, parent.uuid)
|
updateGroupSize(store, parent.uuid)
|
||||||
// store.dispatch('updateGroupSize', parent.uuid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasStore.reChangeCanvas()
|
canvasStore.reChangeCanvas()
|
||||||
// store.dispatch('reChangeCanvas')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TResize = {
|
export function resize(store: TWidgetStore, size: TSize) {
|
||||||
width: number
|
const { width, height } = size
|
||||||
height: number
|
const target = store.dActiveElement
|
||||||
}
|
|
||||||
|
|
||||||
export function resize(state: TWidgetStore, data: TResize) {
|
|
||||||
const { width, height } = data
|
|
||||||
const target = state.dActiveElement
|
|
||||||
if (!target) return target
|
if (!target) return target
|
||||||
target.width = width
|
target.width = width
|
||||||
target.height = height
|
target.height = height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 自适应适配所有元素 */
|
||||||
|
export function autoResizeAll(store: TWidgetStore, lastPageSize: TSize) {
|
||||||
|
if (!lastPageSize) return
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
|
const { width: lastWidth, height: lastHeight } = lastPageSize
|
||||||
|
const { width: pageWidth, height: pageHeight } = canvasStore.dPage
|
||||||
|
const originWHRatio = lastWidth / lastHeight // 原始比例
|
||||||
|
const WHRatio = pageWidth / pageHeight // 当前比例
|
||||||
|
const changeFn = originWHRatio > WHRatio ? 'max' : 'min'
|
||||||
|
const degree = [pageWidth / lastWidth, pageHeight / lastHeight]
|
||||||
|
const ratio = Math[changeFn](...degree)
|
||||||
|
const pageDiff = (pageWidth - lastWidth) / 2
|
||||||
|
for (const widget of store.dWidgets) {
|
||||||
|
const originWidth = widget.width
|
||||||
|
let diff = 0
|
||||||
|
if (widget.type === 'w-text') {
|
||||||
|
widget.fontSize && (widget.fontSize *= ratio)
|
||||||
|
} else widget.height *= ratio
|
||||||
|
widget.width *= ratio
|
||||||
|
diff = (originWidth - widget.width) / 2
|
||||||
|
widget.left = widget.left + diff + pageDiff
|
||||||
|
widget.top *= degree[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -44,8 +44,6 @@ export function selectWidget(store: TWidgetStore, { uuid }: TSelectWidgetData) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
store.dSelectWidgets = []
|
store.dSelectWidgets = []
|
||||||
console.log("uuid", uuid);
|
|
||||||
|
|
||||||
if (uuid === '-1') {
|
if (uuid === '-1') {
|
||||||
store.dActiveElement = pageStore.dPage
|
store.dActiveElement = pageStore.dPage
|
||||||
const pageHistory = historyStore.dPageHistory
|
const pageHistory = historyStore.dPageHistory
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-18 21:00:00
|
* @Date: 2024-03-18 21:00:00
|
||||||
* @Description: Store方法export
|
* @Description: Store方法export
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-28 14:00:00
|
* @LastEditTime: 2024-04-10 08:17:16
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Store, defineStore } from "pinia";
|
import { Store, defineStore } from "pinia";
|
||||||
import { TInidDMovePayload, TMovePayload, dMove, initDMove, setDropOver, setMouseEvent, setdActiveElement, updateGroupSize, updateHoverUuid } from "./actions";
|
import { TInidDMovePayload, TMovePayload, dMove, initDMove, setDropOver, setMouseEvent, setdActiveElement, updateGroupSize, updateHoverUuid } from "./actions";
|
||||||
import { TPageState } from "@/store/design/canvas/d";
|
import { TPageState } from "@/store/design/canvas/d";
|
||||||
import { TInitResize, TResize, TdResizePayload, dResize, initDResize, resize } from "./actions/resize";
|
import { TInitResize, TSize, TdResizePayload, dResize, initDResize, resize, autoResizeAll } from "./actions/resize";
|
||||||
import { TUpdateWidgetMultiplePayload, TUpdateWidgetPayload, TsetWidgetStyleData, addWidget, deleteWidget, setDWidgets, setWidgetStyle, updateWidgetData, updateWidgetMultiple, lockWidgets } from "./actions/widget";
|
import { TUpdateWidgetMultiplePayload, TUpdateWidgetPayload, TsetWidgetStyleData, addWidget, deleteWidget, setDWidgets, setWidgetStyle, updateWidgetData, updateWidgetMultiple, lockWidgets } from "./actions/widget";
|
||||||
import { addGroup } from "./actions/group";
|
import { addGroup } from "./actions/group";
|
||||||
import { setTemplate } from "./actions/template";
|
import { setTemplate } from "./actions/template";
|
||||||
@ -113,12 +113,13 @@ type TAction = {
|
|||||||
/** 设置拖拽时在哪个图层 */
|
/** 设置拖拽时在哪个图层 */
|
||||||
setDropOver: (uuid: string) => void
|
setDropOver: (uuid: string) => void
|
||||||
setSelectItem: (data: TselectItem) => void
|
setSelectItem: (data: TselectItem) => void
|
||||||
resize: (data: TResize) => void
|
resize: (data: TSize) => void
|
||||||
setWidgetStyle: (data: TsetWidgetStyleData) => void
|
setWidgetStyle: (data: TsetWidgetStyleData) => void
|
||||||
setDWidgets: (data: TdWidgetData[]) => void
|
setDWidgets: (data: TdWidgetData[]) => void
|
||||||
lockWidgets: () => void
|
lockWidgets: () => void
|
||||||
setMouseEvent: (e: MouseEvent | null) => void
|
setMouseEvent: (e: MouseEvent | null) => void
|
||||||
setdActiveElement: (data: TdWidgetData) => void
|
setdActiveElement: (data: TdWidgetData) => void
|
||||||
|
autoResizeAll: (data: TSize) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("widgetStore", {
|
const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("widgetStore", {
|
||||||
@ -180,6 +181,7 @@ const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("
|
|||||||
lockWidgets() { lockWidgets(this) },
|
lockWidgets() { lockWidgets(this) },
|
||||||
setMouseEvent(event) { setMouseEvent(this, event) },
|
setMouseEvent(event) { setMouseEvent(this, event) },
|
||||||
setdActiveElement(data) { setdActiveElement(this, data) },
|
setdActiveElement(data) { setdActiveElement(this, data) },
|
||||||
|
autoResizeAll(data) { autoResizeAll(this, data) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-07-14 11:43:13
|
* @Date: 2021-07-14 11:43:13
|
||||||
* @Description: 全局组件注册方法
|
* @Description: 全局组件导入
|
||||||
* @LastEditors: ShawnPhang
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2021-08-10 17:39:01
|
* @LastEditTime: 2024-04-08 18:23:15
|
||||||
*/
|
*/
|
||||||
// import { Button, Field, Divider, NavBar, Toast, Popup } from 'vant'
|
|
||||||
import coms from '@/components/modules'
|
import coms from '@/components/modules'
|
||||||
|
import pageStyle from '@/components/modules/layout/designBoard/pageStyle.vue'
|
||||||
import { App } from 'vue'
|
import { App } from 'vue'
|
||||||
|
|
||||||
export default (Vue: App) => {
|
export default (Vue: App) => {
|
||||||
coms(Vue)
|
coms(Vue)
|
||||||
// Vue.component(Button.name, Button)
|
Vue.component('page-style', pageStyle) // 背景属性已不在 modules/widgets 中,单独注册
|
||||||
// Vue.use(Field).use(Divider).use(NavBar).use(Toast).use(Popup)
|
// Vue.use(Field).use(Divider).use(NavBar).use(Toast).use(Popup)
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { StyleValue, onMounted, reactive, nextTick } from 'vue'
|
import { StyleValue, onMounted, reactive, nextTick } from 'vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
// import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
|
|
||||||
import Preload from '@/utils/plugins/preload'
|
import Preload from '@/utils/plugins/preload'
|
||||||
import FontFaceObserver from 'fontfaceobserver'
|
import FontFaceObserver from 'fontfaceobserver'
|
||||||
import { fontWithDraw, font2style } from '@/utils/widgets/loadFontRule'
|
import { fontWithDraw, font2style } from '@/utils/widgets/loadFontRule'
|
||||||
import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
||||||
import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
|
import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
|
||||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
@ -50,7 +48,7 @@ onMounted(() => {
|
|||||||
async function load() {
|
async function load() {
|
||||||
let backgroundImage = ''
|
let backgroundImage = ''
|
||||||
let loadFlag = false
|
let loadFlag = false
|
||||||
const { id, tempid, tempType: type } = route.query
|
const { id, tempid, tempType: type = 0 } = route.query
|
||||||
if (id || tempid) {
|
if (id || tempid) {
|
||||||
const postData = {
|
const postData = {
|
||||||
id: Number(id || tempid),
|
id: Number(id || tempid),
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastUpdateContent: Support typescript
|
* @LastUpdateContent: Support typescript
|
||||||
* @LastEditTime: 2024-04-05 05:34:43
|
* @LastEditTime: 2024-04-10 07:16:48
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div id="page-design-index" ref="pageDesignIndex" class="page-design-bg-color">
|
<div id="page-design-index" ref="pageDesignIndex" class="page-design-bg-color">
|
||||||
@ -59,6 +59,8 @@
|
|||||||
/>
|
/>
|
||||||
<!-- 漫游导航 -->
|
<!-- 漫游导航 -->
|
||||||
<Tour ref="tourRef" :steps="[ref1, ref2, ref3, ref4]" />
|
<Tour ref="tourRef" :steps="[ref1, ref2, ref3, ref4]" />
|
||||||
|
<!-- 创建设计 -->
|
||||||
|
<createDesign ref="createDesignRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -66,7 +68,7 @@
|
|||||||
import _config from '../config'
|
import _config from '../config'
|
||||||
import {
|
import {
|
||||||
CSSProperties, computed, nextTick,
|
CSSProperties, computed, nextTick,
|
||||||
onBeforeUnmount, onMounted, reactive, ref,
|
onBeforeUnmount, onMounted, reactive, ref, Ref
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue'
|
import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue'
|
||||||
import Moveable from '@/components/business/moveable/Moveable.vue'
|
import Moveable from '@/components/business/moveable/Moveable.vue'
|
||||||
@ -74,18 +76,16 @@ import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
|||||||
import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
|
import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
|
||||||
import lineGuides from '@/components/modules/layout/lineGuides.vue'
|
import lineGuides from '@/components/modules/layout/lineGuides.vue'
|
||||||
import shortcuts from '@/mixins/shortcuts'
|
import shortcuts from '@/mixins/shortcuts'
|
||||||
// import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
|
|
||||||
import HeaderOptions from './components/HeaderOptions.vue'
|
import HeaderOptions from './components/HeaderOptions.vue'
|
||||||
import Folder from './components/Folder.vue'
|
import Folder from './components/Folder.vue'
|
||||||
import Helper from './components/Helper.vue'
|
import Helper from './components/Helper.vue'
|
||||||
import ProgressLoading from '@/components/common/ProgressLoading/download.vue'
|
import ProgressLoading from '@/components/common/ProgressLoading/download.vue'
|
||||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useCanvasStore, useControlStore, useHistoryStore, useWidgetStore, useGroupStore } from '@/store'
|
import { useCanvasStore, useControlStore, useHistoryStore, useWidgetStore, useGroupStore } from '@/store'
|
||||||
import type { ButtonInstance } from 'element-plus'
|
import type { ButtonInstance } from 'element-plus'
|
||||||
import Tour from './components/Tour.vue'
|
import Tour from './components/Tour.vue'
|
||||||
|
import createDesign from '@/components/business/create-design'
|
||||||
|
|
||||||
const ref1 = ref<ButtonInstance>()
|
const ref1 = ref<ButtonInstance>()
|
||||||
const ref2 = ref<ButtonInstance>()
|
const ref2 = ref<ButtonInstance>()
|
||||||
@ -111,7 +111,6 @@ const groupStore = useGroupStore()
|
|||||||
const { dPage } = storeToRefs(useCanvasStore())
|
const { dPage } = storeToRefs(useCanvasStore())
|
||||||
const { dZoom } = storeToRefs(useCanvasStore())
|
const { dZoom } = storeToRefs(useCanvasStore())
|
||||||
const { dHistoryParams } = storeToRefs(useHistoryStore())
|
const { dHistoryParams } = storeToRefs(useHistoryStore())
|
||||||
// const { dActiveElement, dCopyElement } = storeToRefs(widgetStore)
|
|
||||||
|
|
||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
style: {
|
style: {
|
||||||
@ -128,7 +127,7 @@ const state = reactive<TState>({
|
|||||||
const optionsRef = ref<typeof HeaderOptions | null>(null)
|
const optionsRef = ref<typeof HeaderOptions | null>(null)
|
||||||
const zoomControlRef = ref<typeof zoomControl | null>(null)
|
const zoomControlRef = ref<typeof zoomControl | null>(null)
|
||||||
const controlStore = useControlStore()
|
const controlStore = useControlStore()
|
||||||
const route = useRoute()
|
const createDesignRef: Ref<typeof createDesign | null> = ref(null)
|
||||||
|
|
||||||
const beforeUnload = function (e: Event): any {
|
const beforeUnload = function (e: Event): any {
|
||||||
if (dHistoryParams.value.length > 0) {
|
if (dHistoryParams.value.length > 0) {
|
||||||
@ -211,16 +210,13 @@ function downloadCancel() {
|
|||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
// 初始化加载页面
|
// 初始化加载页面
|
||||||
const { id, tempid, tempType } = route.query
|
|
||||||
if (!optionsRef.value) return
|
if (!optionsRef.value) return
|
||||||
optionsRef.value.load(id, tempid, tempType, async () => {
|
optionsRef.value.load(async () => {
|
||||||
if (!zoomControlRef.value) return
|
if (!zoomControlRef.value) return
|
||||||
// await nextTick()
|
// await nextTick()
|
||||||
// zoomControlRef.value.screenChange()
|
// zoomControlRef.value.screenChange()
|
||||||
|
|
||||||
// 初始化激活的控件为page
|
// 初始化激活的控件为page
|
||||||
widgetStore.selectWidget({ uuid: '-1' })
|
widgetStore.selectWidget({ uuid: '-1' })
|
||||||
// store.dispatch('selectWidget', { uuid: '-1' })
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +242,10 @@ const fns: any = {
|
|||||||
download: () => {
|
download: () => {
|
||||||
optionsRef.value?.download()
|
optionsRef.value?.download()
|
||||||
},
|
},
|
||||||
changeLineGuides
|
changeLineGuides,
|
||||||
|
newDesign: () => {
|
||||||
|
createDesignRef.value?.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const dealWith = (fnName: string, params?: any) => {
|
const dealWith = (fnName: string, params?: any) => {
|
||||||
fns[fnName](params)
|
fns[fnName](params)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-04-03 19:15:21
|
* @Date: 2024-04-03 19:15:21
|
||||||
* @Description: 文件
|
* @Description: 文件
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-05 06:01:20
|
* @LastEditTime: 2024-04-10 07:16:00
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<el-dropdown trigger="click" size="large" placement="bottom-start">
|
<el-dropdown trigger="click" size="large" placement="bottom-start">
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item><div class="item">创建设计</div></el-dropdown-item>
|
<el-dropdown-item><div @click="$emit('select', 'newDesign')" class="item">创建设计</div></el-dropdown-item>
|
||||||
<el-dropdown-item @click="openPSD">导入文件</el-dropdown-item>
|
<el-dropdown-item @click="openPSD">导入文件</el-dropdown-item>
|
||||||
<el-dropdown-item @click="$emit('select', 'save')" divided>保存</el-dropdown-item>
|
<el-dropdown-item @click="$emit('select', 'save')" divided>保存</el-dropdown-item>
|
||||||
<el-dropdown-item @click="$emit('select', 'download')">导出文件</el-dropdown-item>
|
<el-dropdown-item @click="$emit('select', 'download')">导出文件</el-dropdown-item>
|
||||||
@ -25,8 +25,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// import { ref } from 'vue'
|
// import { ref, Ref } from 'vue'
|
||||||
import { useRouter} from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ElDropdown, ElDropdownItem, ElDropdownMenu } from 'element-plus'
|
import { ElDropdown, ElDropdownItem, ElDropdownMenu } from 'element-plus'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-01-12 11:26:53
|
* @Date: 2022-01-12 11:26:53
|
||||||
* @Description: 顶部操作按钮组
|
* @Description: 顶部操作按钮组
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-05 05:37:53
|
* @LastEditTime: 2024-04-09 23:39:24
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="top-title"><el-input v-model="state.title" placeholder="未命名的设计" class="input-wrap" /></div>
|
<div class="top-title"><el-input v-model="state.title" placeholder="未命名的设计" class="input-wrap" /></div>
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<!-- <el-button @click="$store.commit('managerEdit', false)">取消</el-button> -->
|
<!-- <el-button @click="$store.commit('managerEdit', false)">取消</el-button> -->
|
||||||
<div class="divide__line">|</div>
|
<div class="divide__line">|</div>
|
||||||
</template>
|
</template>
|
||||||
|
<watermark-option style="margin-right: .5rem;" />
|
||||||
<!-- <el-button @click="draw">绘制(测试)</el-button> -->
|
<!-- <el-button @click="draw">绘制(测试)</el-button> -->
|
||||||
<!-- <copyRight> -->
|
<!-- <copyRight> -->
|
||||||
<slot />
|
<slot />
|
||||||
@ -39,6 +40,7 @@ import _config from '@/config'
|
|||||||
import useConfirm from '@/common/methods/confirm'
|
import useConfirm from '@/common/methods/confirm'
|
||||||
import { useControlStore, useHistoryStore, useCanvasStore, useUserStore, useWidgetStore } from '@/store/index'
|
import { useControlStore, useHistoryStore, useCanvasStore, useUserStore, useWidgetStore } from '@/store/index'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
import watermarkOption from './Watermark.vue'
|
||||||
|
|
||||||
type TProps = {
|
type TProps = {
|
||||||
modelValue?: boolean
|
modelValue?: boolean
|
||||||
@ -51,6 +53,7 @@ type TEmits = {
|
|||||||
|
|
||||||
type TState= {
|
type TState= {
|
||||||
stateBollean: boolean,
|
stateBollean: boolean,
|
||||||
|
wmBollean: boolean,
|
||||||
title: string,
|
title: string,
|
||||||
loading: boolean,
|
loading: boolean,
|
||||||
}
|
}
|
||||||
@ -80,6 +83,7 @@ const { dHistory, dPageHistory } = storeToRefs(useHistoryStore())
|
|||||||
|
|
||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
stateBollean: false,
|
stateBollean: false,
|
||||||
|
wmBollean: false,
|
||||||
title: '',
|
title: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
})
|
})
|
||||||
@ -91,7 +95,6 @@ async function save(hasCover: boolean = false) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// store.commit('setShowMoveable', false) // 清理掉上一次的选择框
|
|
||||||
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
|
||||||
// console.log(proxy?.dPage, proxy?.dWidgets)
|
// console.log(proxy?.dPage, proxy?.dWidgets)
|
||||||
@ -189,11 +192,17 @@ async function saveTemp() {
|
|||||||
|
|
||||||
// ...mapActions(['pushHistory', 'addGroup']),
|
// ...mapActions(['pushHistory', 'addGroup']),
|
||||||
|
|
||||||
async function load(id: number, tempId: number, type: number, cb: () => void) {
|
async function load(cb: () => void) {
|
||||||
|
const { id, tempid: tempId, tempType: type, w_h } = route.query
|
||||||
if (route.name !== 'Draw') {
|
if (route.name !== 'Draw') {
|
||||||
await useFontStore.init() // 初始化加载字体
|
await useFontStore.init() // 初始化加载字体
|
||||||
}
|
}
|
||||||
const apiName = tempId && !id ? 'getTempDetail' : 'getWorks'
|
const apiName = tempId && !id ? 'getTempDetail' : 'getWorks'
|
||||||
|
if (w_h) {
|
||||||
|
const wh: any = w_h.toString().split('*')
|
||||||
|
wh[0] && (dPage.value.width = wh[0])
|
||||||
|
wh[1] && (dPage.value.height = wh[1])
|
||||||
|
}
|
||||||
if (!id && !tempId) {
|
if (!id && !tempId) {
|
||||||
cb()
|
cb()
|
||||||
return
|
return
|
||||||
|
22
src/views/components/Watermark.vue
Normal file
22
src/views/components/Watermark.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-08 16:50:04
|
||||||
|
* @Description: 画布加水印
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-08 18:00:37
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<el-switch v-model="wmBollean" @change="wmChange" size="large" inline-prompt style="--el-switch-off-color: #9999999e" active-text="移除水印" inactive-text="官方水印" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useBaseStore } from '@/store'
|
||||||
|
|
||||||
|
const baseStore = useBaseStore()
|
||||||
|
const wmBollean = ref(false)
|
||||||
|
|
||||||
|
function wmChange(isRemove: string | number | boolean) {
|
||||||
|
baseStore.changeWatermark(isRemove ? '' : ['迅排设计', 'poster-design'])
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user