mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
feat: support multi-canvas & adaptive canvas
This commit is contained in:
parent
22ecc9900d
commit
b739528c21
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-01-17 16:06:30
|
* @Date: 2022-01-17 16:06:30
|
||||||
* @Description: Design Palxp
|
* @Description: Design Palxp
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-09-19 18:36:13
|
* @LastEditTime: 2024-04-13 18:16:44
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
@ -12,6 +12,7 @@
|
|||||||
<link rel="icon" href="/favicon.svg" />
|
<link rel="icon" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>迅排设计 - 轻松创意,迅捷排版,感受云上设计带来的乐趣!</title>
|
<title>迅排设计 - 轻松创意,迅捷排版,感受云上设计带来的乐趣!</title>
|
||||||
|
<script> var _hmt = _hmt || [] </script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -2,14 +2,18 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-08-19 18:43:22
|
* @Date: 2021-08-19 18:43:22
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-07-24 13:01:10
|
* @LastEditTime: 2024-04-16 15:37:54
|
||||||
*/
|
*/
|
||||||
import fetch from '@/utils/axios'
|
import fetch from '@/utils/axios'
|
||||||
import _config from '@/config'
|
import _config from '@/config'
|
||||||
|
|
||||||
|
function serialize(obj: any) {
|
||||||
|
return Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
|
||||||
|
}
|
||||||
|
|
||||||
// const screenshot_url = window.location.protocol + '//' + window.location.host + '/draw'
|
// const screenshot_url = window.location.protocol + '//' + window.location.host + '/draw'
|
||||||
export const download = (params: Type.Object = {}) => `${_config.SCREEN_URL}/api/screenshots?id=${params.id}&width=${params.width}&height=${params.height}`
|
export const download = (params: Type.Object = {}) => `${_config.SCREEN_URL}/api/screenshots?${serialize(params)}`
|
||||||
|
|
||||||
type IGetTempListParam = {
|
type IGetTempListParam = {
|
||||||
search: string
|
search: string
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
@import './color.less';
|
@import './color.less';
|
||||||
// design index page
|
// design index page
|
||||||
|
|
||||||
@color4: #50555b;
|
@color4: #50555b;
|
||||||
@color5: #808080;
|
@color5: #808080;
|
||||||
|
|
||||||
@width0: 1180px;
|
@width0: 1180px;
|
||||||
@width1: 120px;
|
@width1: 120px;
|
||||||
@width2: 100%;
|
@width2: 100%;
|
||||||
|
|
||||||
@height2: 54px;
|
@height2: 54px;
|
||||||
|
|
||||||
|
@canvasBG: #f8f8f8;
|
||||||
|
|
||||||
.page-design-bg-color {
|
.page-design-bg-color {
|
||||||
// background-color: #4b678c;
|
// background-color: #4b678c;
|
||||||
// background-color: #4682b4;
|
// background-color: #4682b4;
|
||||||
@ -22,7 +21,7 @@
|
|||||||
min-width: @width0;
|
min-width: @width0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: @width2;
|
width: @width2;
|
||||||
|
background-color: @canvasBG;
|
||||||
.top-nav {
|
.top-nav {
|
||||||
height: @height2;
|
height: @height2;
|
||||||
min-width: @width0;
|
min-width: @width0;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-04-09 11:24:57
|
* @Date: 2024-04-09 11:24:57
|
||||||
* @Description: 创建/编辑画布尺寸
|
* @Description: 创建/编辑画布尺寸
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-10 17:29:15
|
* @LastEditTime: 2024-04-16 17:11:59
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
@ -32,9 +32,10 @@ import { ElCheckbox } from 'element-plus'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import sizeEditor from './sizeEditor.vue'
|
import sizeEditor from './sizeEditor.vue'
|
||||||
import sizes from '@/assets/data/PageSizeData'
|
import sizes from '@/assets/data/PageSizeData'
|
||||||
import { useWidgetStore } from '@/store';
|
import { useWidgetStore, useControlStore } from '@/store';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const controlStore = useControlStore()
|
||||||
const widgetStore = useWidgetStore()
|
const widgetStore = useWidgetStore()
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@ -54,6 +55,7 @@ const applySize = ({ width, height }: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
if (props.params) {
|
if (props.params) {
|
||||||
page.value.width = props.params.width
|
page.value.width = props.params.width
|
||||||
page.value.height = props.params.height
|
page.value.height = props.params.height
|
||||||
|
@ -1,73 +1,67 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-10 23:02:46
|
||||||
|
* @Description: 主画布
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-16 11:34:08
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px', minWidth: (dPage.width * dZoom) / 100 + 120 + 'px' }" >
|
<div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px', minWidth: (dPage.width * dZoom) / 100 + dPresetPadding * 2 + 'px' }">
|
||||||
<div
|
<div
|
||||||
id="out-page"
|
id="out-page"
|
||||||
class="out-page"
|
class="out-page"
|
||||||
:style="{
|
:style="{
|
||||||
width: (dPage.width * dZoom) / 100 + 120 + 'px',
|
padding: dPresetPadding + 'px',
|
||||||
height: (dPage.height * dZoom) / 100 + 120 + 'px',
|
width: (dPage.width * dZoom) / 100 + dPresetPadding * 2 + 'px',
|
||||||
|
height: (dPage.height * dZoom) / 100 + dPresetPadding * 2 + 'px',
|
||||||
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" />
|
<resize-page :width="(dPage.width * dZoom) / 100" :height="(dPage.height * dZoom) / 100" />
|
||||||
<watermark :customStyle="{ height: (dPage.height * dZoom) / 100 + 'px'}">
|
<watermark :customStyle="{ height: (dPage.height * dZoom) / 100 + 'px' }">
|
||||||
<div
|
<div
|
||||||
:id="pageDesignCanvasId"
|
:id="pageDesignCanvasId"
|
||||||
class="design-canvas"
|
class="design-canvas"
|
||||||
:data-type="dPage.type"
|
:data-type="dPage.type"
|
||||||
:data-uuid="dPage.uuid"
|
:data-uuid="dPage.uuid"
|
||||||
:style="{
|
:style="{
|
||||||
width: dPage.width + 'px',
|
width: dPage.width + 'px',
|
||||||
height: dPage.height + 'px',
|
height: dPage.height + 'px',
|
||||||
transform: 'scale(' + dZoom / 100 + ')',
|
transform: 'scale(' + dZoom / 100 + ')',
|
||||||
transformOrigin: (dZoom >= 100 ? 'center' : 'left') + ' top',
|
transformOrigin: (dZoom >= 100 ? 'center' : 'left') + ' top',
|
||||||
backgroundColor: dPage.backgroundGradient ? undefined : dPage.backgroundColor,
|
backgroundColor: dPage.backgroundGradient ? undefined : dPage.backgroundColor,
|
||||||
backgroundImage: dPage.backgroundImage ? `url(${dPage?.backgroundImage})` : dPage.backgroundGradient || undefined,
|
backgroundImage: dPage.backgroundImage ? `url(${dPage?.backgroundImage})` : dPage.backgroundGradient || undefined,
|
||||||
backgroundSize: dPage.backgroundTransform?.x ? 'auto' : 'cover',
|
backgroundSize: dPage.backgroundTransform?.x ? 'auto' : 'cover',
|
||||||
backgroundPositionX: (dPage.backgroundTransform?.x || 0) + 'px',
|
backgroundPositionX: (dPage.backgroundTransform?.x || 0) + 'px',
|
||||||
backgroundPositionY: (dPage.backgroundTransform?.y || 0) + 'px',
|
backgroundPositionY: (dPage.backgroundTransform?.y || 0) + 'px',
|
||||||
opacity: dPage.opacity + (dZoom < 100 ? dPage.tag : 0),
|
opacity: dPage.opacity + (dZoom < 100 ? dPage.tag : 0),
|
||||||
}"
|
}"
|
||||||
@mousemove="dropOver($event)"
|
@mousemove="dropOver($event)"
|
||||||
@drop="drop($event)"
|
@drop="drop($event)"
|
||||||
@mouseup="drop($event)"
|
@mouseup="drop($event)"
|
||||||
>
|
|
||||||
<!-- <grid-size /> -->
|
|
||||||
<component
|
|
||||||
:is="layer.type"
|
|
||||||
v-for="layer in getlayers()"
|
|
||||||
:id="layer.uuid" :key="layer.uuid"
|
|
||||||
:class="['layer', { 'layer-hover': layer.uuid === dHoverUuid || dActiveElement?.parent === layer.uuid, 'layer-no-hover': dActiveElement?.uuid === layer.uuid }]"
|
|
||||||
:data-title="layer.type" :params="layer"
|
|
||||||
:parent="dPage" :data-type="layer.type"
|
|
||||||
:data-uuid="layer.uuid"
|
|
||||||
>
|
>
|
||||||
<template v-if="layer.isContainer">
|
<!-- <grid-size /> -->
|
||||||
<!-- :class="{
|
<component :is="layer.type" v-for="layer in getlayers()" :id="layer.uuid" :key="layer.uuid" :class="['layer', { 'layer-hover': layer.uuid === dHoverUuid || dActiveElement?.parent === layer.uuid, 'layer-no-hover': dActiveElement?.uuid === layer.uuid }]" :data-title="layer.type" :params="layer" :parent="dPage" :data-type="layer.type" :data-uuid="layer.uuid">
|
||||||
|
<template v-if="layer.isContainer">
|
||||||
|
<!-- :class="{
|
||||||
layer: true,
|
layer: true,
|
||||||
'layer-active': getIsActive(widget.uuid),
|
'layer-active': getIsActive(widget.uuid),
|
||||||
'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent,
|
'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent,
|
||||||
'layer-hover': widget.uuid === dHoverUuid,
|
'layer-hover': widget.uuid === dHoverUuid,
|
||||||
}" -->
|
}" -->
|
||||||
<component
|
<component :is="widget.type" v-for="widget in getChilds(layer.uuid)" :key="widget.uuid" child :class="['layer', { 'layer-no-hover': dActiveElement?.uuid !== widget.parent && dActiveElement?.parent !== widget.parent }]" :data-title="widget.type" :params="widget" :parent="layer" :data-type="widget.type" :data-uuid="widget.uuid" />
|
||||||
:is="widget.type"
|
</template>
|
||||||
v-for="widget in getChilds(layer.uuid)"
|
</component>
|
||||||
:key="widget.uuid" child :class="['layer', { 'layer-no-hover':dActiveElement?.uuid !== widget.parent && dActiveElement?.parent !== widget.parent }]"
|
|
||||||
:data-title="widget.type" :params="widget"
|
|
||||||
:parent="layer" :data-type="widget.type"
|
|
||||||
:data-uuid="widget.uuid"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</component>
|
|
||||||
|
|
||||||
<!-- <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>
|
</watermark>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<slot name="bottom" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -84,6 +78,7 @@ 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 resizePage from './comps/resize.vue'
|
||||||
import watermark from './comps/pageWatermark.vue'
|
import watermark from './comps/pageWatermark.vue'
|
||||||
|
|
||||||
// 页面设计组件
|
// 页面设计组件
|
||||||
type TProps = {
|
type TProps = {
|
||||||
pageDesignCanvasId: string
|
pageDesignCanvasId: string
|
||||||
@ -103,11 +98,10 @@ const canvasStore = useCanvasStore()
|
|||||||
const { pageDesignCanvasId } = defineProps<TProps>()
|
const { pageDesignCanvasId } = defineProps<TProps>()
|
||||||
|
|
||||||
const { dPage } = storeToRefs(useCanvasStore())
|
const { dPage } = storeToRefs(useCanvasStore())
|
||||||
const { dZoom, dPaddingTop, dScreen } = storeToRefs(canvasStore)
|
const { dZoom, dPresetPadding, dPaddingTop, dScreen } = storeToRefs(canvasStore)
|
||||||
const { dDraging, showRotatable, dAltDown, dSpaceDown } = storeToRefs(controlStore)
|
const { dDraging, showRotatable, dAltDown, dSpaceDown } = storeToRefs(controlStore)
|
||||||
const { dWidgets, dActiveElement, dSelectWidgets, dHoverUuid } = storeToRefs(widgetStore)
|
const { dWidgets, dActiveElement, dSelectWidgets, dHoverUuid } = storeToRefs(widgetStore)
|
||||||
|
|
||||||
|
|
||||||
let _dropIn: string | null = ''
|
let _dropIn: string | null = ''
|
||||||
let _srcCache: string | null = ''
|
let _srcCache: string | null = ''
|
||||||
|
|
||||||
@ -145,14 +139,14 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// components: {lineGuides},
|
// components: {lineGuides},
|
||||||
// mixins: [moveInit],
|
// mixins: [moveInit],
|
||||||
// ...mapActions(['updateScreen', 'selectWidget', 'deleteWidget', 'addWidget', 'addGroup']),
|
// ...mapActions(['updateScreen', 'selectWidget', 'deleteWidget', 'addWidget', 'addGroup']),
|
||||||
|
|
||||||
// getBackground(data) {
|
// getBackground(data) {
|
||||||
// if (data.startsWith('http')) return `url(${data})`
|
// if (data.startsWith('http')) return `url(${data})`
|
||||||
// if (data.startsWith('linear-gradient')) return data
|
// if (data.startsWith('linear-gradient')) return data
|
||||||
// },
|
// },
|
||||||
|
|
||||||
async function dropOver(e: MouseEvent) {
|
async function dropOver(e: MouseEvent) {
|
||||||
if (!dActiveElement.value) return
|
if (!dActiveElement.value) return
|
||||||
@ -171,7 +165,7 @@ async function dropOver(e: MouseEvent) {
|
|||||||
if (!target) return
|
if (!target) return
|
||||||
const uuid = target.getAttribute('data-uuid')
|
const uuid = target.getAttribute('data-uuid')
|
||||||
|
|
||||||
widgetStore.setDropOver(uuid ?? "-1")
|
widgetStore.setDropOver(uuid ?? '-1')
|
||||||
// store.dispatch('setDropOver', uuid)
|
// store.dispatch('setDropOver', uuid)
|
||||||
|
|
||||||
const imgEl = target?.firstElementChild?.firstElementChild as HTMLImageElement
|
const imgEl = target?.firstElementChild?.firstElementChild as HTMLImageElement
|
||||||
@ -200,7 +194,7 @@ async function drop(e: MouseEvent) {
|
|||||||
const dropIn = _dropIn
|
const dropIn = _dropIn
|
||||||
_dropIn = ''
|
_dropIn = ''
|
||||||
|
|
||||||
widgetStore.setDropOver("-1")
|
widgetStore.setDropOver('-1')
|
||||||
// store.dispatch('setDropOver', '-1')
|
// store.dispatch('setDropOver', '-1')
|
||||||
|
|
||||||
// store.commit('setShowMoveable', false) // 清理上一次的选择
|
// store.commit('setShowMoveable', false) // 清理上一次的选择
|
||||||
@ -238,7 +232,7 @@ async function drop(e: MouseEvent) {
|
|||||||
})
|
})
|
||||||
const half = {
|
const half = {
|
||||||
x: parent.width ? (parent.width * dZoom.value) / 100 / 2 : 0,
|
x: parent.width ? (parent.width * dZoom.value) / 100 / 2 : 0,
|
||||||
y: parent.height ? (parent.height * dZoom.value) / 100 / 2 : 0
|
y: parent.height ? (parent.height * dZoom.value) / 100 / 2 : 0,
|
||||||
}
|
}
|
||||||
componentItem.forEach((element) => {
|
componentItem.forEach((element) => {
|
||||||
element.left += (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
element.left += (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||||
@ -251,7 +245,7 @@ async function drop(e: MouseEvent) {
|
|||||||
// 设置坐标
|
// 设置坐标
|
||||||
const half = {
|
const half = {
|
||||||
x: setting.width ? (setting.width * dZoom.value) / 100 / 2 : 0,
|
x: setting.width ? (setting.width * dZoom.value) / 100 / 2 : 0,
|
||||||
y: setting.height ? (setting.height * dZoom.value) / 100 / 2 : 0
|
y: setting.height ? (setting.height * dZoom.value) / 100 / 2 : 0,
|
||||||
}
|
}
|
||||||
// const half = { x: (this.dDragInitData.offsetX * this.dZoom) / 100, y: (this.dDragInitData.offsetY * this.dZoom) / 100 }
|
// const half = { x: (this.dDragInitData.offsetX * this.dZoom) / 100, y: (this.dDragInitData.offsetY * this.dZoom) / 100 }
|
||||||
setting.left = (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
setting.left = (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||||
@ -267,7 +261,7 @@ async function drop(e: MouseEvent) {
|
|||||||
// store.commit('setShowMoveable', true) // 恢复选择
|
// store.commit('setShowMoveable', true) // 恢复选择
|
||||||
controlStore.setShowMoveable(true) // 恢复选择
|
controlStore.setShowMoveable(true) // 恢复选择
|
||||||
|
|
||||||
const widget = dWidgets.value.find((item: {uuid: string}) => item.uuid === uuid)
|
const widget = dWidgets.value.find((item: { uuid: string }) => item.uuid === uuid)
|
||||||
if (!widget) return
|
if (!widget) return
|
||||||
widget.imgUrl = item.value.url
|
widget.imgUrl = item.value.url
|
||||||
// if (e.target.className.baseVal) {
|
// if (e.target.className.baseVal) {
|
||||||
@ -276,14 +270,13 @@ async function drop(e: MouseEvent) {
|
|||||||
// }
|
// }
|
||||||
} else {
|
} else {
|
||||||
if (dropIn) {
|
if (dropIn) {
|
||||||
const widget = dWidgets.value.find((item: {uuid: string}) => item.uuid == dropIn)
|
const widget = dWidgets.value.find((item: { uuid: string }) => item.uuid == dropIn)
|
||||||
if (!widget) return
|
if (!widget) return
|
||||||
widget.imgUrl = item.value.url
|
widget.imgUrl = item.value.url
|
||||||
console.log('加入+', widget)
|
console.log('加入+', widget)
|
||||||
|
|
||||||
// store.commit('setShowMoveable', true) // 恢复选择
|
// store.commit('setShowMoveable', true) // 恢复选择
|
||||||
controlStore.setShowMoveable(true) // 恢复选择
|
controlStore.setShowMoveable(true) // 恢复选择
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
widgetStore.addWidget(setting as Required<TPageState>)
|
widgetStore.addWidget(setting as Required<TPageState>)
|
||||||
// store.dispatch('addWidget', setting) // 正常加入面板
|
// store.dispatch('addWidget', setting) // 正常加入面板
|
||||||
@ -342,7 +335,7 @@ async function handleSelection(e: MouseEvent) {
|
|||||||
if (type) {
|
if (type) {
|
||||||
let uuid = target.getAttribute('data-uuid')
|
let uuid = target.getAttribute('data-uuid')
|
||||||
if (uuid !== '-1' && !dAltDown.value) {
|
if (uuid !== '-1' && !dAltDown.value) {
|
||||||
let widget = dWidgets.value.find((item: {uuid: string}) => item.uuid === uuid)
|
let widget = dWidgets.value.find((item: { uuid: string }) => item.uuid === uuid)
|
||||||
if (!widget || !dActiveElement.value) return
|
if (!widget || !dActiveElement.value) return
|
||||||
if (widget.parent !== '-1' && widget.parent !== dActiveElement.value.uuid && widget.parent !== dActiveElement.value.parent) {
|
if (widget.parent !== '-1' && widget.parent !== dActiveElement.value.uuid && widget.parent !== dActiveElement.value.parent) {
|
||||||
uuid = widget.parent || null
|
uuid = widget.parent || null
|
||||||
@ -353,7 +346,7 @@ async function handleSelection(e: MouseEvent) {
|
|||||||
// this.$store.commit('setMoveable', false)
|
// this.$store.commit('setMoveable', false)
|
||||||
if (showRotatable.value !== false) {
|
if (showRotatable.value !== false) {
|
||||||
widgetStore.selectWidget({
|
widgetStore.selectWidget({
|
||||||
uuid: uuid ?? " -1",
|
uuid: uuid ?? ' -1',
|
||||||
})
|
})
|
||||||
// store.dispatch('selectWidget', {
|
// store.dispatch('selectWidget', {
|
||||||
// uuid: uuid,
|
// uuid: uuid,
|
||||||
@ -366,7 +359,7 @@ async function handleSelection(e: MouseEvent) {
|
|||||||
} else {
|
} else {
|
||||||
// 取消选中元素
|
// 取消选中元素
|
||||||
widgetStore.selectWidget({
|
widgetStore.selectWidget({
|
||||||
uuid: "-1"
|
uuid: '-1',
|
||||||
})
|
})
|
||||||
// store.dispatch('selectWidget', {
|
// store.dispatch('selectWidget', {
|
||||||
// uuid: '-1',
|
// uuid: '-1',
|
||||||
@ -381,34 +374,33 @@ function getlayers() {
|
|||||||
function getChilds(uuid: string) {
|
function getChilds(uuid: string) {
|
||||||
return dWidgets.value.filter((item) => item.parent === uuid)
|
return dWidgets.value.filter((item) => item.parent === uuid)
|
||||||
}
|
}
|
||||||
// getIsActive(uuid) {
|
// getIsActive(uuid) {
|
||||||
// if (this.dSelectWidgets.length > 0) {
|
// if (this.dSelectWidgets.length > 0) {
|
||||||
// let widget = this.dSelectWidgets.find((item) => item.uuid === uuid)
|
// let widget = this.dSelectWidgets.find((item) => item.uuid === uuid)
|
||||||
// if (widget) {
|
// if (widget) {
|
||||||
// return true
|
// return true
|
||||||
// }
|
// }
|
||||||
// return false
|
// return false
|
||||||
// } else {
|
// } else {
|
||||||
// return uuid === this.dActiveElement.uuid
|
// return uuid === this.dActiveElement.uuid
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
#main {
|
#main {
|
||||||
overflow: auto; position: relative;
|
overflow: auto;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
#page-design {
|
#page-design {
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
// display: flex;
|
|
||||||
// align-items: center;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
// width: 100%;
|
// width: 100%;
|
||||||
.out-page {
|
.out-page {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 60px;
|
// padding: 60px;
|
||||||
position: relative;
|
position: relative;
|
||||||
.design-canvas {
|
.design-canvas {
|
||||||
// transition: all 0.3s;
|
// transition: all 0.3s;
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="page-style">
|
<div id="page-style">
|
||||||
<div v-if="state.showBgLib" style="width: 256px;height: 100%;">
|
<div v-if="state.showBgLib" style="width: 256px; height: 100%">
|
||||||
<span class="header-back" @click="state.showBgLib = false">
|
<span class="header-back" @click="state.showBgLib = false"> <i class="iconfont icon-right"></i> 选择背景 </span>
|
||||||
<i class="iconfont icon-right"></i> 选择背景
|
<bg-img-list-wrap style="padding-top: 2rem" model="stylePanel" />
|
||||||
</span>
|
|
||||||
<bg-img-list-wrap style="padding-top: 2rem;" model="stylePanel" />
|
|
||||||
</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">
|
||||||
@ -13,20 +11,20 @@
|
|||||||
</sizeEditor>
|
</sizeEditor>
|
||||||
</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>
|
||||||
<Tabs :value="state.mode" @update:value="onChangeMode">
|
<Tabs :value="state.mode" @update:value="onChangeMode">
|
||||||
<TabPanel v-for="label in state.modes" :key="label" :label="label"></TabPanel>
|
<TabPanel v-for="label in state.modes" :key="label" :label="label"></TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<color-select v-show="state.mode === '颜色'" v-model="state.innerElement.backgroundColor" :modes="['纯色','渐变']" @change="colorChange" />
|
<color-select v-show="state.mode === '颜色'" v-model="state.innerElement.backgroundColor" :modes="['纯色', '渐变']" @change="colorChange" />
|
||||||
<div v-if="state.mode === '图片' && state.innerElement.backgroundImage" style="margin-top: 1.2rem">
|
<div v-if="state.mode === '图片' && state.innerElement.backgroundImage" style="margin-top: 1.2rem">
|
||||||
<div class="backgroud-wrap">
|
<div class="backgroud-wrap">
|
||||||
<el-image style="height: 100%" :src="state.innerElement.backgroundImage" fit="contain"></el-image>
|
<el-image style="height: 100%" :src="state.innerElement.backgroundImage" fit="contain"></el-image>
|
||||||
<div class="bg-control">
|
<div class="bg-control">
|
||||||
<div class="btns">
|
<div class="btns">
|
||||||
<uploader style="width: 47%;" @done="uploadImgDone">
|
<uploader style="width: 47%" @done="uploadImgDone">
|
||||||
<el-button style="width: 100%;" plain>上传图片</el-button>
|
<el-button style="width: 100%" plain>上传图片</el-button>
|
||||||
</uploader>
|
</uploader>
|
||||||
<el-button style="width: 47%;" @click="state.showBgLib = true" plain>背景库</el-button>
|
<el-button style="width: 47%" @click="state.showBgLib = true" plain>背景库</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-options">
|
<div class="bg-options">
|
||||||
@ -91,7 +89,7 @@ const state = reactive<TState>({
|
|||||||
downP: 0,
|
downP: 0,
|
||||||
mode: '颜色',
|
mode: '颜色',
|
||||||
modes: ['颜色', '图片'],
|
modes: ['颜色', '图片'],
|
||||||
showBgLib: false
|
showBgLib: false,
|
||||||
})
|
})
|
||||||
const sizeEditRef: Ref<typeof createDesign | null> = ref(null)
|
const sizeEditRef: Ref<typeof createDesign | null> = ref(null)
|
||||||
// const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
// const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
||||||
@ -103,7 +101,7 @@ watch(
|
|||||||
() => {
|
() => {
|
||||||
change()
|
change()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -111,7 +109,7 @@ watch(
|
|||||||
() => {
|
() => {
|
||||||
changeValue()
|
changeValue()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -144,12 +142,9 @@ function changeValue() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for (let key in state.innerElement) {
|
for (let key in state.innerElement) {
|
||||||
if (
|
if (state.innerElement[key] !== (dActiveElement.value as Record<string, any>)[key]) {
|
||||||
key !== 'setting' && key !== 'record' &&
|
|
||||||
state.innerElement[key] !== (dActiveElement.value as Record<string, any>)[key]
|
|
||||||
) {
|
|
||||||
if (state.ingoreKeys.indexOf(key) !== -1) {
|
if (state.ingoreKeys.indexOf(key) !== -1) {
|
||||||
(dActiveElement.value as Record<string, any>)[key] = state.innerElement[key]
|
;(dActiveElement.value as Record<string, any>)[key] = state.innerElement[key]
|
||||||
} else {
|
} else {
|
||||||
pageStore.updatePageData({
|
pageStore.updatePageData({
|
||||||
key: key as keyof TPageState,
|
key: key as keyof TPageState,
|
||||||
@ -197,7 +192,7 @@ 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
|
||||||
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,
|
||||||
@ -229,25 +224,26 @@ function openSizeEdit() {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.btn-wrap {
|
.btn-wrap {
|
||||||
width: 100%; margin-top: 1.2rem;
|
width: 100%;
|
||||||
|
margin-top: 1.2rem;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
&-back {
|
&-back {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
height: 2.9rem;
|
height: 2.9rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
width: 259px;
|
width: 259px;
|
||||||
.icon-right {
|
.icon-right {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.backgroud-wrap {
|
.backgroud-wrap {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-04-08 10:31:34
|
* @Date: 2022-04-08 10:31:34
|
||||||
* @Description: 标尺
|
* @Description: 标尺
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-11 01:42:25
|
* @LastEditTime: 2024-04-10 23:07:44
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div></div>
|
<div></div>
|
||||||
@ -13,29 +13,28 @@
|
|||||||
import { watch } from 'vue'
|
import { watch } from 'vue'
|
||||||
|
|
||||||
import Guides, { GuideOptions } from '@scena/guides'
|
import Guides, { GuideOptions } from '@scena/guides'
|
||||||
import { useCanvasStore } from '@/store';
|
import { useCanvasStore } from '@/store'
|
||||||
|
|
||||||
type TProps = {
|
type TProps = {
|
||||||
show: boolean
|
show: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type TSameParams = {
|
type TSameParams = {
|
||||||
backgroundColor: string,
|
backgroundColor: string
|
||||||
lineColor: string
|
lineColor: string
|
||||||
textColor: string
|
textColor: string
|
||||||
// direction: 'start',
|
// direction: 'start',
|
||||||
// height: 30,
|
// height: 30,
|
||||||
displayDragPos: boolean,
|
displayDragPos: boolean
|
||||||
dragPosFormat: (v: string | number) => string,
|
dragPosFormat: (v: string | number) => string
|
||||||
}
|
}
|
||||||
|
|
||||||
type TGuidesData = Guides & GuideOptions
|
type TGuidesData = Guides & GuideOptions
|
||||||
|
|
||||||
const props = withDefaults(defineProps<TProps>(), {
|
const props = withDefaults(defineProps<TProps>(), {
|
||||||
show: false
|
show: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const canvasStore = useCanvasStore()
|
const canvasStore = useCanvasStore()
|
||||||
const container = 'page-design' // page-design out-page
|
const container = 'page-design' // page-design out-page
|
||||||
let guidesTop: TGuidesData | null = null
|
let guidesTop: TGuidesData | null = null
|
||||||
@ -55,20 +54,6 @@ watch(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// onMounted(() => {
|
|
||||||
// // let scrollX = 0
|
|
||||||
// // let scrollY = 0
|
|
||||||
// // window.addEventListener('resize', () => {
|
|
||||||
// // guides.resize()
|
|
||||||
// // })
|
|
||||||
// // window.addEventListener('wheel', (e) => {
|
|
||||||
// // scrollX += e.deltaX
|
|
||||||
// // scrollY += e.deltaY
|
|
||||||
// // guides.scrollGuides(scrollY)
|
|
||||||
// // guides.scroll(scrollX)
|
|
||||||
// // })
|
|
||||||
// })
|
|
||||||
|
|
||||||
function destroy() {
|
function destroy() {
|
||||||
guidesTop?.destroy()
|
guidesTop?.destroy()
|
||||||
guidesLeft?.destroy()
|
guidesLeft?.destroy()
|
||||||
|
2
src/components/modules/layout/multipleBoards/index.ts
Normal file
2
src/components/modules/layout/multipleBoards/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import index from './multipleBoards.vue'
|
||||||
|
export default index
|
313
src/components/modules/layout/multipleBoards/multipleBoards.vue
Normal file
313
src/components/modules/layout/multipleBoards/multipleBoards.vue
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-11 17:27:58
|
||||||
|
* @Description: 多画板操作界面
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-16 22:58:33
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div :style="{ position, bottom: -1 * st + 'px', left: sl + 'px' }" :class="['artboards', isFold ? 'fold' : 'unfold']">
|
||||||
|
<div class="wrap">
|
||||||
|
<div v-if="isFold" v-show="dLayouts.length > 0" class="btn" @click="isFold = !isFold">画板 {{ index + 1 }}/{{ dLayouts.length }} <i class="icon sd-zhankai" /></div>
|
||||||
|
<div class="list" v-else>
|
||||||
|
<span @click="isFold = !isFold" class="icon-btn"><i class="icon sd-zhankai" /></span>
|
||||||
|
<div v-for="(l, li) in dLayouts" :key="'l' + li" :style="{width: getPW(l.global)+'px'}" @click="selectPoster(li)" :class="['item-box', index == li ? 'item-select' : 'item-default']">
|
||||||
|
<div
|
||||||
|
class="mini-poster"
|
||||||
|
:style="{
|
||||||
|
transform: getTransform(l.global),
|
||||||
|
width: l.global.width + 'px',
|
||||||
|
height: l.global.height + 'px',
|
||||||
|
backgroundColor: l.global.backgroundGradient ? undefined : l.global.backgroundColor,
|
||||||
|
backgroundImage: l.global.backgroundImage ? `url(${l.global?.backgroundImage})` : l.global.backgroundGradient || undefined,
|
||||||
|
backgroundSize: l.global.backgroundTransform?.x ? 'auto' : 'cover',
|
||||||
|
backgroundPositionX: (l.global.backgroundTransform?.x || 0) + 'px',
|
||||||
|
backgroundPositionY: (l.global.backgroundTransform?.y || 0) + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<component :is="layer.type + '-static'" v-for="layer in getlayers(l.layers)" :key="layer.uuid" :params="layer" :parent="l.global">
|
||||||
|
<template v-if="layer.isContainer">
|
||||||
|
<component :is="widget.type + '-static'" v-for="widget in getChilds(l.layers, layer.uuid)" :key="widget.uuid" :params="widget" :parent="layer" />
|
||||||
|
</template>
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
|
<div class="item-idx">{{ li + 1 }}</div>
|
||||||
|
<i @click.stop="removePoster(li)" class="icon sd-quxiao" />
|
||||||
|
</div>
|
||||||
|
<div v-show="dLayouts.length < 9" @click="addLayer" class="item-add"><i class="iconfont icon-add" /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, Ref, onMounted, nextTick, watch, computed } from 'vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useCanvasStore, useWidgetStore, useForceStore, useControlStore } from '@/store'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
const forceStore = useForceStore()
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
|
const controlStore = useControlStore()
|
||||||
|
const position: Ref = ref('absolute') // sticky
|
||||||
|
const isFold = ref(true)
|
||||||
|
const st = ref(0)
|
||||||
|
const sl = ref(0)
|
||||||
|
const index = computed(() => canvasStore.dCurrentPage)
|
||||||
|
const { dZoom, dPage } = storeToRefs(canvasStore)
|
||||||
|
const { dWidgets, dLayouts } = storeToRefs(widgetStore)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => dZoom.value,
|
||||||
|
(val) => {
|
||||||
|
// 在画布缩放时bottom复位
|
||||||
|
mainEl.scrollTop = 0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => isFold.value,
|
||||||
|
(isFold) => {
|
||||||
|
canvasStore.setBottomHeight(isFold ? 0 : 90)
|
||||||
|
setTimeout(() => {
|
||||||
|
forceStore.setZoomScreenChange()
|
||||||
|
}, 300)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
let mainEl: any = null
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick()
|
||||||
|
mainEl = document.getElementById('main')
|
||||||
|
|
||||||
|
mainEl.addEventListener('scroll', function (e) {
|
||||||
|
st.value = mainEl.scrollTop
|
||||||
|
sl.value = mainEl.scrollLeft
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 计算变换量 */
|
||||||
|
function getTransform(global: any) {
|
||||||
|
const { width, height } = global
|
||||||
|
const isVertical = height > width
|
||||||
|
const edge = isVertical ? Math.max(width, height) : Math.min(width, height)
|
||||||
|
const s = 72 / edge
|
||||||
|
const left = isVertical ? ((72 - width * s) / 2 - 1) / s : 0
|
||||||
|
return `scale(${s}) translateX(${left}px)`
|
||||||
|
}
|
||||||
|
/** 计算实际宽度 */
|
||||||
|
function getPW(global: any) {
|
||||||
|
const { width, height } = global
|
||||||
|
const isVertical = height > width
|
||||||
|
const s = 72 / Math.min(width, height)
|
||||||
|
return isVertical ? 72 : width * s
|
||||||
|
}
|
||||||
|
|
||||||
|
function getlayers(widgets: any) {
|
||||||
|
return widgets.filter((item: any) => item.parent === dPage.value.uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChilds(widgets: any, uuid: string) {
|
||||||
|
return widgets.filter((item: any) => item.parent === uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitPage() {
|
||||||
|
const clonePage = JSON.parse(JSON.stringify(dPage.value))
|
||||||
|
clonePage.backgroundColor = '#ffffffff'
|
||||||
|
clonePage.backgroundGradient = ''
|
||||||
|
clonePage.backgroundImage = ''
|
||||||
|
return clonePage
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLayer() {
|
||||||
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
widgetStore.dLayouts.push({ global: getInitPage(), layers: [] })
|
||||||
|
canvasStore.dCurrentPage = dLayouts.value.length - 1
|
||||||
|
widgetStore.setDWidgets(widgetStore.getWidgets)
|
||||||
|
canvasStore.setDPage(getInitPage())
|
||||||
|
canvasStore.updateDPage()
|
||||||
|
widgetStore.selectWidget({ uuid: '-1' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectPoster(i: number) {
|
||||||
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
canvasStore.dCurrentPage = i
|
||||||
|
widgetStore.setDWidgets(widgetStore.getWidgets)
|
||||||
|
canvasStore.setDPage(dLayouts.value[i].global)
|
||||||
|
widgetStore.selectWidget({ uuid: '-1' })
|
||||||
|
}
|
||||||
|
function removePoster(removeIndex: number) {
|
||||||
|
if (index.value === removeIndex) {
|
||||||
|
// 当前画布下,清空画布内容而非删除
|
||||||
|
widgetStore.dLayouts[removeIndex].layers.length = 0
|
||||||
|
ElMessage('画布已清空')
|
||||||
|
widgetStore.setDWidgets([]) // 清除画布图层
|
||||||
|
// widgetStore.updateDWidgets()
|
||||||
|
// widgetStore.dLayouts[removeIndex].global = getInitPage()
|
||||||
|
canvasStore.setDPage(getInitPage()) // 初始化背景
|
||||||
|
// canvasStore.updateDPage()
|
||||||
|
// widgetStore.setDWidgets([])
|
||||||
|
} else widgetStore.dLayouts.splice(removeIndex, 1)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.artboards {
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
padding: 0 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666666;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.5s;
|
||||||
|
.icon {
|
||||||
|
transition: all 0.3s;
|
||||||
|
color: #babec2;
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.item-box,
|
||||||
|
.item-add {
|
||||||
|
position: relative;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 5px 0 0 14px;
|
||||||
|
background: #f1f2f4;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.07);
|
||||||
|
}
|
||||||
|
.item-box:hover {
|
||||||
|
.sd-quxiao {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sd-quxiao,
|
||||||
|
.item-idx {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.item-idx {
|
||||||
|
font-size: 12px;
|
||||||
|
bottom: 2px;
|
||||||
|
left: 2px;
|
||||||
|
width: 17px;
|
||||||
|
height: 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
.sd-quxiao {
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 1px 2px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #666666;
|
||||||
|
right: 1px;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
.sd-quxiao:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
.item-add {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.icon-add {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-add:hover {
|
||||||
|
filter: brightness(95%);
|
||||||
|
}
|
||||||
|
.item-default:hover {
|
||||||
|
box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.4), 0px 4px 12px 0px rgba(0, 0, 0, 0.07);
|
||||||
|
}
|
||||||
|
.item-select {
|
||||||
|
box-shadow: 0px 0px 2px 3px @main-color;
|
||||||
|
}
|
||||||
|
.item-box:first-of-type {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.item-box:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.unfold {
|
||||||
|
width: calc(100% - 155px);
|
||||||
|
height: 90px;
|
||||||
|
.wrap {
|
||||||
|
padding: 10px 10px 10px 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.08), 0px 4px 12px 0px rgba(0, 0, 0, 0.04);
|
||||||
|
.icon-btn {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 47px;
|
||||||
|
height: 70px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.sd-zhankai {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.sd-zhankai:hover {
|
||||||
|
transform: scale(1.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fold {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 150px;
|
||||||
|
text-align: center;
|
||||||
|
height: 38px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
.wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.08), 0px 4px 12px 0px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.btn:hover > .sd-zhankai {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mini-poster {
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
</style>
|
@ -51,7 +51,7 @@ const canvasStore = useCanvasStore()
|
|||||||
const { dPage } = storeToRefs(useCanvasStore())
|
const { dPage } = storeToRefs(useCanvasStore())
|
||||||
const { zoomScreenChange } = storeToRefs(useForceStore())
|
const { zoomScreenChange } = storeToRefs(useForceStore())
|
||||||
const { dZoom, dScreen } = storeToRefs(canvasStore)
|
const { dZoom, dScreen } = storeToRefs(canvasStore)
|
||||||
|
const presetPadding = canvasStore.dPresetPadding
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
activezoomIndex,
|
activezoomIndex,
|
||||||
@ -142,10 +142,6 @@ function changeScreen() {
|
|||||||
width: screen.offsetWidth,
|
width: screen.offsetWidth,
|
||||||
height: screen.offsetHeight,
|
height: screen.offsetHeight,
|
||||||
})
|
})
|
||||||
// store.dispatch('updateScreen', {
|
|
||||||
// width: screen.offsetWidth,
|
|
||||||
// height: screen.offsetHeight,
|
|
||||||
// })
|
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,27 +235,29 @@ function nearZoom(add?: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calcZoom() {
|
function calcZoom() {
|
||||||
let widthZoom = ((dScreen.value.width - 142) * 100) / dPage.value.width
|
// let widthZoom = ((dScreen.value.width - 142) * 100) / dPage.value.width
|
||||||
let heightZoom = ((dScreen.value.height - 122) * 100) / dPage.value.height
|
// let heightZoom = ((dScreen.value.height - 122) * 100) / dPage.value.height
|
||||||
|
const diffHeight = presetPadding * 2 + 2 + canvasStore.dBottomHeight
|
||||||
|
const diffWidth = presetPadding * 2 + 22
|
||||||
|
let widthZoom = ((dScreen.value.width - diffWidth) * 100) / dPage.value.width
|
||||||
|
let heightZoom = ((dScreen.value.height - diffHeight) * 100) / dPage.value.height
|
||||||
bestZoom.value = Math.min(widthZoom, heightZoom)
|
bestZoom.value = Math.min(widthZoom, heightZoom)
|
||||||
return bestZoom.value
|
return bestZoom.value
|
||||||
}
|
}
|
||||||
|
|
||||||
async function autoFixTop() {
|
async function autoFixTop() {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
const presetPadding = 60
|
|
||||||
const el = document.getElementById('out-page')
|
const el = document.getElementById('out-page')
|
||||||
if (!el) return
|
if (!el) return
|
||||||
const clientHeight = window.innerHeight - 54
|
const headerBarHeight = 54
|
||||||
|
const clientHeight = window.innerHeight - headerBarHeight - canvasStore.dBottomHeight
|
||||||
// const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54
|
// const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54
|
||||||
let padding = (clientHeight - el.offsetHeight) / 2
|
let padding = (clientHeight - el.offsetHeight) / 2
|
||||||
if (typeof curAction.value === 'undefined') {
|
if (typeof curAction.value === 'undefined') {
|
||||||
padding += presetPadding / 2
|
padding += presetPadding / 2
|
||||||
}
|
}
|
||||||
curAction.value === 'add' && (padding -= presetPadding)
|
curAction.value === 'add' && (padding -= presetPadding)
|
||||||
|
|
||||||
canvasStore.updatePaddingTop(padding > 0 ? padding : 0)
|
canvasStore.updatePaddingTop(padding > 0 ? padding : 0)
|
||||||
// store.commit('updatePaddingTop', padding > 0 ? padding : 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@ -280,26 +278,28 @@ defineExpose({
|
|||||||
@z-border-color: #e6e6e6;
|
@z-border-color: #e6e6e6;
|
||||||
|
|
||||||
#zoom-control {
|
#zoom-control {
|
||||||
bottom: 20px;
|
bottom: 10px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 302px;
|
right: 292px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
.zoom-control-wrap {
|
.zoom-control-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 40px;
|
height: 38px;
|
||||||
.radius-left {
|
.radius-left {
|
||||||
border-bottom-left-radius: 50%;
|
border-bottom-left-radius: 6px;
|
||||||
border-top-left-radius: 50%;
|
border-top-left-radius: 6px;
|
||||||
border-block-end: 1px solid @z-border-color;
|
border-block-end: 1px solid @z-border-color;
|
||||||
border-block-start: 1px solid @z-border-color;
|
border-block-start: 1px solid @z-border-color;
|
||||||
|
border-left: 1px solid @z-border-color;
|
||||||
}
|
}
|
||||||
.radius-right {
|
.radius-right {
|
||||||
border-bottom-right-radius: 50%;
|
border-bottom-right-radius: 6px;
|
||||||
border-top-right-radius: 50%;
|
border-top-right-radius: 6px;
|
||||||
border-block-end: 1px solid @z-border-color;
|
border-block-end: 1px solid @z-border-color;
|
||||||
border-block-start: 1px solid @z-border-color;
|
border-block-start: 1px solid @z-border-color;
|
||||||
|
border-right: 1px solid @z-border-color;
|
||||||
}
|
}
|
||||||
.zoom-icon {
|
.zoom-icon {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -378,10 +378,4 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #zoom-control-active {
|
|
||||||
// background-color: @color1;
|
|
||||||
// background-color: @color5;
|
|
||||||
// color: @color-select;
|
|
||||||
// color: @color-select;
|
|
||||||
// }
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -150,7 +150,7 @@ defineExpose({
|
|||||||
left: 394px;
|
left: 394px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
width: 20px;
|
width: 15px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-02 09:41:41
|
* @Date: 2021-08-02 09:41:41
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-10-16 00:30:03
|
* @LastEditTime: 2024-04-16 17:19:15
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
@ -59,26 +59,6 @@ const widget = ref<HTMLElement | null>(null)
|
|||||||
const ratio = ref(0)
|
const ratio = ref(0)
|
||||||
const temp = ref<Record<string, any>>({})
|
const temp = ref<Record<string, any>>({})
|
||||||
const compWidgetsRecord = ref<Record<string, any>>({})
|
const compWidgetsRecord = ref<Record<string, any>>({})
|
||||||
// const setting = {
|
|
||||||
// name: '组合',
|
|
||||||
// type: NAME,
|
|
||||||
// uuid: -1,
|
|
||||||
// width: 0,
|
|
||||||
// height: 0,
|
|
||||||
// left: 0,
|
|
||||||
// top: 0,
|
|
||||||
// transform: '',
|
|
||||||
// opacity: 1,
|
|
||||||
// parent: '-1',
|
|
||||||
// isContainer: true,
|
|
||||||
// record: {
|
|
||||||
// width: 0,
|
|
||||||
// height: 0,
|
|
||||||
// minWidth: 0,
|
|
||||||
// minHeight: 0,
|
|
||||||
// dir: 'none',
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
|
|
||||||
const timer = ref<number | null>(null)
|
const timer = ref<number | null>(null)
|
||||||
// const { dActiveElement, dWidgets } = useSetupMapGetters(['dActiveElement', 'dWidgets'])
|
// const { dActiveElement, dWidgets } = useSetupMapGetters(['dActiveElement', 'dWidgets'])
|
||||||
@ -196,12 +176,12 @@ function touchend() {
|
|||||||
keyChange(key, 'width', temp.value[key].width)
|
keyChange(key, 'width', temp.value[key].width)
|
||||||
keyChange(key, 'height', temp.value[key].height)
|
keyChange(key, 'height', temp.value[key].height)
|
||||||
// 重新拿前面设定好的,实时DOM修改过了
|
// 重新拿前面设定好的,实时DOM修改过了
|
||||||
keySetValue(key, 'left', compWidgetsRecord.value[key].left * ratio.value)
|
keySetValue(key, 'left', compWidgetsRecord.value[key]?.left * ratio.value)
|
||||||
keySetValue(key, 'top', compWidgetsRecord.value[key].top * ratio.value)
|
keySetValue(key, 'top', compWidgetsRecord.value[key]?.top * ratio.value)
|
||||||
// this.keySetValue(key, 'left', Number(document.getElementById(key).style.left.replace('px', '')) * this.ratio)
|
// this.keySetValue(key, 'left', Number(document.getElementById(key).style.left.replace('px', '')) * this.ratio)
|
||||||
// this.keySetValue(key, 'top', Number(document.getElementById(key).style.top.replace('px', '')) * this.ratio)
|
// this.keySetValue(key, 'top', Number(document.getElementById(key).style.top.replace('px', '')) * this.ratio)
|
||||||
if (temp.value[key].raw.type === 'w-text') {
|
if (temp.value[key].raw.type === 'w-text') {
|
||||||
keyChange(key, 'fontSize', compWidgetsRecord.value[key].fontSize * ratio.value)
|
keyChange(key, 'fontSize', compWidgetsRecord.value[key]?.fontSize * ratio.value)
|
||||||
// this.keyChange(key, 'fontSize', this.temp[key].raw.fontSize * this.ratio)
|
// this.keyChange(key, 'fontSize', this.temp[key].raw.fontSize * this.ratio)
|
||||||
// this.keyChange(key, 'letterSpacing', this.temp[key].raw.letterSpacing * this.ratio)
|
// this.keyChange(key, 'letterSpacing', this.temp[key].raw.letterSpacing * this.ratio)
|
||||||
}
|
}
|
||||||
|
48
src/components/modules/widgets/wGroup/wGroupStatic.vue
Normal file
48
src/components/modules/widgets/wGroup/wGroupStatic.vue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2021-08-02 09:41:41
|
||||||
|
* @Description: 静态组件
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-16 16:13:56
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: (props.params.left || 0) - (props.parent?.left || 0) + 'px',
|
||||||
|
top: (props.params.top || 0) - (props.parent.top || 0) + 'px',
|
||||||
|
width: params.width + 'px',
|
||||||
|
height: params.height + 'px',
|
||||||
|
opacity: params.opacity,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// 组合组件
|
||||||
|
|
||||||
|
export type TParamsData = {
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
opacity: number
|
||||||
|
rotate: number
|
||||||
|
uuid: string
|
||||||
|
lock: boolean
|
||||||
|
fontSize: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
params?: Partial<TParamsData>
|
||||||
|
parent?: Partial<Pick<TParamsData, "top" | "left">>
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<TProps>(), {
|
||||||
|
params: () => ({}),
|
||||||
|
parent: () => ({})
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
92
src/components/modules/widgets/wImage/wImageStatic.vue
Normal file
92
src/components/modules/widgets/wImage/wImageStatic.vue
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-12 17:47:19
|
||||||
|
* @Description: 静态组件
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-16 16:25:35
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="widgetRef"
|
||||||
|
:style="{
|
||||||
|
position: state.position,
|
||||||
|
left: params.left - parent.left + 'px',
|
||||||
|
top: params.top - parent.top + 'px',
|
||||||
|
width: params.width + 'px',
|
||||||
|
height: params.height + 'px',
|
||||||
|
opacity: params.opacity,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div :style="{ transform: params.flip ? `rotate${params.flip}(180deg)` : undefined, borderRadius: params.radius + 'px', '-webkit-mask-image': `${params.mask ? `url('${params.mask}')` : 'initial'}` }" :class="['img__box', { mask: params.mask }]">
|
||||||
|
<div v-if="params.isNinePatch" ref="targetRef" class="target" :style="{ border: `${(params.height * params.sliceData.ratio) / 2}px solid transparent`, borderImage: `url('${params.imgUrl}') ${params.sliceData.left} round` }"></div>
|
||||||
|
<img v-else ref="targetRef" class="target" style="transform-origin: center" :src="params.imgUrl" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { CSSProperties, reactive, ref } from 'vue'
|
||||||
|
import setting from "./wImageSetting"
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
params: typeof setting
|
||||||
|
parent: {
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TState = {
|
||||||
|
position: 'absolute' | 'relative', // 'absolute'relative
|
||||||
|
editBoxStyle: CSSProperties,
|
||||||
|
cropWidgetXY: {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
holdPosition: {
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TProps>()
|
||||||
|
const state = reactive<TState>({
|
||||||
|
position: 'absolute', // 'absolute'relative
|
||||||
|
editBoxStyle: {
|
||||||
|
transformOrigin: 'center',
|
||||||
|
transform: '',
|
||||||
|
},
|
||||||
|
cropWidgetXY: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
holdPosition: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const widgetRef = ref<HTMLElement | null>(null)
|
||||||
|
const targetRef = ref<HTMLImageElement | null>(null)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.mask {
|
||||||
|
-webkit-mask-size: 100% 100%;
|
||||||
|
-webkit-mask-position: center;
|
||||||
|
}
|
||||||
|
.img__box {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.target {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
135
src/components/modules/widgets/wSvg/wSvgStatic.vue
Normal file
135
src/components/modules/widgets/wSvg/wSvgStatic.vue
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<!--
|
||||||
|
TODO: 重构
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="widgetRef"
|
||||||
|
:style="{
|
||||||
|
position: state.position,
|
||||||
|
left: params.left - parent.left + 'px',
|
||||||
|
top: params.top - parent.top + 'px',
|
||||||
|
width: params.width + 'px',
|
||||||
|
height: params.height + 'px',
|
||||||
|
opacity: params.opacity,
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { TWSvgSetting } from './wSvgSetting'
|
||||||
|
import { CSSProperties, computed, nextTick, onBeforeMount, onMounted, onUpdated, reactive, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
params: TWSvgSetting
|
||||||
|
parent: {
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TState = {
|
||||||
|
position: CSSProperties['position'], // 'absolute'relative
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TProps>()
|
||||||
|
const state = reactive<TState>({
|
||||||
|
position: 'absolute', // 'absolute'relative
|
||||||
|
})
|
||||||
|
|
||||||
|
const widgetRef = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
let svgElements: Record<string, any>[] | null = null
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick()
|
||||||
|
await loadSvg()
|
||||||
|
})
|
||||||
|
|
||||||
|
function loadSvg() {
|
||||||
|
// console.log(this.params)
|
||||||
|
const Snap = (window as any).Snap
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
Snap.load(
|
||||||
|
props.params.svgUrl,
|
||||||
|
function (svg: Record<string, any>) {
|
||||||
|
let svg2 = Snap(svg.node)
|
||||||
|
// let item = svg2.select('circle')
|
||||||
|
// item.attr({
|
||||||
|
// fill: 'rgb(255, 0, 0)',
|
||||||
|
// })
|
||||||
|
// console.log(item.attr('fill'))
|
||||||
|
|
||||||
|
let items = svg2.node.childNodes
|
||||||
|
svg2.node.removeAttribute('width')
|
||||||
|
svg2.node.removeAttribute('height')
|
||||||
|
svg2.node.setAttribute('style', 'height: inherit;width: inherit;')
|
||||||
|
// svg2.node.setAttribute('height', 'inherit')
|
||||||
|
svgElements = []
|
||||||
|
const colorsObj = color2obj()
|
||||||
|
|
||||||
|
deepElement(items)
|
||||||
|
|
||||||
|
function deepElement(els: Record<string, any>) {
|
||||||
|
// 判断是NodeList对象则继续递归,否则进入元素处理工厂
|
||||||
|
if (els.item) {
|
||||||
|
els.forEach((element: Record<string, any>) => {
|
||||||
|
elementFactory(element)
|
||||||
|
if (element.childNodes.length > 0) {
|
||||||
|
element.childNodes.forEach((element: Record<string, any>) => {
|
||||||
|
deepElement(element)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
elementFactory(els)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 元素工厂: 遍历元素中是否存在可自定义的颜色属性
|
||||||
|
function elementFactory(element: Record<string, any>) {
|
||||||
|
const attrsColor: Record<string, any> = {}
|
||||||
|
try {
|
||||||
|
element.attributes.forEach((attr: Record<string, any>) => {
|
||||||
|
if (colorsObj[attr.value]) {
|
||||||
|
// console.log(attr.name, colorsObj[attr.value])
|
||||||
|
attr.value = colorsObj[attr.value]
|
||||||
|
attrsColor[attr.name] = props.params.colors.findIndex((x) => x == attr.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {}
|
||||||
|
if (JSON.stringify(attrsColor) !== '{}' && svgElements) {
|
||||||
|
svgElements.push({
|
||||||
|
item: element,
|
||||||
|
attrsColor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// console.log(element.attributes, element.getAttribute('fill'), _this.params.colors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// _this.viewBox = svg2.node.viewBox.baseVal
|
||||||
|
// _this.svgImg = img
|
||||||
|
|
||||||
|
// img.attr({
|
||||||
|
// width: '100%',
|
||||||
|
// height: '100%',
|
||||||
|
// transform: '',
|
||||||
|
// 'xlink:href': _this.params.imgUrl || '',
|
||||||
|
// })
|
||||||
|
if (widgetRef.value) {
|
||||||
|
// svg.node.classList.add('svg__box')
|
||||||
|
widgetRef.value.appendChild(svg.node)
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
document.getElementById(props.params.uuid),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function color2obj() {
|
||||||
|
const obj: Record<string, any> = {}
|
||||||
|
for (let i = 0; i < props.params.colors.length; i++) {
|
||||||
|
obj[`{{colors[${i}]}}`] = props.params.colors[i]
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
100
src/components/modules/widgets/wText/wTextStatic.vue
Normal file
100
src/components/modules/widgets/wText/wTextStatic.vue
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="widget"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: params.left - parent.left + 'px',
|
||||||
|
top: params.top - parent.top + 'px',
|
||||||
|
width: params.width + 'px',
|
||||||
|
minWidth: params.fontSize + 'px',
|
||||||
|
minHeight: params.fontSize * params.lineHeight + 'px',
|
||||||
|
height: params.height + 'px',
|
||||||
|
lineHeight: params.fontSize * params.lineHeight + 'px',
|
||||||
|
letterSpacing: (params.fontSize * params.letterSpacing) / 100 + 'px',
|
||||||
|
fontSize: params.fontSize + 'px',
|
||||||
|
color: params.color,
|
||||||
|
textAlign: params.textAlign,
|
||||||
|
fontWeight: params.fontWeight,
|
||||||
|
fontStyle: params.fontStyle,
|
||||||
|
textDecoration: params.textDecoration,
|
||||||
|
opacity: params.opacity,
|
||||||
|
backgroundColor: params.backgroundColor,
|
||||||
|
writingMode: params.writingMode,
|
||||||
|
fontFamily: `'${params.fontClass.value}'`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="params.textEffects">
|
||||||
|
<div
|
||||||
|
v-for="(ef, efi) in params.textEffects"
|
||||||
|
:key="efi + 'effect'"
|
||||||
|
:style="{
|
||||||
|
fontFamily: `'${params.fontClass.value}'`,
|
||||||
|
color: ef.filling && ef.filling.enable && ef.filling.type === 0 ? ef.filling.color : 'transparent',
|
||||||
|
WebkitTextStroke: ef.stroke && ef.stroke.enable ? `${ef.stroke.width}px ${ef.stroke.color}` : undefined,
|
||||||
|
textShadow: ef.shadow && ef.shadow.enable ? `${ef.shadow.offsetX}px ${ef.shadow.offsetY}px ${ef.shadow.blur}px ${ef.shadow.color}` : undefined,
|
||||||
|
backgroundImage: ef.filling && ef.filling.enable ? (ef.filling.type === 0 ? undefined : getGradientOrImg(ef)) : undefined,
|
||||||
|
WebkitBackgroundClip: ef.filling && ef.filling.enable ? (ef.filling.type === 0 ? undefined : 'text') : undefined,
|
||||||
|
transform: ef.offset && ef.offset.enable ? `translate(${ef.offset.x}px, ${ef.offset.y}px)` : undefined,
|
||||||
|
}"
|
||||||
|
class="edit-text effect-text"
|
||||||
|
spellcheck="false"
|
||||||
|
v-html="params.text"
|
||||||
|
></div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
:style="{ fontFamily: `'${params.fontClass.value}'` }"
|
||||||
|
class="edit-text" spellcheck="false"
|
||||||
|
v-html="params.text"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, onMounted, ref } from 'vue'
|
||||||
|
import getGradientOrImg from './getGradientOrImg'
|
||||||
|
import { wTextSetting } from './wTextSetting'
|
||||||
|
|
||||||
|
export type TwTextParams = {
|
||||||
|
rotate?: number
|
||||||
|
lock?: boolean
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
} & typeof wTextSetting
|
||||||
|
|
||||||
|
type TProps = {
|
||||||
|
params: TwTextParams
|
||||||
|
parent: {
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TProps>()
|
||||||
|
const widget = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!widget.value) return
|
||||||
|
props.params.transform && (widget.value.style.transform = props.params.transform)
|
||||||
|
props.params.rotate && (widget.value.style.transform += `translate(0px, 0px) rotate(${props.params.rotate}) scale(1, 1)`)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getGradientOrImg,
|
||||||
|
widget,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.edit-text {
|
||||||
|
outline: none;
|
||||||
|
word-break: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.effect-text {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-04-05 07:31:45
|
* @Date: 2024-04-05 07:31:45
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-10 00:34:21
|
* @LastEditTime: 2024-04-12 01:00:40
|
||||||
*/
|
*/
|
||||||
// const prefix = import.meta.env
|
// const prefix = import.meta.env
|
||||||
const prefix = process.env
|
const prefix = process.env
|
||||||
@ -23,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_ljv2tbkwgqp.css',
|
ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_xojoer6zhp.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, // 是否开启服务端字体压缩
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-03-09 14:20:09
|
* @Date: 2022-03-09 14:20:09
|
||||||
* @Description: 处理常用操作
|
* @Description: 处理常用操作
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-04 00:33:01
|
* @LastEditTime: 2024-04-16 19:19:36
|
||||||
*/
|
*/
|
||||||
import { useControlStore, useWidgetStore } from '@/store'
|
import { useControlStore, useWidgetStore } from '@/store'
|
||||||
import { TdWidgetData } from '@/store/design/widget'
|
import { TdWidgetData } from '@/store/design/widget'
|
||||||
@ -50,7 +50,7 @@ export default function keyCodeOptions(e: any, params: any) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.key === ' ') {
|
if (e.key === ' ' && widgetStore.dActiveElement?.uuid == '-1') {
|
||||||
dealWithSpace(e)
|
dealWithSpace(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-08-19 18:43:22
|
* @Date: 2021-08-19 18:43:22
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-07-31 09:31:52
|
* @LastEditTime: 2024-04-16 19:10:18
|
||||||
*/
|
*/
|
||||||
import { useControlStore, useWidgetStore } from '@/store'
|
import { useControlStore, useWidgetStore } from '@/store'
|
||||||
// import store from '@/store'
|
// import store from '@/store'
|
||||||
@ -22,12 +22,6 @@ const move = {
|
|||||||
originX: target.left,
|
originX: target.left,
|
||||||
originY: target.top,
|
originY: target.top,
|
||||||
})
|
})
|
||||||
// store.dispatch('initDMove', {
|
|
||||||
// startX: e.pageX,
|
|
||||||
// startY: e.pageY,
|
|
||||||
// originX: target.left,
|
|
||||||
// originY: target.top,
|
|
||||||
// })
|
|
||||||
|
|
||||||
// 绑定鼠标移动事件
|
// 绑定鼠标移动事件
|
||||||
document.addEventListener('mousemove', this.handlemousemove, true)
|
document.addEventListener('mousemove', this.handlemousemove, true)
|
||||||
@ -45,10 +39,6 @@ const move = {
|
|||||||
x: e.pageX,
|
x: e.pageX,
|
||||||
y: e.pageY,
|
y: e.pageY,
|
||||||
})
|
})
|
||||||
// store.dispatch('dMove', {
|
|
||||||
// x: e.pageX,
|
|
||||||
// y: e.pageY,
|
|
||||||
// })
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handlemouseup() {
|
handlemouseup() {
|
||||||
@ -56,7 +46,6 @@ const move = {
|
|||||||
document.removeEventListener('mousemove', this.handlemousemove, true)
|
document.removeEventListener('mousemove', this.handlemousemove, true)
|
||||||
document.removeEventListener('mouseup', this.handlemouseup, true)
|
document.removeEventListener('mouseup', this.handlemouseup, true)
|
||||||
controlStore.stopDMove()
|
controlStore.stopDMove()
|
||||||
// store.dispatch('stopDMove')
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -70,7 +59,6 @@ const moveInit = {
|
|||||||
// 设置mouseevent给moveable初始
|
// 设置mouseevent给moveable初始
|
||||||
// 在组合操作时排除
|
// 在组合操作时排除
|
||||||
widgetStore.setMouseEvent(e)
|
widgetStore.setMouseEvent(e)
|
||||||
// store.commit('setMouseEvent', e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = widgetStore.dActiveElement
|
const target = widgetStore.dActiveElement
|
||||||
@ -81,18 +69,11 @@ const moveInit = {
|
|||||||
originX: target.left,
|
originX: target.left,
|
||||||
originY: target.top,
|
originY: target.top,
|
||||||
})
|
})
|
||||||
// store.dispatch('initDMove', {
|
|
||||||
// startX: e.pageX,
|
|
||||||
// startY: e.pageY,
|
|
||||||
// originX: target.left,
|
|
||||||
// originY: target.top,
|
|
||||||
// })
|
|
||||||
|
|
||||||
const handlemouseup = () => {
|
const handlemouseup = () => {
|
||||||
const widgetStore = useWidgetStore()
|
const widgetStore = useWidgetStore()
|
||||||
// 销毁选中即刻移
|
// 销毁选中即刻移
|
||||||
widgetStore.setMouseEvent(null)
|
widgetStore.setMouseEvent(null)
|
||||||
// store.commit('setMouseEvent', null)
|
|
||||||
|
|
||||||
document.removeEventListener('mouseup', handlemouseup, true)
|
document.removeEventListener('mouseup', handlemouseup, true)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-04-04 00:36:13
|
* @Date: 2024-04-04 00:36:13
|
||||||
* @Description: 快捷键支持列表
|
* @Description: 快捷键支持列表
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-05 05:56:27
|
* @LastEditTime: 2024-04-11 15:05:41
|
||||||
*/
|
*/
|
||||||
const ctrlKey = isMacOS() ? `⌘` : `Ctrl`
|
const ctrlKey = isMacOS() ? `⌘` : `Ctrl`
|
||||||
function isMacOS() {
|
function isMacOS() {
|
||||||
@ -35,14 +35,6 @@ export default [
|
|||||||
feat: `重做`,
|
feat: `重做`,
|
||||||
info: `${ctrlKey} + Shift + Z`,
|
info: `${ctrlKey} + Shift + Z`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
feat: `元素移动`,
|
|
||||||
info: `← ↑ → ↓`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
feat: `快速移动`,
|
|
||||||
info: `Shift + ← ↑ → ↓`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
feat: `复制`,
|
feat: `复制`,
|
||||||
info: `${ctrlKey} + C`,
|
info: `${ctrlKey} + C`,
|
||||||
@ -55,6 +47,14 @@ export default [
|
|||||||
feat: `删除`,
|
feat: `删除`,
|
||||||
info: `Delete / Backspace`,
|
info: `Delete / Backspace`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
feat: `元素移动`,
|
||||||
|
info: `← ↑ → ↓`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
feat: `快速移动`,
|
||||||
|
info: `Shift + ← ↑ → ↓`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
feat: `多选`,
|
feat: `多选`,
|
||||||
info: `${ctrlKey} / Shift + 点选`,
|
info: `${ctrlKey} / Shift + 点选`,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-01 14:12:08
|
* @Date: 2021-08-01 14:12:08
|
||||||
* @Description: 快捷键,目前是mixin形式放入views/index.vue中
|
* @Description: 快捷键,目前是mixin形式放入views/index.vue中
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-04 00:36:19
|
* @LastEditTime: 2024-04-16 19:17:51
|
||||||
*/
|
*/
|
||||||
import keyCodeOptions from './methods/keyCodeOptions'
|
import keyCodeOptions from './methods/keyCodeOptions'
|
||||||
import dealWithCtrl from './methods/dealWithCtrl'
|
import dealWithCtrl from './methods/dealWithCtrl'
|
||||||
@ -71,7 +71,7 @@ const shortcuts = {
|
|||||||
if (e.key === 'Alt' || e.key === 'Shift' || e.key === 'Control' || e.key === 'Meta') {
|
if (e.key === 'Alt' || e.key === 'Shift' || e.key === 'Control' || e.key === 'Meta') {
|
||||||
store.updateAltDown(false)
|
store.updateAltDown(false)
|
||||||
}
|
}
|
||||||
if (e.key === ' ') {
|
if (e.key === ' ' && controlStore.dSpaceDown) {
|
||||||
appContainer.classList.remove('move-case');
|
appContainer.classList.remove('move-case');
|
||||||
controlStore.setSpaceDown(false)
|
controlStore.setSpaceDown(false)
|
||||||
widgetStore.lockWidgets()
|
widgetStore.lockWidgets()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-04-05 06:23:23
|
* @Date: 2024-04-05 06:23:23
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-05 14:53:01
|
* @LastEditTime: 2024-04-16 12:13:54
|
||||||
*/
|
*/
|
||||||
export type TScreeData = {
|
export type TScreeData = {
|
||||||
/** 记录编辑界面的宽度 */
|
/** 记录编辑界面的宽度 */
|
||||||
@ -20,6 +20,10 @@ export type TGuidelinesData = {
|
|||||||
export type TCanvasState = {
|
export type TCanvasState = {
|
||||||
/** 画布缩放百分比 */
|
/** 画布缩放百分比 */
|
||||||
dZoom: number
|
dZoom: number
|
||||||
|
/** 画布默认预留边距 */
|
||||||
|
dPresetPadding: number,
|
||||||
|
/** 画布底部工具栏高度 */
|
||||||
|
dBottomHeight: number,
|
||||||
/** 画布垂直居中修正值 */
|
/** 画布垂直居中修正值 */
|
||||||
dPaddingTop: number
|
dPaddingTop: number
|
||||||
/** 编辑界面 */
|
/** 编辑界面 */
|
||||||
@ -28,6 +32,8 @@ export type TCanvasState = {
|
|||||||
guidelines: TGuidelinesData
|
guidelines: TGuidelinesData
|
||||||
/** 页面数据 */
|
/** 页面数据 */
|
||||||
dPage: TPageState
|
dPage: TPageState
|
||||||
|
/** 当前页面下标 */
|
||||||
|
dCurrentPage: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TStoreAction = {
|
export type TStoreAction = {
|
||||||
@ -47,8 +53,13 @@ export type TStoreAction = {
|
|||||||
value: TPageState[T]
|
value: TPageState[T]
|
||||||
pushHistory?: boolean
|
pushHistory?: boolean
|
||||||
}): void
|
}): void
|
||||||
|
getDPage(data: TPageState): void
|
||||||
/** 设置dPage */
|
/** 设置dPage */
|
||||||
setDPage(data: TPageState): void
|
setDPage(data: TPageState): void
|
||||||
|
/** 更新 Page(从layouts获取)*/
|
||||||
|
updateDPage(): void
|
||||||
|
/** 设置底部工具栏高度 */
|
||||||
|
setBottomHeight(h: number): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TPageState = {
|
export type TPageState = {
|
||||||
@ -75,11 +86,5 @@ export type TPageState = {
|
|||||||
opacity: number
|
opacity: number
|
||||||
/** 强制刷新用 */
|
/** 强制刷新用 */
|
||||||
tag: number
|
tag: number
|
||||||
setting:{
|
|
||||||
label: string
|
|
||||||
parentKey: string
|
|
||||||
value: boolean
|
|
||||||
}[]
|
|
||||||
record: Record<string, any>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,17 +4,21 @@
|
|||||||
* @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-08 21:23:38
|
* @LastEditTime: 2024-04-16 12:16:25
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Store, defineStore } from 'pinia'
|
import { Store, defineStore } from 'pinia'
|
||||||
import { TCanvasState, TScreeData, TGuidelinesData, TStoreAction, TPageState } from './d'
|
import { TCanvasState, TScreeData, TGuidelinesData, TStoreAction, TPageState } from './d'
|
||||||
|
import { useWidgetStore } from "@/store";
|
||||||
|
import pageDefault from './page-default';
|
||||||
|
|
||||||
/** 画布全局设置 */
|
/** 画布全局设置 */
|
||||||
const CanvasStore = defineStore<"canvasStore", TCanvasState, {}, TStoreAction>("canvasStore", {
|
const CanvasStore = defineStore<"canvasStore", TCanvasState, {}, TStoreAction>("canvasStore", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
dZoom: 0, // 画布缩放百分比
|
dZoom: 0, // 画布缩放百分比
|
||||||
dPaddingTop: 0, // 画布垂直居中修正值
|
dPresetPadding: 25, // 画布默认预留边距
|
||||||
|
dBottomHeight: 0, // 画布底部工具栏高度
|
||||||
|
dPaddingTop: 0, // 用于画布垂直居中的修正值
|
||||||
dScreen: {
|
dScreen: {
|
||||||
width: 0, // 记录编辑界面的宽度
|
width: 0, // 记录编辑界面的宽度
|
||||||
height: 0, // 记录编辑界面的高度
|
height: 0, // 记录编辑界面的高度
|
||||||
@ -24,30 +28,15 @@ const CanvasStore = defineStore<"canvasStore", TCanvasState, {}, TStoreAction>("
|
|||||||
verticalGuidelines: [],
|
verticalGuidelines: [],
|
||||||
horizontalGuidelines: [],
|
horizontalGuidelines: [],
|
||||||
},
|
},
|
||||||
dPage: {
|
dCurrentPage: 0,
|
||||||
name: '背景页面',
|
dPage: pageDefault
|
||||||
type: 'page',
|
|
||||||
uuid: '-1',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: 1920, // 画布宽度
|
|
||||||
height: 1080, // 画布高度
|
|
||||||
backgroundColor: '#ffffff', // 画布背景颜色
|
|
||||||
backgroundGradient: '', // 用于兼容渐变颜色
|
|
||||||
backgroundImage: '', // 画布背景图片
|
|
||||||
backgroundTransform: {},
|
|
||||||
opacity: 1, // 透明度
|
|
||||||
tag: 0, // 强制刷新用
|
|
||||||
setting: [
|
|
||||||
{
|
|
||||||
label: '背景颜色',
|
|
||||||
parentKey: 'backgroundColor',
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
record: {},
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
|
getters: {
|
||||||
|
getDPage() {
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
|
return widgetStore.dLayouts[this.dCurrentPage].global
|
||||||
|
},
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
/** 更新画布缩放百分比 */
|
/** 更新画布缩放百分比 */
|
||||||
updateZoom(zoom: number) {
|
updateZoom(zoom: number) {
|
||||||
@ -80,11 +69,27 @@ const CanvasStore = defineStore<"canvasStore", TCanvasState, {}, TStoreAction>("
|
|||||||
},
|
},
|
||||||
/** 设置 Page */
|
/** 设置 Page */
|
||||||
setDPage(data: TPageState) {
|
setDPage(data: TPageState) {
|
||||||
const cur = this.dPage
|
this.dPage = data
|
||||||
const keys = Object.keys(data) as (keyof TPageState)[];
|
this.updateDPage()
|
||||||
keys.forEach(val => {
|
// const cur = this.dPage
|
||||||
cur[val] = data[val]
|
// const keys = Object.keys(data) as (keyof TPageState)[];
|
||||||
})
|
// keys.forEach(val => {
|
||||||
|
// cur[val] = data[val]
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
/** 更新 Page(layouts)*/
|
||||||
|
updateDPage() {
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
|
widgetStore.dLayouts[this.dCurrentPage].global = this.dPage
|
||||||
|
// const cur = this.dPage
|
||||||
|
// const keys = Object.keys(data) as (keyof TPageState)[];
|
||||||
|
// keys.forEach(val => {
|
||||||
|
// cur[val] = data[val]
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
/** 设置底部工具栏高度 */
|
||||||
|
setBottomHeight(h: number) {
|
||||||
|
this.dBottomHeight = h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
22
src/store/design/canvas/page-default.ts
Normal file
22
src/store/design/canvas/page-default.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* @Author: ShawnPhang
|
||||||
|
* @Date: 2024-04-16 10:06:23
|
||||||
|
* @Description:
|
||||||
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
|
* @LastEditTime: 2024-04-16 10:06:32
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: '新画板',
|
||||||
|
type: 'page',
|
||||||
|
uuid: '-1',
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 1920, // 画布宽度
|
||||||
|
height: 1080, // 画布高度
|
||||||
|
backgroundColor: '#ffffffff', // 画布背景颜色
|
||||||
|
backgroundGradient: '', // 用于兼容渐变颜色
|
||||||
|
backgroundImage: '', // 画布背景图片
|
||||||
|
backgroundTransform: {},
|
||||||
|
opacity: 1, // 透明度
|
||||||
|
tag: 0, // 强制刷新用
|
||||||
|
}
|
@ -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:
|
* @Description:
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-27 21:00:00
|
* @LastEditTime: 2024-04-15 16:53:51
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Store, defineStore } from "pinia"
|
import { Store, defineStore } from 'pinia'
|
||||||
import {pushHistory, pushColorToHistory} from "./actions/pushHistory"
|
import { pushHistory, pushColorToHistory } from './actions/pushHistory'
|
||||||
import handleHistory from "./actions/handleHistory"
|
import handleHistory from './actions/handleHistory'
|
||||||
import { useCanvasStore, useWidgetStore } from "@/store"
|
import { useCanvasStore, useWidgetStore } from '@/store'
|
||||||
|
|
||||||
export type THistoryParamData = {
|
export type THistoryParamData = {
|
||||||
index: number
|
index: number
|
||||||
@ -20,11 +20,9 @@ export type THistoryParamData = {
|
|||||||
type THistoryState = {
|
type THistoryState = {
|
||||||
/** 记录历史操作(保存整个画布的json数据) */
|
/** 记录历史操作(保存整个画布的json数据) */
|
||||||
dHistory: string[]
|
dHistory: string[]
|
||||||
/** 记录历史操作对应的激活的组件的uuid */
|
|
||||||
dActiveUuidHistory: string[]
|
|
||||||
/** 记录历史操作对应的page */
|
/** 记录历史操作对应的page */
|
||||||
dPageHistory: string[]
|
dPageHistory: string[]
|
||||||
dHistoryParams: THistoryParamData,
|
dHistoryParams: THistoryParamData
|
||||||
/** 记录历史选择的颜色 */
|
/** 记录历史选择的颜色 */
|
||||||
dColorHistory: string[]
|
dColorHistory: string[]
|
||||||
}
|
}
|
||||||
@ -41,12 +39,12 @@ type THistoryAction = {
|
|||||||
* action为undo表示撤销
|
* action为undo表示撤销
|
||||||
* action为redo表示重做
|
* action为redo表示重做
|
||||||
*/
|
*/
|
||||||
handleHistory: (action: "undo" | "redo") => void
|
handleHistory: (action: 'undo' | 'redo') => void
|
||||||
pushColorToHistory: (color: string) => void
|
pushColorToHistory: (color: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 历史记录Store */
|
/** 历史记录Store */
|
||||||
const HistoryStore = defineStore<"historyStore", THistoryState, {}, THistoryAction>("historyStore", {
|
const HistoryStore = defineStore<'historyStore', THistoryState, {}, THistoryAction>('historyStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
dHistory: [],
|
dHistory: [],
|
||||||
dHistoryParams: {
|
dHistoryParams: {
|
||||||
@ -54,9 +52,8 @@ const HistoryStore = defineStore<"historyStore", THistoryState, {}, THistoryActi
|
|||||||
length: 0,
|
length: 0,
|
||||||
maxLength: 20,
|
maxLength: 20,
|
||||||
},
|
},
|
||||||
dActiveUuidHistory: [],
|
|
||||||
dColorHistory: [],
|
dColorHistory: [],
|
||||||
dPageHistory: []
|
dPageHistory: [],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -72,10 +69,10 @@ const HistoryStore = defineStore<"historyStore", THistoryState, {}, THistoryActi
|
|||||||
},
|
},
|
||||||
pushColorToHistory(color) {
|
pushColorToHistory(color) {
|
||||||
pushColorToHistory(this, color)
|
pushColorToHistory(this, color)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export type THistoryStore = Store<"historyStore", THistoryState, {}, THistoryAction>
|
export type THistoryStore = Store<'historyStore', THistoryState, {}, THistoryAction>
|
||||||
|
|
||||||
export default HistoryStore
|
export default HistoryStore
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2024-03-18 21:00:00
|
* @Date: 2024-03-18 21:00:00
|
||||||
* @Description: Store方法export
|
* @Description: Store方法export
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-10 18:01:14
|
* @LastEditTime: 2024-04-16 17:25:42
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCanvasStore, useControlStore } from '@/store'
|
import { useCanvasStore, useControlStore } from '@/store'
|
||||||
@ -136,8 +136,10 @@ export function autoResizeAll(store: TWidgetStore, lastPageSize: TSize) {
|
|||||||
let diff = 0
|
let diff = 0
|
||||||
if (widget.type === 'w-text') {
|
if (widget.type === 'w-text') {
|
||||||
widget.fontSize && (widget.fontSize *= ratio)
|
widget.fontSize && (widget.fontSize *= ratio)
|
||||||
|
} else if (widget.type !== 'w-group') {
|
||||||
|
widget.width *= ratio
|
||||||
|
widget.height *= ratio
|
||||||
} else widget.height *= ratio
|
} else widget.height *= ratio
|
||||||
widget.width *= ratio
|
|
||||||
diff = (originWidth - widget.width) / 2
|
diff = (originWidth - widget.width) / 2
|
||||||
widget.left = widget.left + diff + pageDiff
|
widget.left = widget.left + diff + pageDiff
|
||||||
widget.top *= degree[1]
|
widget.top *= degree[1]
|
||||||
|
@ -2,29 +2,27 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-28 21:00:00
|
* @Date: 2024-03-28 21:00:00
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-28 14:00:00
|
* @LastEditTime: 2024-04-16 01:03:05
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { customAlphabet } from 'nanoid/non-secure'
|
import { customAlphabet } from 'nanoid/non-secure'
|
||||||
import { TWidgetStore, TdWidgetData } from '..'
|
import { TWidgetStore, TdWidgetData } from '..'
|
||||||
import { useCanvasStore, useHistoryStore } from '@/store'
|
import { useCanvasStore, useWidgetStore } from '@/store'
|
||||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||||
|
|
||||||
// TODO: 选择模板
|
// TODO: 选择模板
|
||||||
export function setTemplate(store: TWidgetStore, allWidgets: TdWidgetData[]) {
|
export function setTemplate(store: TWidgetStore, allWidgets: TdWidgetData[]) {
|
||||||
const historyStore = useHistoryStore()
|
// const historyStore = useHistoryStore()
|
||||||
const canvasStore = useCanvasStore()
|
const canvasStore = useCanvasStore()
|
||||||
|
const widgetStore = useWidgetStore()
|
||||||
allWidgets.forEach((item) => {
|
allWidgets.forEach((item) => {
|
||||||
Number(item.uuid) < 0 && (item.uuid = nanoid()) // 重设id
|
Number(item.uuid) < 0 && (item.uuid = nanoid()) // 重设id
|
||||||
item.text && (item.text = decodeURIComponent(item.text))
|
item.text && (item.text = decodeURIComponent(item.text))
|
||||||
store.dWidgets.push(item)
|
store.dWidgets.push(item)
|
||||||
})
|
})
|
||||||
|
widgetStore.updateDWidgets()
|
||||||
historyStore.pushHistory("setTemplate")
|
// historyStore.pushHistory("setTemplate")
|
||||||
// store.dispatch('pushHistory', 'setTemplate')
|
|
||||||
|
|
||||||
canvasStore.reChangeCanvas()
|
canvasStore.reChangeCanvas()
|
||||||
// store.dispatch('reChangeCanvas')
|
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-28 21:00:00
|
* @Date: 2024-03-28 21:00:00
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-28 14:00:00
|
* @LastEditTime: 2024-04-16 11:12:40
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCanvasStore, useHistoryStore } from "@/store"
|
import { useCanvasStore, useHistoryStore } from '@/store'
|
||||||
import { TWidgetStore, TdWidgetData } from ".."
|
import { TWidgetStore, TdWidgetData } from '..'
|
||||||
import { customAlphabet } from 'nanoid/non-secure'
|
import { customAlphabet } from 'nanoid/non-secure'
|
||||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||||
|
|
||||||
@ -57,11 +57,11 @@ export function updateWidgetData(store: TWidgetStore, { uuid, key, value, pushHi
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
(widget[key] as TUpdateWidgetPayload['value']) = value
|
;(widget[key] as TUpdateWidgetPayload['value']) = value
|
||||||
if (pushHistory) {
|
if (pushHistory) {
|
||||||
const historyStore = useHistoryStore()
|
const historyStore = useHistoryStore()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
historyStore.pushHistory("updateWidgetData")
|
historyStore.pushHistory('updateWidgetData')
|
||||||
// pushHistory && store.dispatch('pushHistory', 'updateWidgetData')
|
// pushHistory && store.dispatch('pushHistory', 'updateWidgetData')
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
@ -107,12 +107,12 @@ export function updateWidgetMultiple(store: TWidgetStore, { uuid, data, pushHist
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
(widget[key] as number | string) = value
|
;(widget[key] as number | string) = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const historyStore = useHistoryStore()
|
const historyStore = useHistoryStore()
|
||||||
historyStore.pushHistory("updateWidgetMultiple")
|
historyStore.pushHistory('updateWidgetMultiple')
|
||||||
// store.dispatch('pushHistory', 'updateWidgetMultiple')
|
// store.dispatch('pushHistory', 'updateWidgetMultiple')
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ export function addWidget(store: TWidgetStore, setting: TdWidgetData) {
|
|||||||
// uuid: store.dWidgets[len - 1].uuid,
|
// uuid: store.dWidgets[len - 1].uuid,
|
||||||
// })
|
// })
|
||||||
|
|
||||||
historyStore.pushHistory("addWidget")
|
historyStore.pushHistory('addWidget')
|
||||||
// store.dispatch('pushHistory', 'addWidget')
|
// store.dispatch('pushHistory', 'addWidget')
|
||||||
canvasStore.reChangeCanvas()
|
canvasStore.reChangeCanvas()
|
||||||
// store.dispatch('reChangeCanvas')
|
// store.dispatch('reChangeCanvas')
|
||||||
@ -154,12 +154,15 @@ export function deleteWidget(store: TWidgetStore) {
|
|||||||
const uuid = selectWidgets[i].uuid
|
const uuid = selectWidgets[i].uuid
|
||||||
const index = widgets.findIndex((item) => item.uuid === uuid)
|
const index = widgets.findIndex((item) => item.uuid === uuid)
|
||||||
widgets.splice(index, 1)
|
widgets.splice(index, 1)
|
||||||
try {
|
// try {
|
||||||
// 清除掉可能存在的选中框
|
// // 清除掉可能存在的中框
|
||||||
document.getElementById(uuid)?.classList.remove('widget-selected')
|
// document.getElementById(uuid)?.classList.remove('widget-selected')
|
||||||
} catch (e) {}
|
// } catch (e) {}
|
||||||
}
|
}
|
||||||
store.dSelectWidgets = []
|
store.dSelectWidgets = []
|
||||||
|
store.selectWidget({
|
||||||
|
uuid: '-1',
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
if (activeElement.type === 'page') {
|
if (activeElement.type === 'page') {
|
||||||
return
|
return
|
||||||
@ -213,7 +216,7 @@ export function deleteWidget(store: TWidgetStore) {
|
|||||||
// store.dispatch('updateGroupSize', store.dActiveElement.uuid)
|
// store.dispatch('updateGroupSize', store.dActiveElement.uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
historyStore.pushHistory("deleteWidget")
|
historyStore.pushHistory('deleteWidget')
|
||||||
// store.dispatch('pushHistory', 'deleteWidget')
|
// store.dispatch('pushHistory', 'deleteWidget')
|
||||||
canvasStore.reChangeCanvas()
|
canvasStore.reChangeCanvas()
|
||||||
// store.dispatch('reChangeCanvas')
|
// store.dispatch('reChangeCanvas')
|
||||||
@ -229,11 +232,19 @@ export type TsetWidgetStyleData = {
|
|||||||
export function setWidgetStyle(state: TWidgetStore, { uuid, key, value, pushHistory }: TsetWidgetStyleData) {
|
export function setWidgetStyle(state: TWidgetStore, { uuid, key, value, pushHistory }: TsetWidgetStyleData) {
|
||||||
const widget = state.dWidgets.find((item) => item.uuid === uuid)
|
const widget = state.dWidgets.find((item) => item.uuid === uuid)
|
||||||
if (!widget) return
|
if (!widget) return
|
||||||
(widget[key] as Record<string, any>) = value
|
;(widget[key] as Record<string, any>) = value
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setDWidgets(state: TWidgetStore, e: TdWidgetData[]) {
|
export function setDWidgets(state: TWidgetStore, e: TdWidgetData[]) {
|
||||||
state.dWidgets = e
|
state.dWidgets = e
|
||||||
|
updateDWidgets(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateDWidgets(state: TWidgetStore) {
|
||||||
|
const pageStore = useCanvasStore()
|
||||||
|
const { dCurrentPage } = pageStore
|
||||||
|
state.dLayouts[dCurrentPage].layers = state.dWidgets
|
||||||
|
state.dWidgets = state.getWidgets
|
||||||
}
|
}
|
||||||
|
|
||||||
// 锁定所有图层 / 再次调用时还原图层
|
// 锁定所有图层 / 再次调用时还原图层
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
* @Author: Jeremy Yu
|
* @Author: Jeremy Yu
|
||||||
* @Date: 2024-03-28 14:00:00
|
* @Date: 2024-03-28 14:00:00
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-03-28 14:00:00
|
* @LastEditTime: 2024-04-15 16:54:45
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCanvasStore } from "@/store"
|
import { useCanvasStore } from '@/store'
|
||||||
import { TWidgetState, TdWidgetData } from ".."
|
import { TWidgetState, TdWidgetData } from '..'
|
||||||
import { TPageState } from "@/store/design/canvas/d"
|
import { TPageState } from '@/store/design/canvas/d'
|
||||||
|
|
||||||
export type TWidgetJsonData = TPageState & {
|
export type TWidgetJsonData = TPageState & {
|
||||||
widgets: TdWidgetData
|
widgets: TdWidgetData
|
||||||
@ -17,9 +17,7 @@ export type TWidgetJsonData = TPageState & {
|
|||||||
/** 返回组件Json数据 */
|
/** 返回组件Json数据 */
|
||||||
export function widgetJsonData(state: TWidgetState) {
|
export function widgetJsonData(state: TWidgetState) {
|
||||||
const pageStore = useCanvasStore()
|
const pageStore = useCanvasStore()
|
||||||
const page: TWidgetJsonData = JSON.parse(JSON.stringify(pageStore.dPage))
|
const { dCurrentPage } = pageStore
|
||||||
const widgets = JSON.parse(JSON.stringify(state.dWidgets))
|
// const page: TWidgetJsonData = JSON.parse(JSON.stringify(pageStore.dPage))
|
||||||
page.widgets = widgets
|
return state.dLayouts[dCurrentPage].layers
|
||||||
|
|
||||||
return page
|
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
* @Date: 2024-03-18 21:00:00
|
* @Date: 2024-03-18 21:00:00
|
||||||
* @Description: Store方法export
|
* @Description: Store方法export
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-10 08:17:16
|
* @LastEditTime: 2024-04-16 10:07:13
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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, TSize, TdResizePayload, dResize, initDResize, resize, autoResizeAll } 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, updateDWidgets, 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";
|
||||||
import { copyWidget, pasteWidget } from "./actions/clone";
|
import { copyWidget, pasteWidget } from "./actions/clone";
|
||||||
@ -18,6 +18,7 @@ import { TSelectWidgetData, TselectItem, selectItem, selectWidget, selectWidgets
|
|||||||
import { TUpdateAlignData, updateAlign } from "./actions/align";
|
import { TUpdateAlignData, updateAlign } from "./actions/align";
|
||||||
import { TWidgetJsonData, widgetJsonData } from "./getter";
|
import { TWidgetJsonData, widgetJsonData } from "./getter";
|
||||||
import { TupdateLayerIndexData, ungroup, updateLayerIndex } from "./actions/layer";
|
import { TupdateLayerIndexData, ungroup, updateLayerIndex } from "./actions/layer";
|
||||||
|
import pageDefault from "../canvas/page-default";
|
||||||
|
|
||||||
export type TdWidgetData = TPageState & Partial<TCommonItemData> & {
|
export type TdWidgetData = TPageState & Partial<TCommonItemData> & {
|
||||||
parent?: string
|
parent?: string
|
||||||
@ -35,6 +36,11 @@ export type TdWidgetData = TPageState & Partial<TCommonItemData> & {
|
|||||||
writingMode?: string
|
writingMode?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TdLayout = {
|
||||||
|
global: TPageState
|
||||||
|
layers: TdWidgetData[]
|
||||||
|
}
|
||||||
|
|
||||||
export type TWidgetState = {
|
export type TWidgetState = {
|
||||||
dActiveWidgetXY: {
|
dActiveWidgetXY: {
|
||||||
/** 选中组件的横向初始值 */
|
/** 选中组件的横向初始值 */
|
||||||
@ -61,6 +67,8 @@ export type TWidgetState = {
|
|||||||
dDropOverUuid: string
|
dDropOverUuid: string
|
||||||
/** 已使用的组件 */
|
/** 已使用的组件 */
|
||||||
dWidgets: TdWidgetData[]
|
dWidgets: TdWidgetData[]
|
||||||
|
/** 所有图层数据与页面数据 */
|
||||||
|
dLayouts: TdLayout[]
|
||||||
/** 记录多选的组件 */
|
/** 记录多选的组件 */
|
||||||
dSelectWidgets: TdWidgetData[]
|
dSelectWidgets: TdWidgetData[]
|
||||||
/** 复制的组件(可能是单个也可能是数组) */
|
/** 复制的组件(可能是单个也可能是数组) */
|
||||||
@ -72,7 +80,7 @@ export type TWidgetState = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TGetter = {
|
type TGetter = {
|
||||||
getWidgetJsonData(state: TWidgetState): TWidgetJsonData
|
getWidgets(state: TWidgetState): TWidgetJsonData
|
||||||
}
|
}
|
||||||
|
|
||||||
type TAction = {
|
type TAction = {
|
||||||
@ -116,6 +124,7 @@ type TAction = {
|
|||||||
resize: (data: TSize) => void
|
resize: (data: TSize) => void
|
||||||
setWidgetStyle: (data: TsetWidgetStyleData) => void
|
setWidgetStyle: (data: TsetWidgetStyleData) => void
|
||||||
setDWidgets: (data: TdWidgetData[]) => void
|
setDWidgets: (data: TdWidgetData[]) => void
|
||||||
|
updateDWidgets: () => void
|
||||||
lockWidgets: () => void
|
lockWidgets: () => void
|
||||||
setMouseEvent: (e: MouseEvent | null) => void
|
setMouseEvent: (e: MouseEvent | null) => void
|
||||||
setdActiveElement: (data: TdWidgetData) => void
|
setdActiveElement: (data: TdWidgetData) => void
|
||||||
@ -141,6 +150,10 @@ const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("
|
|||||||
dHoverUuid: '-1', // 鼠标在这个图层上
|
dHoverUuid: '-1', // 鼠标在这个图层上
|
||||||
dDropOverUuid: '', // 拖动时放在哪个图层上
|
dDropOverUuid: '', // 拖动时放在哪个图层上
|
||||||
dWidgets: [], // 已使用的组件
|
dWidgets: [], // 已使用的组件
|
||||||
|
dLayouts: [{
|
||||||
|
global: pageDefault,
|
||||||
|
layers: []
|
||||||
|
}], // 页面与图层数据
|
||||||
dSelectWidgets: [], // 记录多选的组件
|
dSelectWidgets: [], // 记录多选的组件
|
||||||
selectItem: { data: null }, // 记录当前选择的元素, data
|
selectItem: { data: null }, // 记录当前选择的元素, data
|
||||||
activeMouseEvent: null, // 正在活动的鼠标事件
|
activeMouseEvent: null, // 正在活动的鼠标事件
|
||||||
@ -148,7 +161,7 @@ const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
getWidgetJsonData(store) {
|
getWidgets(store) {
|
||||||
return widgetJsonData(store)
|
return widgetJsonData(store)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -178,6 +191,7 @@ const WidgetStore = defineStore<"widgetStore", TWidgetState, TGetter, TAction>("
|
|||||||
resize(data) { resize(this, data) },
|
resize(data) { resize(this, data) },
|
||||||
setWidgetStyle(data) { setWidgetStyle(this, data) },
|
setWidgetStyle(data) { setWidgetStyle(this, data) },
|
||||||
setDWidgets(data) { setDWidgets(this, data) },
|
setDWidgets(data) { setDWidgets(this, data) },
|
||||||
|
updateDWidgets() { updateDWidgets(this) },
|
||||||
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) },
|
||||||
|
@ -2,16 +2,15 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-07-13 02:48:38
|
* @Date: 2021-07-13 02:48:38
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>, Jeremy Yu <https://github.com/JeremyYu-cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2022-03-07 20:25:54
|
* @LastEditTime: 2024-04-13 18:19:28
|
||||||
*/
|
*/
|
||||||
// import store from '../store'
|
|
||||||
import * as services from '../api/index'
|
import * as services from '../api/index'
|
||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
import _config from '@/config'
|
import _config from '@/config'
|
||||||
import modules from './plugins/modules'
|
import modules from './plugins/modules'
|
||||||
import cssLoader from './plugins/cssLoader'
|
import cssLoader from './plugins/cssLoader'
|
||||||
import type {App} from 'vue'
|
import type { App } from 'vue'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局组件方法
|
* 全局组件方法
|
||||||
@ -28,9 +27,12 @@ export default {
|
|||||||
|
|
||||||
myVue.config.globalProperties.$utils = utils
|
myVue.config.globalProperties.$utils = utils
|
||||||
|
|
||||||
// myVue.config.globalProperties.$bus =
|
// baidu statistics
|
||||||
|
;(function () {
|
||||||
// myVue.prototype.$Ilist = List;
|
const hm = document.createElement('script')
|
||||||
// myVue.prototype.$Imap = mmap;
|
hm.src = 'https://hm.baidu.com/hm.js?21238d2872af8b12083429237026b84c'
|
||||||
|
const s: any = document.getElementsByTagName('script')[0]
|
||||||
|
s.parentNode.insertBefore(hm, s)
|
||||||
|
})()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ 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 { 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'
|
||||||
import { useGroupStore, useCanvasStore, useWidgetStore } from '@/store'
|
import { useGroupStore, useCanvasStore, useWidgetStore } from '@/store'
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ const state = reactive<TState>({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
const pageStore = useCanvasStore()
|
const pageStore = useCanvasStore()
|
||||||
const groupStore = useGroupStore()
|
// const groupStore = useGroupStore()
|
||||||
const widgetStore = useWidgetStore()
|
const widgetStore = useWidgetStore()
|
||||||
const { dPage } = storeToRefs(pageStore)
|
const { dPage } = storeToRefs(pageStore)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
groupStore.initGroupJson(JSON.stringify(wGroupSetting))
|
// groupStore.initGroupJson(JSON.stringify(wGroupSetting))
|
||||||
// store.dispatch('initGroupJson', JSON.stringify(wGroupSetting))
|
// store.dispatch('initGroupJson', JSON.stringify(wGroupSetting))
|
||||||
// initGroupJson(JSON.stringify(wGroup.setting))
|
// initGroupJson(JSON.stringify(wGroup.setting))
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@ -48,37 +48,37 @@ onMounted(() => {
|
|||||||
async function load() {
|
async function load() {
|
||||||
let backgroundImage = ''
|
let backgroundImage = ''
|
||||||
let loadFlag = false
|
let loadFlag = false
|
||||||
const { id, tempid, tempType: type = 0 } = route.query
|
const { id, tempid, tempType: type = 0, index = 0 }: any = route.query
|
||||||
if (id || tempid) {
|
if (id || tempid) {
|
||||||
const postData = {
|
const postData = {
|
||||||
id: Number(id || tempid),
|
id: Number(id || tempid),
|
||||||
type: Number(type)
|
type: Number(type)
|
||||||
}
|
}
|
||||||
const { data, width, height } = await api.home[id ? 'getWorks' : 'getTempDetail'](postData)
|
const { data, width, height } = await api.home[id ? 'getWorks' : 'getTempDetail'](postData)
|
||||||
const content = JSON.parse(data)
|
let content = JSON.parse(data)
|
||||||
const widgets = Number(type) == 1 ? content : content.widgets
|
const isGroupTemplate = Number(type) == 1
|
||||||
|
|
||||||
if (Number(type) == 1) {
|
if (Array.isArray(content)) {
|
||||||
|
const { global, layers } = content[index]
|
||||||
|
content = {page: global, widgets: layers}
|
||||||
|
}
|
||||||
|
const widgets = isGroupTemplate ? content : content.widgets
|
||||||
|
|
||||||
|
if (isGroupTemplate) {
|
||||||
dPage.value.width = width
|
dPage.value.width = width
|
||||||
dPage.value.height = height
|
dPage.value.height = height
|
||||||
dPage.value.backgroundColor = '#ffffff00'
|
dPage.value.backgroundColor = '#ffffff00'
|
||||||
widgetStore.addGroup(content)
|
widgetStore.addGroup(content)
|
||||||
// store.dispatch('addGroup', content)
|
|
||||||
// addGroup(content)
|
|
||||||
} else {
|
} else {
|
||||||
pageStore.setDPage(content.page)
|
pageStore.setDPage(content.page)
|
||||||
// store.commit('setDPage', content.page)
|
|
||||||
// 移除背景图,作为独立事件
|
// 移除背景图,作为独立事件
|
||||||
backgroundImage = content.page?.backgroundImage
|
backgroundImage = content.page?.backgroundImage
|
||||||
backgroundImage && delete content.page.backgroundImage
|
backgroundImage && delete content.page.backgroundImage
|
||||||
pageStore.setDPage(content.page)
|
pageStore.setDPage(content.page)
|
||||||
// store.commit('setDPage', content.page)
|
|
||||||
if (id) {
|
if (id) {
|
||||||
widgetStore.setDWidgets(widgets)
|
widgetStore.setDWidgets(widgets)
|
||||||
// store.commit('setDWidgets', widgets)
|
|
||||||
} else {
|
} else {
|
||||||
widgetStore.setTemplate(widgets)
|
widgetStore.setTemplate(widgets)
|
||||||
// store.dispatch('setTemplate', widgets)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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-10 07:16:48
|
* @LastEditTime: 2024-04-16 11:35:11
|
||||||
-->
|
-->
|
||||||
<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">
|
||||||
@ -37,6 +37,8 @@
|
|||||||
<div class="shelter" :style="{ width: Math.floor((dPage.width * dZoom) / 100) + 'px', height: Math.floor((dPage.height * dZoom) / 100) + 'px' }"></div>
|
<div class="shelter" :style="{ width: Math.floor((dPage.width * dZoom) / 100) + 'px', height: Math.floor((dPage.height * dZoom) / 100) + 'px' }"></div>
|
||||||
<!-- 提供一个背景图层 -->
|
<!-- 提供一个背景图层 -->
|
||||||
<div class="shelter-bg transparent-bg" :style="{ width: Math.floor((dPage.width * dZoom) / 100) + 'px', height: Math.floor((dPage.height * dZoom) / 100) + 'px' }"></div>
|
<div class="shelter-bg transparent-bg" :style="{ width: Math.floor((dPage.width * dZoom) / 100) + 'px', height: Math.floor((dPage.height * dZoom) / 100) + 'px' }"></div>
|
||||||
|
<!-- 多画板操作组件 -->
|
||||||
|
<template #bottom> <multipleBoards /> </template>
|
||||||
</design-board>
|
</design-board>
|
||||||
<style-panel ref="ref3"></style-panel>
|
<style-panel ref="ref3"></style-panel>
|
||||||
</div>
|
</div>
|
||||||
@ -86,6 +88,7 @@ import { useCanvasStore, useControlStore, useHistoryStore, useWidgetStore, useGr
|
|||||||
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'
|
import createDesign from '@/components/business/create-design'
|
||||||
|
import multipleBoards from '@/components/modules/layout/multipleBoards'
|
||||||
|
|
||||||
const ref1 = ref<ButtonInstance>()
|
const ref1 = ref<ButtonInstance>()
|
||||||
const ref2 = ref<ButtonInstance>()
|
const ref2 = ref<ButtonInstance>()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-01-10 14:57:53
|
* @Date: 2022-01-10 14:57:53
|
||||||
* @Description: Psd文件解析
|
* @Description: Psd文件解析
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2024-04-03 20:58:43
|
* @LastEditTime: 2024-04-11 15:37:38
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div id="page-design-index" ref="pageDesignIndex">
|
<div id="page-design-index" ref="pageDesignIndex">
|
||||||
@ -156,12 +156,7 @@ async function loadPSD(file: File) {
|
|||||||
|
|
||||||
async function clear() {
|
async function clear() {
|
||||||
widgetStore.setDWidgets([])
|
widgetStore.setDWidgets([])
|
||||||
// store.commit('setDWidgets', [])
|
|
||||||
|
|
||||||
pageStore.setDPage(Object.assign(pageStore.dPage, { width: 1920, height: 1080, backgroundColor: '#ffffff', backgroundImage: '' }))
|
pageStore.setDPage(Object.assign(pageStore.dPage, { width: 1920, height: 1080, backgroundColor: '#ffffff', backgroundImage: '' }))
|
||||||
// store.commit('setDPage', Object.assign(store.getters.dPage, { width: 1920, height: 1080, backgroundColor: '#ffffff', backgroundImage: '' }))
|
|
||||||
|
|
||||||
// store.commit('setShowMoveable', false)
|
|
||||||
controlStore.setShowMoveable(false)
|
controlStore.setShowMoveable(false)
|
||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
@ -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-09 23:39:24
|
* @LastEditTime: 2024-04-16 15:38:39
|
||||||
-->
|
-->
|
||||||
<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>
|
||||||
@ -94,14 +94,13 @@ async function save(hasCover: boolean = false) {
|
|||||||
if (dHistory.value.length <= 0) {
|
if (dHistory.value.length <= 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
|
||||||
// console.log(proxy?.dPage, proxy?.dWidgets)
|
// console.log(proxy?.dPage, proxy?.dWidgets)
|
||||||
const { id, tempid } = route.query
|
const { id, tempid } = route.query
|
||||||
const cover = hasCover ? await draw() : undefined
|
const cover = hasCover ? await draw() : undefined
|
||||||
const widgets = dWidgets.value // reviseData()
|
// const widgets = dWidgets.value // reviseData()
|
||||||
const { id: newId, stat, msg } = await api.home.saveWorks({ cover, id: (id as string), title: state.title || '未命名设计', data: JSON.stringify({ page: dPage.value, widgets }), temp_id: (tempid as string), width: dPage.value.width, height: dPage.value.height })
|
const data = widgetStore.dLayouts
|
||||||
|
const { id: newId, stat, msg } = await api.home.saveWorks({ cover, id: (id as string), title: state.title || '未命名设计', data: JSON.stringify(data), temp_id: (tempid as string), width: dPage.value.width, height: dPage.value.height })
|
||||||
stat !== 0 ? useNotification('保存成功', '可在"我的作品"中查看') : useNotification('保存失败', msg, { type: 'error' })
|
stat !== 0 ? useNotification('保存成功', '可在"我的作品"中查看') : useNotification('保存失败', msg, { type: 'error' })
|
||||||
!id && router.push({ path: '/home', query: { id: newId }, replace: true })
|
!id && router.push({ path: '/home', query: { id: newId }, replace: true })
|
||||||
controlStore.setShowMoveable(true)
|
controlStore.setShowMoveable(true)
|
||||||
@ -168,7 +167,7 @@ async function saveTemp() {
|
|||||||
clearInterval(animation)
|
clearInterval(animation)
|
||||||
}
|
}
|
||||||
}, 800)
|
}, 800)
|
||||||
await _dl.downloadImg(api.home.download({ id, width, height }) + '&r=' + Math.random(), (progress: number, xhr: any) => {
|
await _dl.downloadImg(api.home.download({ id, width, height, index: pageStore.dCurrentPage }) + '&r=' + Math.random(), (progress: number, xhr: any) => {
|
||||||
if (props.modelValue) {
|
if (props.modelValue) {
|
||||||
clearInterval(animation)
|
clearInterval(animation)
|
||||||
progress >= timerCount && emit('change', { downloadPercent: Number(progress.toFixed(0)), downloadText: '图片生成中' })
|
progress >= timerCount && emit('change', { downloadPercent: Number(progress.toFixed(0)), downloadText: '图片生成中' })
|
||||||
@ -198,7 +197,8 @@ async function load(cb: () => void) {
|
|||||||
await useFontStore.init() // 初始化加载字体
|
await useFontStore.init() // 初始化加载字体
|
||||||
}
|
}
|
||||||
const apiName = tempId && !id ? 'getTempDetail' : 'getWorks'
|
const apiName = tempId && !id ? 'getTempDetail' : 'getWorks'
|
||||||
if (w_h) {
|
if (w_h && !id && !tempId) {
|
||||||
|
// 用于初始化画布大小,创建空作品
|
||||||
const wh: any = w_h.toString().split('*')
|
const wh: any = w_h.toString().split('*')
|
||||||
wh[0] && (dPage.value.width = wh[0])
|
wh[0] && (dPage.value.width = wh[0])
|
||||||
wh[1] && (dPage.value.height = wh[1])
|
wh[1] && (dPage.value.height = wh[1])
|
||||||
@ -208,25 +208,29 @@ async function load(cb: () => void) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { data: content, title, state: _state, width, height } = await api.home[apiName]({ id: id || tempId, type })
|
const { data: content, title, state: _state, width, height } = await api.home[apiName]({ id: id || tempId, type })
|
||||||
if (content) {
|
if (!content) return
|
||||||
const data = JSON.parse(content)
|
const data = JSON.parse(content)
|
||||||
state.stateBollean = !!_state
|
state.stateBollean = !!_state
|
||||||
state.title = title
|
state.title = title
|
||||||
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
controlStore.setShowMoveable(false) // 清理掉上一次的选择框
|
||||||
|
if (type == 1) {
|
||||||
// this.$store.commit('setDWidgets', [])
|
// 加载文字组合组件
|
||||||
if (type == 1) {
|
dPage.value.width = width
|
||||||
// 加载文字组合组件
|
dPage.value.height = height
|
||||||
dPage.value.width = width
|
widgetStore.addGroup(data)
|
||||||
dPage.value.height = height
|
} else {
|
||||||
widgetStore.addGroup(data)
|
if (Array.isArray(data)) {
|
||||||
|
widgetStore.dLayouts = data
|
||||||
|
widgetStore.setDWidgets(widgetStore.getWidgets)
|
||||||
} else {
|
} else {
|
||||||
pageStore.setDPage(data.page)
|
widgetStore.dLayouts = [{global: data.page, layers: data.widgets}]
|
||||||
id ? widgetStore.setDWidgets(data.widgets) : widgetStore.setTemplate(data.widgets)
|
id ? widgetStore.setDWidgets(widgetStore.getWidgets) : widgetStore.setTemplate(widgetStore.getWidgets)
|
||||||
}
|
}
|
||||||
cb()
|
pageStore.setDPage(pageStore.getDPage)
|
||||||
historyStore.pushHistory('请求加载load')
|
// id ? widgetStore.setDWidgets(data.widgets) : widgetStore.setTemplate(data.widgets)
|
||||||
}
|
}
|
||||||
|
cb()
|
||||||
|
historyStore.pushHistory('请求加载load')
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user