mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-28 04:10:31 +08:00
feat: moveable 迁移到vue3
This commit is contained in:
parent
50d193c067
commit
2ae7b0fd4c
3
.gitignore
vendored
3
.gitignore
vendored
@ -25,3 +25,6 @@ pnpm-debug.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
|
||||
**/dist/
|
||||
|
@ -1,7 +1,7 @@
|
||||
// .prettierrc.js 代码美化规则配置
|
||||
module.exports = {
|
||||
// 一行最多 n 字符
|
||||
printWidth: 1000,
|
||||
printWidth: 200,
|
||||
// 使用 2 个空格缩进
|
||||
tabWidth: 2,
|
||||
// 不使用缩进符,而使用空格
|
||||
|
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
@ -9,5 +9,16 @@
|
||||
},
|
||||
"css.validate": false,
|
||||
"less.validate": false,
|
||||
"scss.validate": false
|
||||
"scss.validate": false,
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"clippable",
|
||||
"pinchable",
|
||||
"pinia",
|
||||
"snappable",
|
||||
"ungroup",
|
||||
"warpable"
|
||||
]
|
||||
}
|
||||
|
2038
package-lock.json
generated
2038
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -26,17 +26,18 @@
|
||||
"fontfaceobserver": "^2.1.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"mitt": "^3.0.1",
|
||||
"moveable": "^0.26.0",
|
||||
"moveable-helper": "^0.4.0",
|
||||
"nanoid": "^3.1.23",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^2.1.7",
|
||||
"prepared": "^0.1.1",
|
||||
"qr-code-styling": "^1.6.0-rc.1",
|
||||
"selecto": "^1.13.0",
|
||||
"selecto": "^1.26.3",
|
||||
"throttle-debounce": "^3.0.1",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vue": "3.4.19",
|
||||
"vue-router": "^4.0.0-0",
|
||||
"vue3-moveable": "^0.28.0",
|
||||
"vue3-selecto": "^1.12.3",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -53,6 +54,7 @@
|
||||
"eslint-config-alloy": "~4.1.0",
|
||||
"eslint-plugin-vue": "^7.12.1",
|
||||
"less": "^4.1.1",
|
||||
"prettier-eslint": "^16.3.0",
|
||||
"terser": "^5.28.1",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-element-plus": "^0.7.1",
|
||||
|
3096
screenshot/package-lock.json
generated
Normal file
3096
screenshot/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -47,7 +47,7 @@ export type TGetFontParam = {
|
||||
|
||||
/** 字体item数据 */
|
||||
export type TGetFontItemData = {
|
||||
id: number
|
||||
id: number | string
|
||||
alias: string
|
||||
oid: string
|
||||
value: string
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
import Selecto from 'selecto'
|
||||
import Moveable, { getElementInfo } from 'moveable'
|
||||
// import store from '@/store'
|
||||
import { useWidgetStore, useControlStore } from '@/store'
|
||||
|
||||
export default function(moveable: Moveable) {
|
||||
const widgetStore = useWidgetStore()
|
||||
const controlStore = useControlStore()
|
||||
const selecto = new Selecto({
|
||||
container: document.getElementById('page-design'),
|
||||
selectableTargets: ['.layer'],
|
||||
selectByClick: false,
|
||||
// 是否从内部目标中选择(default: true)
|
||||
selectFromInside: false,
|
||||
// 选择后,是否与所选目标一起选择下一个目标
|
||||
continueSelect: false,
|
||||
// Determines which key to continue selecting the next target via keydown and keyup.
|
||||
toggleContinueSelect: 'shift',
|
||||
// The container for keydown and keyup events
|
||||
keyContainer: document.getElementById('page-design'),
|
||||
// 目标与要选择的拖动区域重叠的速率。(默认:100)
|
||||
hitRate: 5,
|
||||
getElementRect: getElementInfo,
|
||||
})
|
||||
selecto.on('select', (e) => {
|
||||
e.added.forEach((el) => {
|
||||
if (!Array.from(el.classList).includes('layer-lock') && !el.hasAttribute('child')) {
|
||||
el.classList.add('widget-selected')
|
||||
widgetStore.selectWidgetsInOut({
|
||||
uuid: el.getAttribute('data-uuid') || "",
|
||||
})
|
||||
// store.dispatch('selectWidgetsInOut', {
|
||||
// uuid: el.getAttribute('data-uuid'),
|
||||
// })
|
||||
}
|
||||
})
|
||||
e.removed.forEach((el) => {
|
||||
el.classList.remove('widget-selected')
|
||||
widgetStore.selectWidgetsInOut({
|
||||
uuid: el.getAttribute('data-uuid') || "",
|
||||
})
|
||||
// store.dispatch('selectWidgetsInOut', {
|
||||
// uuid: el.getAttribute('data-uuid'),
|
||||
// })
|
||||
})
|
||||
moveable.renderDirections = [] // ['nw', 'ne', 'sw', 'se'] // []
|
||||
moveable.rotatable = false
|
||||
moveable.target = [].slice.call(document.querySelectorAll('.widget-selected'))
|
||||
}).on("dragStart", e => {
|
||||
if (controlStore.dSpaceDown) {
|
||||
e.stop();
|
||||
}
|
||||
})
|
||||
}
|
@ -4,7 +4,10 @@
|
||||
<li
|
||||
v-for="(item, index) in menuListData.list"
|
||||
:key="index"
|
||||
:class="{ 'menu-item': true, 'disable-menu': dCopyElement.length === 0 && item.type === 'paste' }"
|
||||
:class="{
|
||||
'menu-item': true,
|
||||
'disable-menu': dCopyElement.length === 0 && item.type === 'paste',
|
||||
}"
|
||||
@click.stop="selectMenu(item.type)"
|
||||
>
|
||||
{{ item.text }}
|
||||
@ -15,16 +18,11 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import {
|
||||
widgetMenu as widget,
|
||||
pageMenu as page,
|
||||
menuList as menu,
|
||||
TMenuItemData, TWidgetItemData,
|
||||
} from './rcMenuData'
|
||||
import { widgetMenu as widget, pageMenu as page, menuList as menu, TMenuItemData, TWidgetItemData } from './rcMenuData'
|
||||
import { getTarget } from '@/common/methods/target'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useControlStore, useWidgetStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useControlStore, useWidgetStore } from '@/store'
|
||||
|
||||
const menuListData = ref<TMenuItemData>({ ...menu })
|
||||
const showMenuBg = ref<boolean>(false)
|
||||
@ -32,12 +30,12 @@ const widgetMenu = ref<TWidgetItemData[]>({...widget})
|
||||
const pageMenu = ref<TWidgetItemData[]>({ ...page })
|
||||
|
||||
const widgetStore = useWidgetStore()
|
||||
const controlStore = useControlStore()
|
||||
// const {dActiveElement, dWidgets, dCopyElement} = useSetupMapGetters(['dActiveElement', 'dWidgets', 'dCopyElement'])
|
||||
|
||||
const { dActiveElement, dWidgets, dCopyElement } = storeToRefs(widgetStore)
|
||||
const { dAltDown } = storeToRefs(useControlStore())
|
||||
|
||||
|
||||
const styleObj = computed(() => {
|
||||
return {
|
||||
left: menuListData.value.left + 'px',
|
||||
@ -64,12 +62,8 @@ async function mouseRightClick(e: MouseEvent) {
|
||||
|
||||
if (uuid !== '-1' && !dAltDown.value) {
|
||||
let widget = dWidgets.value.find((item: any) => item.uuid === uuid)
|
||||
if (
|
||||
widget?.parent !== '-1' &&
|
||||
widget?.parent !== dActiveElement.value?.uuid &&
|
||||
widget?.parent !== dActiveElement.value?.parent
|
||||
) {
|
||||
uuid = widget?.parent || ""
|
||||
if (widget?.parent !== '-1' && widget?.parent !== dActiveElement.value?.uuid && widget?.parent !== dActiveElement.value?.parent) {
|
||||
uuid = widget?.parent || ''
|
||||
}
|
||||
}
|
||||
widgetStore.selectWidget({
|
||||
@ -130,7 +124,7 @@ function selectMenu(type: TWidgetItemData['type']) {
|
||||
break
|
||||
case 'index-up':
|
||||
widgetStore.updateLayerIndex({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
value: 1,
|
||||
isGroup: dActiveElement.value?.isContainer,
|
||||
})
|
||||
@ -142,7 +136,7 @@ function selectMenu(type: TWidgetItemData['type']) {
|
||||
break
|
||||
case 'index-down':
|
||||
widgetStore.updateLayerIndex({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
value: -1,
|
||||
isGroup: dActiveElement.value?.isContainer,
|
||||
})
|
||||
@ -157,13 +151,21 @@ function selectMenu(type: TWidgetItemData['type']) {
|
||||
// store.dispatch('deleteWidget')
|
||||
break
|
||||
case 'ungroup':
|
||||
widgetStore.ungroup(dActiveElement.value?.uuid || "")
|
||||
widgetStore.ungroup(dActiveElement.value?.uuid || '')
|
||||
// store.dispatch('ungroup', dActiveElement.value.uuid)
|
||||
break
|
||||
case 'warpable':
|
||||
controlStore.setWarpable(true)
|
||||
break
|
||||
case 'scalable':
|
||||
controlStore.setScalable(true)
|
||||
break
|
||||
case 'resizable':
|
||||
controlStore.setResizable(true)
|
||||
break
|
||||
}
|
||||
closeMenu()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-07-30 17:38:50
|
||||
* @Description:
|
||||
* @LastEditors: ShawnPhang, Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditors: xi_zi
|
||||
* @Date: 2024-03-04 18:50:00
|
||||
*/
|
||||
|
||||
@ -19,7 +19,7 @@ export const menuList: TMenuItemData = {
|
||||
}
|
||||
|
||||
export type TWidgetItemData = {
|
||||
type: 'copy' | 'paste' | 'index-up' | 'index-down' | 'del' | 'ungroup'
|
||||
type: 'copy' | 'paste' | 'index-up' | 'index-down' | 'del' | 'ungroup' | 'warpable' | 'scalable' | 'resizable'
|
||||
text: string
|
||||
}
|
||||
|
||||
@ -44,6 +44,18 @@ export const widgetMenu: TWidgetItemData[] = [
|
||||
type: 'del',
|
||||
text: '删除',
|
||||
},
|
||||
{
|
||||
type: 'warpable',
|
||||
text: '斜切',
|
||||
},
|
||||
{
|
||||
type: 'scalable',
|
||||
text: '缩放',
|
||||
},
|
||||
{
|
||||
type: 'resizable',
|
||||
text: '调整大小',
|
||||
},
|
||||
]
|
||||
|
||||
export const pageMenu: TWidgetItemData[] = [
|
||||
|
@ -42,11 +42,17 @@
|
||||
<component
|
||||
:is="layer.type"
|
||||
v-for="layer in getlayers()"
|
||||
:id="layer.uuid" :key="layer.uuid"
|
||||
: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-title="layer.type"
|
||||
:params="layer"
|
||||
:parent="dPage"
|
||||
:data-type="layer.type"
|
||||
:data-uuid="layer.uuid"
|
||||
:style="{
|
||||
...widgetStyle(layer),
|
||||
}"
|
||||
>
|
||||
<template v-if="layer.isContainer">
|
||||
<!-- :class="{
|
||||
@ -58,10 +64,17 @@
|
||||
<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"
|
||||
: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"
|
||||
:style="{
|
||||
...groupWidgetChildrenStyle(layer, widget),
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</component>
|
||||
@ -75,7 +88,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { CSSProperties, onMounted } from 'vue'
|
||||
import { getTarget } from '@/common/methods/target'
|
||||
import setWidgetData from '@/common/methods/DesignFeatures/setWidgetData'
|
||||
import PointImg from '@/utils/plugins/pointImg'
|
||||
@ -85,6 +98,8 @@ import { move, moveInit } from '@/mixins/move'
|
||||
import { useCanvasStore, useControlStore, useGroupStore, useWidgetStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { TPageState } from '@/store/design/canvas/d'
|
||||
import { TdWidgetData } from '@/store/design/widget'
|
||||
import { getOffsetFromTransform, removeTranslate } from '@/utils/widgets/transferTranslate'
|
||||
// 页面设计组件
|
||||
type TProps = {
|
||||
pageDesignCanvasId: string
|
||||
@ -108,7 +123,6 @@ const { dZoom, dPaddingTop, dScreen } = storeToRefs(canvasStore)
|
||||
const { dDraging, showRotatable, dAltDown, dSpaceDown } = storeToRefs(controlStore)
|
||||
const { dWidgets, dActiveElement, dSelectWidgets, dHoverUuid } = storeToRefs(widgetStore)
|
||||
|
||||
|
||||
let _dropIn: string | null = ''
|
||||
let _srcCache: string | null = ''
|
||||
|
||||
@ -172,7 +186,7 @@ async function dropOver(e: MouseEvent) {
|
||||
if (!target) return
|
||||
const uuid = target.getAttribute('data-uuid')
|
||||
|
||||
widgetStore.setDropOver(uuid ?? "-1")
|
||||
widgetStore.setDropOver(uuid ?? '-1')
|
||||
// store.dispatch('setDropOver', uuid)
|
||||
|
||||
const imgEl = target?.firstElementChild?.firstElementChild as HTMLImageElement
|
||||
@ -201,7 +215,7 @@ async function drop(e: MouseEvent) {
|
||||
const dropIn = _dropIn
|
||||
_dropIn = ''
|
||||
|
||||
widgetStore.setDropOver("-1")
|
||||
widgetStore.setDropOver('-1')
|
||||
// store.dispatch('setDropOver', '-1')
|
||||
|
||||
// store.commit('setShowMoveable', false) // 清理上一次的选择
|
||||
@ -239,7 +253,7 @@ async function drop(e: MouseEvent) {
|
||||
})
|
||||
const half = {
|
||||
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) => {
|
||||
element.left += (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||
@ -252,7 +266,7 @@ async function drop(e: MouseEvent) {
|
||||
// 设置坐标
|
||||
const half = {
|
||||
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 }
|
||||
setting.left = (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||
@ -284,7 +298,6 @@ async function drop(e: MouseEvent) {
|
||||
|
||||
// store.commit('setShowMoveable', true) // 恢复选择
|
||||
controlStore.setShowMoveable(true) // 恢复选择
|
||||
|
||||
} else {
|
||||
widgetStore.addWidget(setting as Required<TPageState>)
|
||||
// store.dispatch('addWidget', setting) // 正常加入面板
|
||||
@ -352,14 +365,18 @@ async function handleSelection(e: MouseEvent) {
|
||||
|
||||
// 设置选中元素
|
||||
// this.$store.commit('setMoveable', false)
|
||||
if (showRotatable.value !== false) {
|
||||
/* if (showRotatable.value !== false) {
|
||||
widgetStore.selectWidget({
|
||||
uuid: uuid ?? " -1",
|
||||
uuid: uuid ?? ' -1',
|
||||
})
|
||||
// store.dispatch('selectWidget', {
|
||||
// uuid: uuid,
|
||||
// })
|
||||
}
|
||||
} */
|
||||
|
||||
widgetStore.selectWidget({
|
||||
uuid: uuid ?? ' -1',
|
||||
})
|
||||
|
||||
if (uuid !== '-1') {
|
||||
moveInit.methods.initmovement(e) // 参见 mixins
|
||||
@ -367,7 +384,7 @@ async function handleSelection(e: MouseEvent) {
|
||||
} else {
|
||||
// 取消选中元素
|
||||
widgetStore.selectWidget({
|
||||
uuid: "-1"
|
||||
uuid: '-1',
|
||||
})
|
||||
// store.dispatch('selectWidget', {
|
||||
// uuid: '-1',
|
||||
@ -393,11 +410,36 @@ function getChilds(uuid: string) {
|
||||
// return uuid === this.dActiveElement.uuid
|
||||
// }
|
||||
// },
|
||||
|
||||
const widgetStyle = (widgetData: TdWidgetData): CSSProperties => {
|
||||
const { transform, transformOrigin, width, height } = widgetData
|
||||
const style: CSSProperties = { position: 'absolute' }
|
||||
if (transform) style.transform = transform
|
||||
if (transformOrigin) style.transformOrigin = transformOrigin
|
||||
if (width !== undefined) style.width = `${width}px`
|
||||
if (height !== undefined) style.height = `${height}px`
|
||||
return style
|
||||
}
|
||||
|
||||
const groupWidgetChildrenStyle = (groupWidgetData: TdWidgetData, widgetData: TdWidgetData): CSSProperties => {
|
||||
const { transform, transformOrigin, width, height } = widgetData
|
||||
const { transform: gTransform } = groupWidgetData
|
||||
const { x: gX, y: gY } = getOffsetFromTransform(gTransform || '')
|
||||
const { x, y } = getOffsetFromTransform(transform || '')
|
||||
const style: CSSProperties = { position: 'absolute' }
|
||||
if (transform) style.transform = removeTranslate(transform)
|
||||
if (transformOrigin) style.transformOrigin = transformOrigin
|
||||
if (width !== undefined) style.width = `${width}px`
|
||||
if (height !== undefined) style.height = `${height}px`
|
||||
style.transform = `translate(${x - gX}px, ${y - gY}px) ${style.transform}`
|
||||
return style
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#main {
|
||||
overflow: auto; position: relative;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
}
|
||||
#page-design {
|
||||
scrollbar-width: none;
|
||||
|
@ -8,7 +8,7 @@ export const wGroupSetting = {
|
||||
height: 0,
|
||||
left: 0,
|
||||
top: 0,
|
||||
transform: '',
|
||||
transform: 'translate(0,0) matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)',
|
||||
opacity: 1,
|
||||
parent: '-1',
|
||||
isContainer: true,
|
||||
|
@ -2,22 +2,11 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-08-02 09:41:41
|
||||
* @Description:
|
||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||
* @LastEditTime: 2023-10-16 00:30:03
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 23:31:12
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
ref="widget"
|
||||
:class="['w-group', { 'layer-lock': props.params?.lock }]"
|
||||
: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,
|
||||
}"
|
||||
>
|
||||
<div ref="widget" :class="['w-group', { 'layer-lock': props.params?.lock }]">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,8 +17,8 @@ const NAME = 'w-group'
|
||||
import { nextTick, onBeforeUnmount, onMounted, onUpdated, ref } from 'vue'
|
||||
|
||||
import { setTransformAttribute } from '@/common/methods/handleTransform'
|
||||
import { useWidgetStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useWidgetStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||
|
||||
export type TParamsData = {
|
||||
@ -46,13 +35,12 @@ export type TParamsData = {
|
||||
|
||||
type TProps = {
|
||||
params?: Partial<TParamsData>
|
||||
parent?: Partial<Pick<TParamsData, "top" | "left">>
|
||||
parent?: Partial<Pick<TParamsData, 'top' | 'left'>>
|
||||
}
|
||||
const props = withDefaults(defineProps<TProps>(), {
|
||||
params: () => ({}),
|
||||
parent: () => ({})
|
||||
parent: () => ({}),
|
||||
})
|
||||
;
|
||||
const widgetStore = useWidgetStore()
|
||||
|
||||
const widget = ref<HTMLElement | null>(null)
|
||||
@ -105,7 +93,7 @@ onMounted(async () => {
|
||||
document.addEventListener('mousedown', touchstart, false)
|
||||
document.addEventListener('mouseup', touchend, false)
|
||||
if (props.params?.rotate && widget.value) {
|
||||
(widget.value.style.transform += `rotate(${props.params.rotate})`)
|
||||
widget.value.style.transform += `rotate(${props.params.rotate})`
|
||||
}
|
||||
})
|
||||
|
||||
@ -238,14 +226,13 @@ function keySetValue(uuid: string, key: keyof TParamsData, value: number) {
|
||||
setTimeout(() => {
|
||||
const widget = dWidgets.value.find((item) => item.uuid === uuid)
|
||||
if (!widget) return
|
||||
(widget[key] as Number) = value + Number(props.params[key] || '')
|
||||
;(widget[key] as Number) = value + Number(props.params[key] || '')
|
||||
}, 10)
|
||||
}
|
||||
|
||||
// defineExpose({
|
||||
// setting
|
||||
// })
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -2,8 +2,8 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-08-09 11:21:37
|
||||
* @Description: 组合设置
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-06-29 17:57:24
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 15:44:34
|
||||
-->
|
||||
<template>
|
||||
<div id="w-group-style">
|
||||
@ -18,12 +18,7 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="样式设置" name="2">
|
||||
<!-- <el-button plain type="primary" class="block-btn" @click="store.dispatch('ungroup', state.innerElement.uuid)">取消组合</el-button> -->
|
||||
<div
|
||||
class="ungroup style-item"
|
||||
@click="widgetStore.ungroup(String(state.innerElement.uuid))"
|
||||
>
|
||||
取消组合
|
||||
</div>
|
||||
<div class="ungroup style-item" @click="widgetStore.ungroup(String(state.innerElement.uuid))">取消组合</div>
|
||||
<number-slider v-model="state.innerElement.opacity" class="style-item" label="不透明" :step="0.05" :maxValue="1" @finish="(value) => finish('opacity', value)" />
|
||||
<br />
|
||||
<icon-item-select class="style-item" label="" :data="layerIconList" @finish="layerAction" />
|
||||
@ -52,13 +47,13 @@ import { TUpdateAlignData } from '@/store/design/widget/actions/align'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||
|
||||
type TState = {
|
||||
activeNames: string[],
|
||||
activeNames: string[]
|
||||
// defaultValue: 0,
|
||||
innerElement: typeof wGroupSetting,
|
||||
tag: boolean,
|
||||
ingoreKeys: string[],
|
||||
layerIconList: TIconItemSelectData[],
|
||||
alignIconList: TIconItemSelectData[],
|
||||
innerElement: typeof wGroupSetting
|
||||
tag: boolean
|
||||
ingoreKeys: string[]
|
||||
layerIconList: TIconItemSelectData[]
|
||||
alignIconList: TIconItemSelectData[]
|
||||
}
|
||||
|
||||
const state = reactive<TState>({
|
||||
@ -86,7 +81,7 @@ watch(
|
||||
(newValue, oldValue) => {
|
||||
change()
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -94,7 +89,7 @@ watch(
|
||||
(newValue, oldValue) => {
|
||||
changeValue()
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
function created() {
|
||||
@ -121,12 +116,12 @@ function changeValue() {
|
||||
for (let key in state.innerElement) {
|
||||
const itemKey = key as keyof typeof wGroupSetting
|
||||
if (state.ingoreKeys.indexOf(itemKey) !== -1) {
|
||||
(dActiveElement.value as Record<string, any>)[itemKey] = state.innerElement[itemKey]
|
||||
;(dActiveElement.value as Record<string, any>)[itemKey] = state.innerElement[itemKey]
|
||||
} else if (key !== 'setting' && key !== 'record' && state.innerElement[itemKey] !== (dActiveElement.value as Record<string, any>)[itemKey]) {
|
||||
widgetStore.updateWidgetData({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
key: (key as TUpdateWidgetPayload['key']),
|
||||
value: (state.innerElement[itemKey] as TUpdateWidgetPayload['value']),
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
key: key as TUpdateWidgetPayload['key'],
|
||||
value: state.innerElement[itemKey] as TUpdateWidgetPayload['value'],
|
||||
})
|
||||
// store.dispatch("updateWidgetData", {
|
||||
// uuid: dActiveElement.value?.uuid,
|
||||
@ -137,10 +132,9 @@ function changeValue() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function finish(key: string, value: string | number | number[]) {
|
||||
widgetStore.updateWidgetData({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
key: key as TUpdateWidgetPayload['key'],
|
||||
value: value as TUpdateWidgetPayload['value'],
|
||||
pushHistory: true,
|
||||
@ -155,8 +149,8 @@ function finish(key: string, value: string | number | number[]) {
|
||||
|
||||
function layerAction(item: TIconItemSelectData) {
|
||||
widgetStore.updateLayerIndex({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
value: (item.value as TupdateLayerIndexData['value']),
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
value: item.value as TupdateLayerIndexData['value'],
|
||||
isGroup: true,
|
||||
})
|
||||
// store.dispatch("updateLayerIndex", {
|
||||
@ -168,8 +162,8 @@ function layerAction(item: TIconItemSelectData) {
|
||||
|
||||
function alignAction(item: TIconItemSelectData) {
|
||||
widgetStore.updateAlign({
|
||||
align: (item.value as TUpdateAlignData['align']),
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
align: item.value as TUpdateAlignData['align'],
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
})
|
||||
// store.dispatch("updateAlign", {
|
||||
// align: item.value,
|
||||
|
@ -3,32 +3,32 @@
|
||||
:id="params.uuid"
|
||||
ref="widgetRef"
|
||||
:class="['w-image', { 'layer-lock': params.lock }]"
|
||||
: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
|
||||
v-if="cropEdit"
|
||||
:id="params.uuid + '_ebox'"
|
||||
:ref="params.uuid + '_ebox'"
|
||||
:style="state.editBoxStyle"
|
||||
class="svg__edit__wrap"
|
||||
>
|
||||
<div>
|
||||
<div v-if="cropEdit" :id="params.uuid + '_ebox'" :ref="params.uuid + '_ebox'" :style="state.editBoxStyle" class="svg__edit__wrap">
|
||||
<img class="edit__model" :src="params.imgUrl" />
|
||||
</div>
|
||||
<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>
|
||||
<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 v-if="isMask" class="drop__mask">
|
||||
<div putIn="true" :style="{ fontSize: params.width / 12 + 'px' }" class="drop__btn">拖入</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@ -37,7 +37,7 @@
|
||||
import { CSSProperties, StyleValue, computed, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, watch } from 'vue'
|
||||
|
||||
import { getMatrix } from '@/common/methods/handleTransform'
|
||||
import setting from "./wImageSetting"
|
||||
import setting from './wImageSetting'
|
||||
import PointImg from '@/utils/plugins/pointImg'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||
import { useRoute } from 'vue-router'
|
||||
@ -53,8 +53,8 @@ type TProps = {
|
||||
}
|
||||
|
||||
type TState = {
|
||||
position: 'absolute' | 'relative', // 'absolute'relative
|
||||
editBoxStyle: CSSProperties,
|
||||
position: 'absolute' | 'relative' // 'absolute'relative
|
||||
editBoxStyle: CSSProperties
|
||||
cropWidgetXY: {
|
||||
x: number
|
||||
y: number
|
||||
@ -79,11 +79,10 @@ const state = reactive<TState>({
|
||||
holdPosition: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
}
|
||||
},
|
||||
})
|
||||
const route = useRoute()
|
||||
|
||||
|
||||
const controlStore = useControlStore()
|
||||
const widgetStore = useWidgetStore()
|
||||
const forceStore = useForceStore()
|
||||
@ -98,9 +97,7 @@ let flipTemp: string | null = null
|
||||
// dActiveElement, dWidgets, dMouseXY, dDropOverUuid, dCropUuid
|
||||
// } = useSetupMapGetters(['dActiveElement', 'dWidgets', 'dMouseXY', 'dDropOverUuid', 'dCropUuid'])
|
||||
const { dZoom } = storeToRefs(useCanvasStore())
|
||||
const {
|
||||
dActiveElement, dWidgets, dMouseXY, dDropOverUuid
|
||||
} = storeToRefs(widgetStore)
|
||||
const { dActiveElement, dWidgets, dMouseXY, dDropOverUuid } = storeToRefs(widgetStore)
|
||||
const { dCropUuid } = storeToRefs(controlStore)
|
||||
|
||||
// ...mapGetters(['dActiveElement', 'dWidgets', 'dZoom', 'dMouseXY', 'dDropOverUuid', 'dCropUuid']),
|
||||
@ -129,7 +126,7 @@ watch(
|
||||
}
|
||||
fixRotate()
|
||||
lockOthers(val)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -137,7 +134,7 @@ watch(
|
||||
async () => {
|
||||
await nextTick()
|
||||
updateRecord()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
onUpdated(() => {
|
||||
@ -241,7 +238,7 @@ function updateRecord() {
|
||||
}
|
||||
|
||||
function setTransform(attrName: string, value: string | number) {
|
||||
const iof = props.params.transform.indexOf(attrName)
|
||||
/* const iof = props.params.transform.indexOf(attrName)
|
||||
let setValue = ''
|
||||
if (iof != -1) {
|
||||
const index = iof + attrName.length
|
||||
@ -267,11 +264,11 @@ function setTransform(attrName: string, value: string | number) {
|
||||
// })
|
||||
if (props.params.transform && targetRef.value) {
|
||||
targetRef.value.style.transform = props.params.transform
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
function setEditBox(attrName: string, value: string | number) {
|
||||
const iof = state.editBoxStyle.transform?.indexOf(attrName)
|
||||
/* const iof = state.editBoxStyle.transform?.indexOf(attrName)
|
||||
let setValue = ''
|
||||
if (iof != -1 && iof != undefined) {
|
||||
const index = iof + attrName.length
|
||||
@ -283,7 +280,7 @@ function setEditBox(attrName: string, value: string | number) {
|
||||
} else {
|
||||
setValue = state.editBoxStyle.transform + ` ${attrName}(${value})`
|
||||
}
|
||||
state.editBoxStyle.transform = setValue
|
||||
state.editBoxStyle.transform = setValue */
|
||||
}
|
||||
|
||||
function updateZoom() {
|
||||
@ -320,7 +317,7 @@ function lockOthers(isCrop) {
|
||||
for (const widget of dWidgets.value) {
|
||||
if (widget.uuid === props.params.uuid) {
|
||||
widget.lock = false
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-08-09 11:41:53
|
||||
* @Description:
|
||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||
* @LastEditTime: 2024-03-22 16:14:48
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 13:44:42
|
||||
-->
|
||||
<template>
|
||||
<div id="w-image-style">
|
||||
@ -31,22 +31,20 @@
|
||||
<container-wrap @change="changeContainer" />
|
||||
<div class="slide-wrap">
|
||||
<number-slider v-model="state.innerElement.opacity" style="font-size: 14px" label="不透明" :step="0.05" :maxValue="1" @finish="(value) => finish('opacity', value)" />
|
||||
<number-slider v-model="state.innerElement.radius" style="font-size: 14px" label="圆角" :maxValue="Math.min(Number(state.innerElement.record?.width), Number(state.innerElement.record?.height))" @finish="(value) => finish('radius', value)" />
|
||||
<number-slider
|
||||
v-model="state.innerElement.radius"
|
||||
style="font-size: 14px"
|
||||
label="圆角"
|
||||
:maxValue="Math.min(Number(state.innerElement.record?.width), Number(state.innerElement.record?.height))"
|
||||
@finish="(value) => finish('radius', value)"
|
||||
/>
|
||||
<!-- <number-slider v-model="innerElement.letterSpacing" style="font-size: 14px" label="字距" labelWidth="40px" :step="0.05" :minValue="-50" :maxValue="innerElement.fontSize" @finish="(value) => finish('letterSpacing', value)" />
|
||||
<number-slider v-model="innerElement.lineHeight" style="font-size: 14px" label="行距" labelWidth="40px" :step="0.05" :minValue="0" :maxValue="2.5" @finish="(value) => finish('lineHeight', value)" /> -->
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-if="state.innerElement.isNinePatch" title="点九图设置" name="3">
|
||||
<number-slider
|
||||
v-model="state.innerElement.sliceData.ratio"
|
||||
:step="0.01" label="比率" :maxValue="10"
|
||||
@finish="(value) => finishSliceData('ratio', value)"
|
||||
/>
|
||||
<number-slider
|
||||
v-model="state.innerElement.sliceData.left"
|
||||
:step="0.5" label="大小"
|
||||
@finish="(value) => finishSliceData('left', value)"
|
||||
/>
|
||||
<number-slider v-model="state.innerElement.sliceData.ratio" :step="0.01" label="比率" :maxValue="10" @finish="(value) => finishSliceData('ratio', value)" />
|
||||
<number-slider v-model="state.innerElement.sliceData.left" :step="0.5" label="大小" @finish="(value) => finishSliceData('left', value)" />
|
||||
</el-collapse-item>
|
||||
<br />
|
||||
<icon-item-select class="style-item" label="" :data="layerIconList" @finish="layerAction" />
|
||||
@ -55,11 +53,7 @@
|
||||
</el-collapse>
|
||||
<!-- <CropImage ref="crop" @done="cropDone" /> -->
|
||||
<inner-tool-bar v-show="state.innerElement.cropEdit" :style="toolBarStyle">
|
||||
<number-slider
|
||||
v-model="state.innerElement.zoom"
|
||||
class="inner-bar" label="缩放" labelWidth="40px"
|
||||
:step="0.01" :minValue="1" :maxValue="3"
|
||||
/>
|
||||
<number-slider v-model="state.innerElement.zoom" class="inner-bar" label="缩放" labelWidth="40px" :step="0.01" :minValue="1" :maxValue="3" />
|
||||
<i style="padding: 0 8px; cursor: pointer" class="icon sd-queren" @click="imgCrop(false)" />
|
||||
</inner-tool-bar>
|
||||
<picBox ref="picBoxRef" @select="selectDone" />
|
||||
@ -134,7 +128,6 @@ const state = reactive<TState>({
|
||||
const picBoxRef = ref<typeof picBox | null>(null)
|
||||
const imageCutoutRef = ref<typeof imageCutout | null>(null)
|
||||
|
||||
|
||||
const widgetStore = useWidgetStore()
|
||||
const forceStore = useForceStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
@ -145,10 +138,9 @@ const controlStore = useControlStore()
|
||||
const { dMoving } = storeToRefs(controlStore)
|
||||
const { dActiveElement, dWidgets } = storeToRefs(widgetStore)
|
||||
|
||||
|
||||
let lastUuid: string | undefined = undefined
|
||||
let tag: boolean
|
||||
let toolBarStyle: { left: string, top: string } | null = null
|
||||
let toolBarStyle: { left: string; top: string } | null = null
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
imgCrop(false)
|
||||
@ -166,7 +158,7 @@ watch(
|
||||
}
|
||||
lastUuid = newValue.uuid
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -175,7 +167,7 @@ watch(
|
||||
changeValue()
|
||||
cropHandle()
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
function created() {
|
||||
@ -201,15 +193,12 @@ function changeValue() {
|
||||
}
|
||||
for (let key in state.innerElement) {
|
||||
if (state.ingoreKeys.indexOf(key) !== -1) {
|
||||
(dActiveElement.value as Record<string, any>)[key] = state.innerElement[(key as keyof TImageSetting)]
|
||||
} else if (
|
||||
key !== 'cropEdit' && key !== 'record' &&
|
||||
state.innerElement[(key as keyof TImageSetting)] !== (dActiveElement.value as Record<string, any>)[key]
|
||||
) {
|
||||
;(dActiveElement.value as Record<string, any>)[key] = state.innerElement[key as keyof TImageSetting]
|
||||
} else if (key !== 'cropEdit' && key !== 'record' && state.innerElement[key as keyof TImageSetting] !== (dActiveElement.value as Record<string, any>)[key]) {
|
||||
widgetStore.updateWidgetData({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
key: (key as TUpdateWidgetPayload['key']),
|
||||
value: (state.innerElement[(key as keyof TImageSetting)] as TUpdateWidgetPayload['value']),
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
key: key as TUpdateWidgetPayload['key'],
|
||||
value: state.innerElement[key as keyof TImageSetting] as TUpdateWidgetPayload['value'],
|
||||
})
|
||||
// store.dispatch('updateWidgetData', {
|
||||
// uuid: dActiveElement.value.uuid,
|
||||
@ -240,10 +229,10 @@ function finishSliceData(key: string, value: number | number[]) {
|
||||
}
|
||||
}
|
||||
|
||||
function finish(key: string = "", value: string | number | (string | number)[] | null = "") {
|
||||
function finish(key: string = '', value: string | number | (string | number)[] | null = '') {
|
||||
widgetStore.updateWidgetData({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
key: (key as TUpdateWidgetPayload['key']),
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
key: key as TUpdateWidgetPayload['key'],
|
||||
value: value as TUpdateWidgetPayload['value'],
|
||||
pushHistory: true,
|
||||
})
|
||||
@ -258,22 +247,22 @@ function finish(key: string = "", value: string | number | (string | number)[] |
|
||||
function layerAction(item: TIconItemSelectData) {
|
||||
if (item.key === 'zIndex') {
|
||||
widgetStore.updateLayerIndex({
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
value: (item.value as TupdateLayerIndexData['value']),
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
value: item.value as TupdateLayerIndexData['value'],
|
||||
})
|
||||
// store.dispatch("updateLayerIndex", {
|
||||
// uuid: dActiveElement.value.uuid,
|
||||
// value: item.value,
|
||||
// })
|
||||
} else {
|
||||
finish(item.key || "", item.value === dActiveElement.value?.flip ? null : item.value)
|
||||
finish(item.key || '', item.value === dActiveElement.value?.flip ? null : item.value)
|
||||
}
|
||||
}
|
||||
|
||||
async function alignAction(item: TIconItemSelectData) {
|
||||
widgetStore.updateAlign({
|
||||
align: (item.value as TUpdateAlignData['align']),
|
||||
uuid: dActiveElement.value?.uuid || "",
|
||||
align: item.value as TUpdateAlignData['align'],
|
||||
uuid: dActiveElement.value?.uuid || '',
|
||||
})
|
||||
// store.dispatch("updateAlign", {
|
||||
// align: item.value,
|
||||
@ -295,7 +284,6 @@ function openCropper() {
|
||||
// this.innerElement.height = height.toFixed(0)
|
||||
// }
|
||||
|
||||
|
||||
async function changeContainer(setting: any) {
|
||||
state.innerElement.mask = setting.svgUrl
|
||||
// const index = this.dWidgets.findIndex((x) => x.uuid == this.innerElement.uuid)
|
||||
@ -318,26 +306,25 @@ async function changeContainer(setting: any) {
|
||||
// this.$store.commit('setShowMoveable', true)
|
||||
// }
|
||||
|
||||
|
||||
async function selectDone(img: TGetImageListResult) {
|
||||
state.innerElement.imgUrl = img.url
|
||||
const loadImg = await getImage(img.url)
|
||||
state.innerElement.width = loadImg.width * canvasStore.dZoom / 100
|
||||
state.innerElement.height = loadImg.height * canvasStore.dZoom / 100
|
||||
state.innerElement.width = (loadImg.width * canvasStore.dZoom) / 100
|
||||
state.innerElement.height = (loadImg.height * canvasStore.dZoom) / 100
|
||||
// this.imgCrop(true)
|
||||
}
|
||||
|
||||
function imgCrop(val: boolean) {
|
||||
async function imgCrop(val: boolean) {
|
||||
// TODO: 画布内图像裁剪
|
||||
const el = document.getElementById(state.innerElement.uuid || "")
|
||||
const el = document.getElementById(state.innerElement.uuid || '')
|
||||
if (!el) return
|
||||
const { left, top } = el.getBoundingClientRect()
|
||||
toolBarStyle = { left: left + 'px', top: top + 'px' }
|
||||
state.innerElement.cropEdit = val
|
||||
await nextTick()
|
||||
controlStore.setShowRotatable(!val)
|
||||
}
|
||||
|
||||
|
||||
function cropHandle() {
|
||||
controlStore.setCropUuid(state.innerElement.cropEdit ? state.innerElement.uuid : '-1')
|
||||
// store.commit('setCropUuid', state.innerElement.cropEdit ? state.innerElement.uuid : -1)
|
||||
@ -352,7 +339,7 @@ function openPicBox() {
|
||||
|
||||
// 打开抠图
|
||||
function openImageCutout() {
|
||||
fetch(state.innerElement.imgUrl || "")
|
||||
fetch(state.innerElement.imgUrl || '')
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const file = new File([blob], `image_${Math.random()}.jpg`, { type: 'image/jpeg' })
|
||||
@ -371,7 +358,6 @@ async function cutImageDone(url: string) {
|
||||
state.innerElement.imgUrl = url
|
||||
}, 300)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -2,32 +2,12 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2022-03-13 15:59:52
|
||||
* @Description: 二维码
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-06-29 15:54:10
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 23:32:14
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
:id="`${params.uuid}`"
|
||||
ref="widgetRef"
|
||||
:class="['w-qrcode', { 'layer-lock': params.lock }]"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: params.left - parent.left + 'px',
|
||||
top: params.top - parent.top + 'px',
|
||||
width: params.width + 'px',
|
||||
height: params.height + 'px',
|
||||
opacity: params.opacity,
|
||||
}"
|
||||
>
|
||||
<QRCode
|
||||
ref="qrcode"
|
||||
v-bind="state.qrCodeOptions"
|
||||
:width="width"
|
||||
:height="width"
|
||||
class="target"
|
||||
:image="params.url"
|
||||
:value="params.value"
|
||||
/>
|
||||
<div :id="`${params.uuid}`" ref="widgetRef" :class="['w-qrcode', { 'layer-lock': params.lock }]">
|
||||
<QRCode ref="qrcode" v-bind="state.qrCodeOptions" :width="width" :height="width" class="target" :image="params.url" :value="params.value" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -35,14 +15,13 @@
|
||||
// 图片组件
|
||||
// const NAME = 'w-qrcode'
|
||||
|
||||
|
||||
import QRCode from '@/components/business/qrcode'
|
||||
import { TWQrcodeSetting } from './wQrcodeSetting';
|
||||
import { computed, nextTick, onMounted, onUpdated, reactive, ref, watch } from 'vue';
|
||||
import { TWQrcodeSetting } from './wQrcodeSetting'
|
||||
import { computed, nextTick, onMounted, onUpdated, reactive, ref, watch } from 'vue'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||
import { Options } from 'qr-code-styling';
|
||||
import { useForceStore, useWidgetStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { Options } from 'qr-code-styling'
|
||||
import { useForceStore, useWidgetStore } from '@/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
type TProps = {
|
||||
params: TWQrcodeSetting & {
|
||||
@ -59,12 +38,11 @@ type TState = {
|
||||
qrCodeOptions: Options
|
||||
}
|
||||
|
||||
|
||||
const forceStore = useForceStore()
|
||||
const widgetStore = useWidgetStore()
|
||||
const props = defineProps<TProps>()
|
||||
const state = reactive<TState>({
|
||||
qrCodeOptions: {}
|
||||
qrCodeOptions: {},
|
||||
})
|
||||
// const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
||||
const { dActiveElement } = storeToRefs(widgetStore)
|
||||
@ -76,7 +54,7 @@ watch(
|
||||
() => {
|
||||
changeValues()
|
||||
},
|
||||
{ immediate: true, deep: true, }
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
onUpdated(() => {
|
||||
|
@ -2,30 +2,18 @@
|
||||
TODO: 重构
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
:id="params.uuid"
|
||||
ref="widgetRef"
|
||||
class="w-svg"
|
||||
: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>
|
||||
<div :id="params.uuid" ref="widgetRef" class="w-svg"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// svg
|
||||
// const NAME = 'w-svg'
|
||||
|
||||
import { useCanvasStore, useForceStore, useWidgetStore } from '@/store';
|
||||
import { useCanvasStore, useForceStore, useWidgetStore } from '@/store'
|
||||
import { TWSvgSetting } from './wSvgSetting'
|
||||
import { CSSProperties, computed, nextTick, onBeforeMount, onMounted, onUpdated, reactive, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { TUpdateWidgetPayload } from '@/store/design/widget/actions/widget';
|
||||
import { CSSProperties, computed, nextTick, onBeforeMount, onMounted, onUpdated, reactive, ref, watch } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { TUpdateWidgetPayload } from '@/store/design/widget/actions/widget'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||
|
||||
type TProps = {
|
||||
@ -37,12 +25,12 @@ type TProps = {
|
||||
}
|
||||
|
||||
type TState = {
|
||||
position: CSSProperties['position'], // 'absolute'relative
|
||||
editBoxStyle: CSSProperties,
|
||||
editBoxs: Record<string, any>,
|
||||
editingKey: string,
|
||||
cropWidgetXY: Record<string, any>, // 裁剪框移动作用
|
||||
attrRecord: Record<string, any>, // 记录可更改的属性
|
||||
position: CSSProperties['position'] // 'absolute'relative
|
||||
editBoxStyle: CSSProperties
|
||||
editBoxs: Record<string, any>
|
||||
editingKey: string
|
||||
cropWidgetXY: Record<string, any> // 裁剪框移动作用
|
||||
attrRecord: Record<string, any> // 记录可更改的属性
|
||||
svgImg: Record<string, any> | null
|
||||
}
|
||||
|
||||
@ -56,7 +44,7 @@ const state = reactive<TState>({
|
||||
editingKey: '',
|
||||
cropWidgetXY: {}, // 裁剪框移动作用
|
||||
attrRecord: {}, // 记录可更改的属性
|
||||
svgImg: null
|
||||
svgImg: null,
|
||||
})
|
||||
|
||||
const widgetStore = useWidgetStore()
|
||||
@ -88,7 +76,7 @@ watch(
|
||||
() => {
|
||||
attrsChange()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -96,7 +84,7 @@ watch(
|
||||
async () => {
|
||||
await nextTick()
|
||||
updateRecord()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -106,7 +94,7 @@ watch(
|
||||
state.svgImg.attr({
|
||||
'xlink:href': props.params.imgUrl,
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
@ -118,7 +106,7 @@ watch(
|
||||
} else {
|
||||
el?.removeEventListener('mousedown', touchstart, false)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
onUpdated(() => {
|
||||
|
@ -1,17 +1,15 @@
|
||||
<template>
|
||||
<div
|
||||
:id="`${params.uuid}`"
|
||||
ref="widget"
|
||||
v-loading="state.loading"
|
||||
v-bind="$attrs"
|
||||
class="element-inner"
|
||||
:class="['w-text', { editing: state.editable, 'layer-lock': params.lock }, params.uuid]"
|
||||
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',
|
||||
// minWidth: params.fontSize + 'px',
|
||||
// minHeight: params.fontSize * params.lineHeight + 'px',
|
||||
height: params.height + 'px',
|
||||
width: params.width + 'px',
|
||||
lineHeight: params.fontSize * params.lineHeight + 'px',
|
||||
letterSpacing: (params.fontSize * params.letterSpacing) / 100 + 'px',
|
||||
fontSize: params.fontSize + 'px',
|
||||
@ -46,12 +44,15 @@
|
||||
></div>
|
||||
</template>
|
||||
<div
|
||||
ref="editWrap" :style="{ fontFamily: `'${params.fontClass.value}'` }"
|
||||
class="edit-text" spellcheck="false"
|
||||
ref="editWrap"
|
||||
:style="{ fontFamily: `'${params.fontClass.value}'` }"
|
||||
class="edit-text"
|
||||
spellcheck="false"
|
||||
:contenteditable="state.editable ? 'plaintext-only' : false"
|
||||
@input="writingText($event)"
|
||||
@blur="writeDone($event)"
|
||||
v-html="params.text"></div>
|
||||
v-html="params.text"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -65,12 +66,21 @@ import { fontWithDraw } from '@/utils/widgets/loadFontRule'
|
||||
import getGradientOrImg from './getGradientOrImg'
|
||||
import { wTextSetting } from './wTextSetting'
|
||||
import { useForceStore, useHistoryStore, useWidgetStore } from '@/store'
|
||||
import { addFont } from '@/utils/addFont'
|
||||
|
||||
export type TwTextParams = {
|
||||
rotate?: number
|
||||
lock?: boolean
|
||||
width?: number
|
||||
height?: number
|
||||
imageTransform?: {
|
||||
a: number
|
||||
b: number
|
||||
c: number
|
||||
d: number
|
||||
tx: number
|
||||
ty: number
|
||||
}
|
||||
} & typeof wTextSetting
|
||||
|
||||
type TProps = {
|
||||
@ -92,7 +102,9 @@ const state = reactive({
|
||||
loadFontDone: '',
|
||||
})
|
||||
const widget = ref<HTMLElement | null>(null)
|
||||
const widgetWrap = ref<HTMLElement | null>(null)
|
||||
const editWrap = ref<HTMLElement | null>(null)
|
||||
const editorElRef = ref<HTMLElement | null>(null)
|
||||
|
||||
const dActiveElement = computed(() => widgetStore.dActiveElement)
|
||||
const isDraw = computed(() => route.name === 'Draw' && fontWithDraw)
|
||||
@ -103,11 +115,6 @@ onUpdated(() => {
|
||||
|
||||
onMounted(() => {
|
||||
updateRecord()
|
||||
|
||||
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)`)
|
||||
// store.commit('updateRect')
|
||||
})
|
||||
|
||||
watch(
|
||||
@ -128,9 +135,7 @@ watch(
|
||||
return
|
||||
}
|
||||
state.loading = !isDraw.value
|
||||
const loadFont = new window.FontFace(font.value, `url(${font.url})`)
|
||||
await loadFont.load()
|
||||
document.fonts.add(loadFont)
|
||||
await addFont(font.value, font.url)
|
||||
state.loadFontDone = font.value
|
||||
state.loading = false
|
||||
} else {
|
||||
@ -212,7 +217,7 @@ function writingText(e?: Event) {
|
||||
function writeDone(e: Event) {
|
||||
state.editable = false
|
||||
setTimeout(() => {
|
||||
historyStore.pushHistory("文字修改")
|
||||
historyStore.pushHistory('文字修改')
|
||||
// store.dispatch('pushHistory', '文字修改')
|
||||
}, 100)
|
||||
updateText(e)
|
||||
@ -231,9 +236,9 @@ function dblclickText(_: MouseEvent) {
|
||||
range.select()
|
||||
} else {
|
||||
const range = document.createRange()
|
||||
range.selectNodeContents(el);
|
||||
window.getSelection()?.removeAllRanges();
|
||||
window.getSelection()?.addRange(range);
|
||||
range.selectNodeContents(el)
|
||||
window.getSelection()?.removeAllRanges()
|
||||
window.getSelection()?.addRange(range)
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
@ -251,6 +256,23 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.element-inner {
|
||||
position: absolute;
|
||||
// z-index: 1;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
writing-mode: horizontal-tb;
|
||||
// transform-origin: 0 0;
|
||||
.element-inner-position {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.w-text {
|
||||
// cursor: pointer;
|
||||
user-select: none;
|
||||
|
@ -8,6 +8,7 @@ export type TwTextData = {
|
||||
left: number
|
||||
top: number
|
||||
transform: string
|
||||
transformOrigin: string
|
||||
lineHeight: number
|
||||
letterSpacing: number
|
||||
fontSize: number
|
||||
|
@ -48,8 +48,8 @@ export type TPageState = {
|
||||
name: string
|
||||
type: string
|
||||
uuid: string
|
||||
left: number
|
||||
top: number
|
||||
left?: number
|
||||
top?: number
|
||||
/** 画布宽度 */
|
||||
width: number
|
||||
/** 画布高度 */
|
||||
|
@ -3,8 +3,8 @@
|
||||
* @Author: Jeremy Yu
|
||||
* @Date: 2024-03-18 21:00:00
|
||||
* @Description:
|
||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditTime: 2024-03-18 21:00:00
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 10:26:38
|
||||
*/
|
||||
|
||||
import { useHistoryStore } from "@/store";
|
||||
@ -27,8 +27,11 @@ type TControlState = {
|
||||
dAltDown: boolean
|
||||
// 是否按下空格键
|
||||
dSpaceDown: boolean
|
||||
/** 正在编辑or裁剪的组件id */
|
||||
/** 正在编辑or裁剪的组件id **/
|
||||
dCropUuid: string
|
||||
warpable: boolean, // 是否开启斜切
|
||||
scalable: boolean, // 是否开启缩放
|
||||
resizable: boolean, // 是否开启拖拽
|
||||
}
|
||||
|
||||
type TControlAction = {
|
||||
@ -45,6 +48,24 @@ type TControlAction = {
|
||||
stopDMove: () => void
|
||||
/** 设置正在裁剪or编辑的组件 */
|
||||
setCropUuid: (uuid: string) => void
|
||||
/**
|
||||
* 设置斜切
|
||||
* @param able
|
||||
* @returns
|
||||
*/
|
||||
setWarpable: (able: boolean) => void
|
||||
/**
|
||||
* 设置尺寸控制
|
||||
* @param able
|
||||
* @returns
|
||||
*/
|
||||
setResizable: (able: boolean) => void
|
||||
/**
|
||||
* 设置缩放
|
||||
* @param able
|
||||
* @returns
|
||||
*/
|
||||
setScalable: (able: boolean) => void
|
||||
setSpaceDown: (uuid: boolean) => void // 设置是否按下空格键
|
||||
}
|
||||
|
||||
@ -59,6 +80,9 @@ const ControlStore = defineStore<"controlStore", TControlState, {}, TControlAct
|
||||
showRotatable: true, // 是否显示moveable的旋转按钮
|
||||
dAltDown: false, // 记录是否按下alt键 / 或ctrl
|
||||
dCropUuid: '-1', // 正在编辑or裁剪的组件id
|
||||
warpable: false, // 是否开启斜切
|
||||
scalable: false, // 是否开启缩放
|
||||
resizable: true, // 是否开启拖拽
|
||||
dSpaceDown: false, // 记录是否按下空格键
|
||||
}),
|
||||
getters: {},
|
||||
@ -112,6 +136,31 @@ const ControlStore = defineStore<"controlStore", TControlState, {}, TControlAct
|
||||
// 设置正在裁剪or编辑的组件
|
||||
this.dCropUuid = uuid
|
||||
},
|
||||
setWarpable(able: boolean) {
|
||||
this.warpable = able
|
||||
if (able) {
|
||||
this.scalable = false
|
||||
this.resizable = false
|
||||
} else {
|
||||
this.resizable = true
|
||||
}
|
||||
},
|
||||
setResizable(able: boolean) {
|
||||
this.resizable = able
|
||||
if (able) {
|
||||
this.warpable = false
|
||||
this.scalable = false
|
||||
}
|
||||
},
|
||||
setScalable(able: boolean) {
|
||||
this.scalable = able
|
||||
if (able) {
|
||||
this.warpable = false
|
||||
this.resizable = false
|
||||
} else {
|
||||
this.resizable = true
|
||||
}
|
||||
},
|
||||
setSpaceDown(val: boolean) {
|
||||
this.dSpaceDown = val
|
||||
}
|
||||
|
@ -2,21 +2,21 @@
|
||||
* @Author: Jeremy Yu
|
||||
* @Date: 2024-03-28 14:00:00
|
||||
* @Description:
|
||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditTime: 2024-03-28 14:00:00
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 23:34:21
|
||||
*/
|
||||
|
||||
import { customAlphabet } from 'nanoid/non-secure'
|
||||
import { TGroupStore } from '..'
|
||||
import { useHistoryStore, useCanvasStore, useWidgetStore } from '@/store'
|
||||
import { TdWidgetData } from '../../widget'
|
||||
import { getOffsetFromTransform, transferTransformWidget } from '@/utils/widgets/transferTranslate'
|
||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||
|
||||
export function realCombined(store: TGroupStore) {
|
||||
const widgetStore = useWidgetStore()
|
||||
const pageStore = useCanvasStore()
|
||||
const historyStore = useHistoryStore()
|
||||
|
||||
const selectWidgets = widgetStore.dSelectWidgets
|
||||
if (selectWidgets.length > 1) {
|
||||
const widgets = widgetStore.dWidgets
|
||||
@ -60,10 +60,12 @@ export function realCombined(store: TGroupStore) {
|
||||
// index: index,
|
||||
// widget: widget,
|
||||
// })
|
||||
left = Math.min(left, widget.left)
|
||||
top = Math.min(top, widget.top)
|
||||
right = Math.max(right, Number(widget.width || widget.record.width) + Number(widget.left))
|
||||
bottom = Math.max(bottom, Number(widget.height || widget.record.height) + Number(widget.top))
|
||||
const { x, y } = getOffsetFromTransform(widget.transform ?? '')
|
||||
left = Math.min(left, x)
|
||||
top = Math.min(top, y)
|
||||
const rect = document.getElementById(`${widget.uuid}`)?.getBoundingClientRect()
|
||||
right = Math.max(right, Number((rect?.width ?? 0) / (pageStore.dZoom / 100) || widget.record.width) + Number(x))
|
||||
bottom = Math.max(bottom, Number((rect?.height ?? 0) / (pageStore.dZoom / 100) || widget.record.height) + Number(y))
|
||||
}
|
||||
// sortWidgets.sort((a, b) => a.index > b.index)
|
||||
// for (let i = 0; i < sortWidgets.length; ++i) {
|
||||
@ -71,9 +73,9 @@ export function realCombined(store: TGroupStore) {
|
||||
// widgets.splice(index, 1)
|
||||
// widgets.push(sortWidgets[i].widget)
|
||||
// }
|
||||
|
||||
group.left = Number(left)
|
||||
group.top = Number(top)
|
||||
// group.left = Number(left)
|
||||
// group.top = Number(top)
|
||||
group.transform = `translate(${left}px,${top}px)`
|
||||
group.width = Number(right - left)
|
||||
group.height = Number(bottom - top)
|
||||
widgetStore.dActiveElement = group
|
||||
@ -92,6 +94,7 @@ export function getCombined(store: TGroupStore): Promise<TdWidgetData> {
|
||||
const selectWidgets = widgetStore.dSelectWidgets
|
||||
return new Promise((resolve) => {
|
||||
if (selectWidgets.length > 1) {
|
||||
|
||||
const widgets = widgetStore.dWidgets
|
||||
const group = JSON.parse(store.dGroupJson)
|
||||
group.uuid = nanoid()
|
||||
@ -109,16 +112,17 @@ export function getCombined(store: TGroupStore): Promise<TdWidgetData> {
|
||||
const uuid = sortWidgets[i].uuid
|
||||
const index = widgets.findIndex((item: Type.Object) => item.uuid === uuid)
|
||||
const widget = { ...widgets[index] } // clone
|
||||
left = Math.min(left, widget.left)
|
||||
top = Math.min(top, widget.top)
|
||||
right = Math.max(right, Number(widget.width) + Number(widget.left))
|
||||
bottom = Math.max(bottom, Number(widget.height) + Number(widget.top))
|
||||
const { x, y } = getOffsetFromTransform(widget.transform ?? '')
|
||||
left = Math.min(left, x)
|
||||
top = Math.min(top, y)
|
||||
const rect = document.getElementById(`${widget.uuid}`)?.getBoundingClientRect()
|
||||
right = Math.max(right, Number((rect?.width ?? 0) / (pageStore.dZoom / 100) || widget.record.width) + Number(x))
|
||||
bottom = Math.max(bottom, Number((rect?.height ?? 0) / (pageStore.dZoom / 100) || widget.record.height) + Number(y))
|
||||
}
|
||||
|
||||
group.left = left
|
||||
group.top = top
|
||||
group.width = right - left
|
||||
group.height = bottom - top
|
||||
group.transform = `translate(${left}px,${top}px)`
|
||||
group.width = Number(right - left)
|
||||
group.height = Number(bottom - top)
|
||||
|
||||
resolve(group)
|
||||
}
|
||||
|
@ -2,13 +2,14 @@
|
||||
* @Author: Jeremy Yu
|
||||
* @Date: 2024-03-28 21:00:00
|
||||
* @Description:
|
||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditTime: 2024-03-28 14:00:00
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 16:02:46
|
||||
*/
|
||||
|
||||
import { useCanvasStore, useHistoryStore } from "@/store"
|
||||
import { TWidgetStore, TdWidgetData } from ".."
|
||||
import { customAlphabet } from 'nanoid/non-secure'
|
||||
import { transferTransformWidgets } from "@/utils/widgets/transferTranslate"
|
||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||
|
||||
|
||||
@ -16,11 +17,12 @@ export function addGroup(store: TWidgetStore, group: TdWidgetData[]) {
|
||||
const historyStore = useHistoryStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
let parent: TdWidgetData | null = null
|
||||
group.forEach((item) => {
|
||||
const tGroup = transferTransformWidgets(group)
|
||||
tGroup.forEach((item) => {
|
||||
item.uuid = nanoid() // 重设id
|
||||
item.type === 'w-group' && (parent = item) // 找出父组件
|
||||
})
|
||||
group.forEach((item) => {
|
||||
tGroup.forEach((item) => {
|
||||
!item.isContainer && parent && (item.parent = parent.uuid) // 重设父id
|
||||
item.text && (item.text = decodeURIComponent(item.text))
|
||||
store.dWidgets.push(item)
|
||||
|
@ -10,13 +10,14 @@
|
||||
import { customAlphabet } from 'nanoid/non-secure'
|
||||
import { TWidgetStore, TdWidgetData } from '..'
|
||||
import { useCanvasStore, useHistoryStore } from '@/store'
|
||||
import { transferTransformWidgets } from '@/utils/widgets/transferTranslate'
|
||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||
|
||||
// TODO: 选择模板
|
||||
export function setTemplate(store: TWidgetStore, allWidgets: TdWidgetData[]) {
|
||||
const historyStore = useHistoryStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
allWidgets.forEach((item) => {
|
||||
transferTransformWidgets(allWidgets).forEach((item) => {
|
||||
Number(item.uuid) < 0 && (item.uuid = nanoid()) // 重设id
|
||||
item.text && (item.text = decodeURIComponent(item.text))
|
||||
store.dWidgets.push(item)
|
||||
|
@ -2,13 +2,14 @@
|
||||
* @Author: Jeremy Yu
|
||||
* @Date: 2024-03-28 21:00:00
|
||||
* @Description:
|
||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditTime: 2024-03-28 14:00:00
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 23:23:56
|
||||
*/
|
||||
|
||||
import { useCanvasStore, useHistoryStore } from "@/store"
|
||||
import { TWidgetStore, TdWidgetData } from ".."
|
||||
import { customAlphabet } from 'nanoid/non-secure'
|
||||
import { getOffsetFromTransform, removeTranslate, transferTransformWidget, transferTransformWidgets } from "@/utils/widgets/transferTranslate"
|
||||
const nanoid = customAlphabet('1234567890abcdef', 12)
|
||||
|
||||
type TUpdateWidgetKey = keyof TdWidgetData
|
||||
@ -37,7 +38,7 @@ export function updateWidgetData(store: TWidgetStore, { uuid, key, value, pushHi
|
||||
break
|
||||
case 'left':
|
||||
case 'top':
|
||||
if (widget.isContainer) {
|
||||
/* if (widget.isContainer) {
|
||||
let dLeft = widget.left - Number(value)
|
||||
let dTop = widget.top - Number(value)
|
||||
if (key === 'left') {
|
||||
@ -54,8 +55,32 @@ export function updateWidgetData(store: TWidgetStore, { uuid, key, value, pushHi
|
||||
child.top -= dTop
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
delete widget.left
|
||||
delete widget.top
|
||||
break
|
||||
case 'transform':
|
||||
if (widget.isContainer) {
|
||||
const { x: gX1, y: gY1 } = getOffsetFromTransform(value as any)
|
||||
const { x: gX, y: gY } = getOffsetFromTransform(widget.transform)
|
||||
const dLeft = gX - gX1
|
||||
const dTop = gY - gY1
|
||||
const len = store.dWidgets.length
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const child = store.dWidgets[i]
|
||||
if (child.parent === widget.uuid) {
|
||||
let cTransform = removeTranslate(child.transform)
|
||||
const { x, y } = getOffsetFromTransform(child.transform)
|
||||
cTransform = `translate(${x - dLeft}px, ${y - dTop}px) ${cTransform}`
|
||||
child.transform = cTransform
|
||||
}
|
||||
}
|
||||
}
|
||||
// widget.transform = value as string
|
||||
break;
|
||||
case 'transformOrigin':
|
||||
// widget.transformOrigin = value as string
|
||||
break;
|
||||
}
|
||||
(widget[key] as TUpdateWidgetPayload['value']) = value
|
||||
if (pushHistory) {
|
||||
@ -73,7 +98,8 @@ export type TUpdateWidgetMultiplePayload = {
|
||||
uuid: string
|
||||
data: {
|
||||
key: TUpdateWidgetKey
|
||||
value: number
|
||||
// value: number
|
||||
value: string | number | boolean | Record<string, any>
|
||||
}[]
|
||||
pushHistory?: boolean
|
||||
}
|
||||
@ -82,7 +108,8 @@ export type TUpdateWidgetMultiplePayload = {
|
||||
export function updateWidgetMultiple(store: TWidgetStore, { uuid, data, pushHistory }: TUpdateWidgetMultiplePayload) {
|
||||
for (const item of data) {
|
||||
const { key, value } = item
|
||||
const widget = store.dWidgets.find((item) => item.uuid === uuid)
|
||||
updateWidgetData(store, { uuid, key, value })
|
||||
/* const widget = store.dWidgets.find((item) => item.uuid === uuid)
|
||||
if (widget && (widget[key] !== value || pushHistory)) {
|
||||
switch (key) {
|
||||
case 'left':
|
||||
@ -108,7 +135,7 @@ export function updateWidgetMultiple(store: TWidgetStore, { uuid, data, pushHist
|
||||
break
|
||||
}
|
||||
(widget[key] as number | string) = value
|
||||
}
|
||||
} */
|
||||
}
|
||||
setTimeout(() => {
|
||||
const historyStore = useHistoryStore()
|
||||
@ -122,7 +149,7 @@ export function addWidget(store: TWidgetStore, setting: TdWidgetData) {
|
||||
const historyStore = useHistoryStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
setting.uuid = nanoid()
|
||||
store.dWidgets.push(setting)
|
||||
store.dWidgets.push(transferTransformWidget(setting))
|
||||
const len = store.dWidgets.length
|
||||
// store.state.dActiveElement = store.state.dWidgets[len - 1]
|
||||
|
||||
@ -233,7 +260,7 @@ export function setWidgetStyle(state: TWidgetStore, { uuid, key, value, pushHist
|
||||
}
|
||||
|
||||
export function setDWidgets(state: TWidgetStore, e: TdWidgetData[]) {
|
||||
state.dWidgets = e
|
||||
state.dWidgets = transferTransformWidgets(e)
|
||||
}
|
||||
|
||||
// 锁定所有图层 / 再次调用时还原图层
|
||||
|
@ -2,8 +2,8 @@
|
||||
* @Author: Jeremy Yu
|
||||
* @Date: 2024-03-18 21:00:00
|
||||
* @Description: Store方法export
|
||||
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||
* @LastEditTime: 2024-03-28 14:00:00
|
||||
* @LastEditors: xi_zi
|
||||
* @LastEditTime: 2024-04-03 15:26:46
|
||||
*/
|
||||
|
||||
import { Store, defineStore } from "pinia";
|
||||
@ -28,6 +28,7 @@ export type TdWidgetData = TPageState & Partial<TCommonItemData> & {
|
||||
imgUrl?: string
|
||||
rotate?: string
|
||||
transform?: string
|
||||
transformOrigin?: string
|
||||
sliceData?: Record<string, any>
|
||||
flip?: boolean
|
||||
cropEdit?: boolean
|
||||
|
30
src/utils/addFont.ts
Normal file
30
src/utils/addFont.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* @Description: 添加字体
|
||||
* @Author: xi_zi
|
||||
* @Date: 2024-03-20 14:59:26
|
||||
* @LastEditTime: 2024-03-20 16:11:12
|
||||
* @LastEditors: xi_zi
|
||||
*/
|
||||
|
||||
/**
|
||||
* 字体缓存
|
||||
*/
|
||||
const fonts = new Map()
|
||||
|
||||
/**
|
||||
* 添加字体
|
||||
* @param family
|
||||
* @param url
|
||||
* @returns
|
||||
*/
|
||||
export const addFont = async (family: string, url: string) => {
|
||||
const key = `${family}_${url}`
|
||||
if (fonts.has(key)) return { loadFont: fonts.get(key), family, url }
|
||||
|
||||
const loadFont = new window.FontFace(family, `url(${url})`)
|
||||
await loadFont.load()
|
||||
document.fonts.add(loadFont)
|
||||
fonts.set(key, loadFont)
|
||||
|
||||
return { loadFont, family, url }
|
||||
}
|
971
src/utils/magic.ts
Normal file
971
src/utils/magic.ts
Normal file
@ -0,0 +1,971 @@
|
||||
export default {
|
||||
"version": "2.0.0",
|
||||
"type": "page",
|
||||
"uuid": -1,
|
||||
"global": {
|
||||
"unit": "px",
|
||||
"name": "弹窗-运营类_9cd1ee.psd",
|
||||
"backgroundColor": "#ffffffff",
|
||||
"layout": {
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"height": 1176,
|
||||
"width": 840,
|
||||
"backgroundImage": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/弹窗_运营类_a4c646.png"
|
||||
}
|
||||
},
|
||||
"layouts": [
|
||||
{
|
||||
"uuid": "f069f2ba-5e3a-4dd2-b2b0-d6d2d7e4470a",
|
||||
"imageUrl": "",
|
||||
"title": "弹窗-运营类",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "7e156a83-6cea-4eca-94e7-975c4d9548d0",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/bg_2bdb0d.png",
|
||||
"title": "bg",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1175,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "7ec68f3b-123b-40fd-a868-2e2d71558799",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/搬家4_14ff9d.png",
|
||||
"title": "搬家4",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 287,
|
||||
"height": 56,
|
||||
"left": 277,
|
||||
"top": 1095,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "979d4e6a-700a-4fae-b830-18f5d270dd6d",
|
||||
"imageUrl": "",
|
||||
"title": "主视觉",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "b4561c96-bea7-4d3b-b4b7-307a25d8f8eb",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_894_156f13.png",
|
||||
"title": "椭圆 894",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 767,
|
||||
"height": 41,
|
||||
"left": 53,
|
||||
"top": 849,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "cedabc3d-0025-46a6-b4f1-c3db7d7106b3",
|
||||
"imageUrl": "",
|
||||
"title": "红包 拷贝",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "d058c4cb-f02b-49f3-b6a1-2ee5dfe126cb",
|
||||
"imageUrl": "",
|
||||
"title": "组 3231 拷贝 2",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "6738b1b4-3b1f-44fe-9f04-814c3e634280",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/图层_4_a21999.png",
|
||||
"title": "图层 4",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 703,
|
||||
"height": 528,
|
||||
"left": 68,
|
||||
"top": 345,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "974ae464-0066-4344-845a-398c9324eaa9",
|
||||
"imageUrl": "",
|
||||
"title": "底板2",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "af29f40a-beb0-4af3-94a5-d5f1f9dfa9f2",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/矩形_1066_5f9ff7.png",
|
||||
"title": "矩形 1066",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 594,
|
||||
"height": 333,
|
||||
"left": 128,
|
||||
"top": 322,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "76389660-f7a1-4e17-a2b5-eda27a4a90d1",
|
||||
"imageUrl": "",
|
||||
"title": "组 3998",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "064794d0-9f82-47cf-8b40-c2e6c5fbef51",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/形状_1765_f0b506.png",
|
||||
"title": "形状 1765",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 375,
|
||||
"height": 68,
|
||||
"left": 444,
|
||||
"top": 851,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "3e0e6cef-690e-4562-b541-b86eb11307f9",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/形状_517_93ba60.png",
|
||||
"title": "形状 517",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 324,
|
||||
"height": 72,
|
||||
"left": 8,
|
||||
"top": 847,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "572a49fd-298a-4687-9ae0-1a2773ed7fa2",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/图层_22_b0a7ae.png",
|
||||
"title": "图层 22",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 340,
|
||||
"height": 193,
|
||||
"left": 469,
|
||||
"top": 714,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "f9664870-5a00-4cf9-82e8-62afeea201c3",
|
||||
"imageUrl": "",
|
||||
"title": "组 3182",
|
||||
"opacity": 148,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 840,
|
||||
"height": 1176,
|
||||
"left": 0,
|
||||
"top": 0,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "group",
|
||||
"elements": [
|
||||
{
|
||||
"uuid": "f155cb71-11cf-481c-8a2c-ab3522115c09",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_6b48d5.png",
|
||||
"title": "椭圆 672",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 4,
|
||||
"height": 5,
|
||||
"left": 27,
|
||||
"top": 465,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "fc9b296c-d124-4ca7-8253-e3ca1b725ce9",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_拷贝_3_43f79c.png",
|
||||
"title": "椭圆 672 拷贝 3",
|
||||
"opacity": 128,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 5,
|
||||
"height": 4,
|
||||
"left": 727,
|
||||
"top": 527,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "c209f903-5994-4ce9-a3c3-89858a72f367",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_拷贝_4_d491e3.png",
|
||||
"title": "椭圆 672 拷贝 4",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 3,
|
||||
"height": 3,
|
||||
"left": 729,
|
||||
"top": 317,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "188e84a5-0524-4765-9ed7-22bfc80c25ac",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_拷贝_c115d0.png",
|
||||
"title": "椭圆 672 拷贝",
|
||||
"opacity": 89,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 2,
|
||||
"height": 2,
|
||||
"left": 12,
|
||||
"top": 260,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "8ba537f5-5fc5-40f8-95ad-86e84915e91a",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_拷贝_5_2c7e71.png",
|
||||
"title": "椭圆 672 拷贝 5",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 4,
|
||||
"height": 3,
|
||||
"left": 135,
|
||||
"top": 249,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "8d33d44c-5891-47ff-b76d-ab8040ee0c0b",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/椭圆_672_拷贝_2_416355.png",
|
||||
"title": "椭圆 672 拷贝 2",
|
||||
"opacity": 77,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 5,
|
||||
"height": 5,
|
||||
"left": 60,
|
||||
"top": 528,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "aa703ab3-7678-4b1e-9472-c5e910b43b44",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/图层_516_04e9fe.png",
|
||||
"title": "图层 516",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 262,
|
||||
"height": 171,
|
||||
"left": 49,
|
||||
"top": 737,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "43fb0ac4-48c9-4ec3-8b53-45eaaa1fd6b8",
|
||||
"imageUrl": "",
|
||||
"title": "200元",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 459,
|
||||
"height": 167,
|
||||
"left": 195,
|
||||
"top": 410,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "text",
|
||||
"elements": [
|
||||
|
||||
],
|
||||
"color": "#F92826FF",
|
||||
"fontFamily": "Alibaba-PuHuiTi-B",
|
||||
"fontStyle": "normal",
|
||||
"fontWeight": 400,
|
||||
"fontSize": 230,
|
||||
"lineHeight": 60,
|
||||
"textType": "paint",
|
||||
"letterSpacing": 0,
|
||||
"textDecoration": "none",
|
||||
"orientation": "horizontal",
|
||||
"textAlign": "center",
|
||||
"content": "200元",
|
||||
"contents": [
|
||||
|
||||
],
|
||||
"boundingBox": {
|
||||
"left": 195,
|
||||
"top": 410,
|
||||
"right": 654,
|
||||
"bottom": 577,
|
||||
"width": 459,
|
||||
"height": 167
|
||||
},
|
||||
"textEffects": [
|
||||
|
||||
],
|
||||
"shadows": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "6d054275-770d-4405-9ea0-e671eed9e591",
|
||||
"imageUrl": "",
|
||||
"title": "现金",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 89,
|
||||
"height": 42,
|
||||
"left": 381,
|
||||
"top": 333,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "text",
|
||||
"elements": [
|
||||
|
||||
],
|
||||
"color": "#FF9FA0FF",
|
||||
"fontFamily": "AdobeHeitiStd-Regular",
|
||||
"fontStyle": "normal",
|
||||
"fontWeight": 400,
|
||||
"fontSize": 46,
|
||||
"lineHeight": 60,
|
||||
"textType": "paint",
|
||||
"letterSpacing": 0,
|
||||
"textDecoration": "none",
|
||||
"orientation": "horizontal",
|
||||
"textAlign": "center",
|
||||
"content": "现金",
|
||||
"contents": [
|
||||
|
||||
],
|
||||
"boundingBox": {
|
||||
"left": 381,
|
||||
"top": 333,
|
||||
"right": 470,
|
||||
"bottom": 375,
|
||||
"width": 89,
|
||||
"height": 42
|
||||
},
|
||||
"textEffects": [
|
||||
|
||||
],
|
||||
"shadows": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "67824131-6231-4f3d-be98-c9c199167b61",
|
||||
"imageUrl": "/var/folders/g4/6lr6kwj90_z6mc6njkw1rrkm0000gn/T/com.magic-panel.cep/矩形_976_48da88.png",
|
||||
"title": "矩形 976",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 744,
|
||||
"height": 167,
|
||||
"left": 48,
|
||||
"top": 913,
|
||||
"transform": "",
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "image",
|
||||
"elements": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "b8367b42-a1ad-4082-b43d-3dbb580d2dff",
|
||||
"imageUrl": "",
|
||||
"title": "去领取",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 194,
|
||||
"height": 63,
|
||||
"left": 325,
|
||||
"top": 954,
|
||||
"transform": {
|
||||
"a": 1,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "text",
|
||||
"elements": [
|
||||
|
||||
],
|
||||
"color": "#FFFFFFFF",
|
||||
"fontFamily": "SourceHanSansCN-Bold",
|
||||
"fontStyle": "normal",
|
||||
"fontWeight": 400,
|
||||
"fontSize": 66,
|
||||
"lineHeight": 60,
|
||||
"textType": "paint",
|
||||
"letterSpacing": 0,
|
||||
"textDecoration": "none",
|
||||
"orientation": "horizontal",
|
||||
"textAlign": "center",
|
||||
"content": "去领取",
|
||||
"contents": [
|
||||
|
||||
],
|
||||
"boundingBox": {
|
||||
"left": 325,
|
||||
"top": 954,
|
||||
"right": 519,
|
||||
"bottom": 1017,
|
||||
"width": 194,
|
||||
"height": 63
|
||||
},
|
||||
"textEffects": [
|
||||
|
||||
],
|
||||
"shadows": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "438d2f8b-3d6a-467c-b96c-d072611f0928",
|
||||
"imageUrl": "",
|
||||
"title": "赢现金奖励",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 636,
|
||||
"height": 159,
|
||||
"left": 97,
|
||||
"top": 138,
|
||||
"transform": {
|
||||
"a": 1.07171211757033,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 1.0695627658834,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "text",
|
||||
"elements": [
|
||||
|
||||
],
|
||||
"color": "#FFFFFFFF",
|
||||
"fontFamily": "MFYuanHei-Regular",
|
||||
"fontStyle": "italic",
|
||||
"fontWeight": 400,
|
||||
"fontSize": 110.32544708252,
|
||||
"lineHeight": 120,
|
||||
"textType": "paint",
|
||||
"letterSpacing": 0,
|
||||
"textDecoration": "none",
|
||||
"orientation": "horizontal",
|
||||
"textAlign": "left",
|
||||
"content": "赢现金奖励",
|
||||
"contents": [
|
||||
|
||||
],
|
||||
"boundingBox": {
|
||||
"left": 97,
|
||||
"top": 138,
|
||||
"right": 733,
|
||||
"bottom": 297,
|
||||
"width": 636,
|
||||
"height": 159
|
||||
},
|
||||
"textEffects": [
|
||||
{
|
||||
"enable": true,
|
||||
"shadow": {
|
||||
"enable": true,
|
||||
"blur": 22.39407356372,
|
||||
"offsetX": 3.44029429027805,
|
||||
"offsetY": -1.45024358655247,
|
||||
"color": "#0078FFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enable": true,
|
||||
"stroke": {
|
||||
"width": 1.86617279697666,
|
||||
"color": "#FFFFFFFF",
|
||||
"enable": true,
|
||||
"type": "outer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enable": true,
|
||||
"filling": {
|
||||
"color": "linear-gradient(-183deg, #FFFFFFFF 12%,#FFDD80FF 99%)",
|
||||
"enable": true,
|
||||
"type": 2,
|
||||
"gradient": {
|
||||
"byLine": 0,
|
||||
"angle": -183,
|
||||
"stops": [
|
||||
{
|
||||
"color": "#FFFFFFFF",
|
||||
"offset": 0.12
|
||||
},
|
||||
{
|
||||
"color": "#FFDD80FF",
|
||||
"offset": 0.99
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"shadows": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "4f7dc2ad-c359-42ee-86f5-86f91de4f7d1",
|
||||
"imageUrl": "",
|
||||
"title": "接单码邀冷藏新客 ",
|
||||
"opacity": 255,
|
||||
"padding": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"width": 559,
|
||||
"height": 108,
|
||||
"left": 140,
|
||||
"top": 46,
|
||||
"transform": {
|
||||
"a": 0.85062213156219,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 0.84891618265722,
|
||||
"tx": 0,
|
||||
"ty": 0
|
||||
},
|
||||
"hidden": false,
|
||||
"lock": false,
|
||||
"metaInfo": null,
|
||||
"type": "text",
|
||||
"elements": [
|
||||
|
||||
],
|
||||
"color": "#FFFFFFFF",
|
||||
"fontFamily": "MFYuanHei-Regular",
|
||||
"fontStyle": "italic",
|
||||
"fontWeight": 400,
|
||||
"fontSize": 74.7969207763672,
|
||||
"lineHeight": 120,
|
||||
"textType": "paint",
|
||||
"letterSpacing": 0,
|
||||
"textDecoration": "none",
|
||||
"orientation": "horizontal",
|
||||
"textAlign": "left",
|
||||
"content": "接单码邀冷藏新客\r",
|
||||
"contents": [
|
||||
|
||||
],
|
||||
"boundingBox": {
|
||||
"left": 140,
|
||||
"top": 46,
|
||||
"right": 699,
|
||||
"bottom": 154,
|
||||
"width": 559,
|
||||
"height": 108
|
||||
},
|
||||
"textEffects": [
|
||||
{
|
||||
"enable": true,
|
||||
"shadow": {
|
||||
"enable": true,
|
||||
"blur": 28.2146432704769,
|
||||
"offsetX": 4.33448054323216,
|
||||
"offsetY": -1.82718455994381,
|
||||
"color": "#0078FFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enable": true,
|
||||
"stroke": {
|
||||
"width": 2.35122027253975,
|
||||
"color": "#FFFFFFFF",
|
||||
"enable": true,
|
||||
"type": "outer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"shadows": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
52
src/utils/widgets/tansferTLS.ts
Normal file
52
src/utils/widgets/tansferTLS.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @Description: 根据 Matrix 转换位置&尺寸
|
||||
* @Author: xi_zi
|
||||
* @Date: 2024-03-20 23:32:07
|
||||
* @LastEditTime: 2024-03-20 23:52:28
|
||||
* @LastEditors: xi_zi
|
||||
*/
|
||||
|
||||
/**
|
||||
* 根据 Matrix 转换宽度
|
||||
* @param matrix
|
||||
* @param width
|
||||
* @returns
|
||||
*/
|
||||
export const transferMatrixWidth = (width: number, matrix?: { a: number, b: number, c: number, d: number, tx: number, ty: number }) => {
|
||||
if (matrix?.a === undefined) return width
|
||||
return width / Math.pow(Math.abs(matrix.a), 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Matrix 转换高度
|
||||
* @param matrix
|
||||
* @param height
|
||||
* @returns
|
||||
*/
|
||||
export const transferMatrixHeight = (height: number, matrix?: { a: number, b: number, c: number, d: number, tx: number, ty: number }) => {
|
||||
if (matrix?.d === undefined) return height
|
||||
return height / Math.pow(Math.abs(matrix.d), 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Matrix 转换左侧定位
|
||||
* @param matrix
|
||||
* @param left
|
||||
* @returns
|
||||
*/
|
||||
export const transferMatrixLeft = (left: number, matrix?: { a: number, b: number, c: number, d: number, tx: number, ty: number }) => {
|
||||
if (matrix?.a === undefined) return left
|
||||
return left * Math.pow(Math.abs(matrix.a), 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Matrix 转换顶部定位
|
||||
* @param matrix
|
||||
* @param top
|
||||
* @returns
|
||||
*/
|
||||
export const transferMatrixTop = (top: number, matrix?: { a: number, b: number, c: number, d: number, tx: number, ty: number }) => {
|
||||
if (matrix?.d === undefined) return top
|
||||
return top * Math.pow(Math.abs(matrix.d), 1)
|
||||
}
|
||||
|
61
src/utils/widgets/transferTranslate.ts
Normal file
61
src/utils/widgets/transferTranslate.ts
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* @Description: transform 工具
|
||||
* @Author: xi_zi
|
||||
* @Date: 2024-04-03 15:17:57
|
||||
* @LastEditTime: 2024-04-03 23:11:53
|
||||
* @LastEditors: xi_zi
|
||||
*/
|
||||
import { TdWidgetData } from "@/store/design/widget";
|
||||
|
||||
/**
|
||||
* 兼容旧版 top left 数据
|
||||
* @param widgetData
|
||||
* @returns
|
||||
*/
|
||||
export const transferTransformWidgets = (widgetData: TdWidgetData[]): TdWidgetData[] => {
|
||||
return widgetData.map(data => transferTransformWidget(data))
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容旧版 top left 数据
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export const transferTransformWidget = (data: TdWidgetData): TdWidgetData => {
|
||||
const resData = { ...data }
|
||||
const { left, top, transform, } = resData
|
||||
console.log(data, 'widgetTransformStyle')
|
||||
if (left !== undefined || top !== undefined) {
|
||||
const regex = /translate\([^)]*\)/g
|
||||
resData.transform = `translate(${left ?? 0}px, ${top ?? 0}px) ${(transform ?? '').replace(regex, '')}`
|
||||
delete resData.left;
|
||||
delete resData.top
|
||||
} else if (transform?.includes('translate')) {
|
||||
resData.transform = transform
|
||||
}
|
||||
console.log(resData, 'widgetTransformStyle==end')
|
||||
return resData
|
||||
}
|
||||
|
||||
/**
|
||||
* 将transform中的translate移除
|
||||
* @param transform
|
||||
* @returns
|
||||
*/
|
||||
export const removeTranslate = (transform: string = '') => `${(transform ?? '').replace(/translate\([^)]*\)/g, '')}`
|
||||
|
||||
/**
|
||||
* 获取transform中的translate
|
||||
* @param transform
|
||||
* @returns
|
||||
*/
|
||||
export const getOffsetFromTransform = (transform: string = '') => {
|
||||
const res = { x: 0, y: 0 }
|
||||
const regex = /translate\((-?\d+(\.\d+)?)(px)?,\s*(-?\d+(\.\d+)?)(px)?\)/g
|
||||
transform.replace(regex, (_match, x, _1, _2, y) => {
|
||||
res.x = parseFloat(x ?? 0)
|
||||
res.y = parseFloat(y ?? 0)
|
||||
return ''
|
||||
});
|
||||
return res
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2023-09-18 17:34:44
|
||||
* @Description:
|
||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||
* @LastEditors: xi_zi
|
||||
* @LastUpdateContent: Support typescript
|
||||
* @LastEditTime: 2024-04-03 10:58:42
|
||||
* @LastEditTime: 2024-04-03 11:11:39
|
||||
-->
|
||||
<template>
|
||||
<div id="page-design-index" ref="pageDesignIndex" class="page-design-bg-color">
|
||||
@ -39,46 +39,36 @@
|
||||
<zoom-control ref="zoomControlRef" />
|
||||
<!-- 右键菜单 -->
|
||||
<right-click-menu />
|
||||
<!-- 旋转缩放组件 -->
|
||||
<Moveable />
|
||||
|
||||
<moveable />
|
||||
|
||||
<!-- 遮罩百分比进度条 -->
|
||||
<ProgressLoading
|
||||
:percent="state.downloadPercent"
|
||||
:text="state.downloadText"
|
||||
:msg="state.downloadMsg"
|
||||
cancelText="取消"
|
||||
@cancel="downloadCancel"
|
||||
@done="state.downloadPercent = 0"
|
||||
/>
|
||||
<ProgressLoading :percent="state.downloadPercent" :text="state.downloadText" cancelText="取消" @cancel="downloadCancel" @done="state.downloadPercent = 0" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import _config from '../config'
|
||||
import {
|
||||
CSSProperties, computed, nextTick,
|
||||
onBeforeUnmount, onMounted, reactive, ref,
|
||||
} from 'vue'
|
||||
import { CSSProperties, computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
||||
import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue'
|
||||
import Moveable from '@/components/business/moveable/Moveable.vue'
|
||||
import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
||||
import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
|
||||
import lineGuides from '@/components/modules/layout/lineGuides.vue'
|
||||
import shortcuts from '@/mixins/shortcuts'
|
||||
// import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
|
||||
import HeaderOptions from './components/HeaderOptions.vue'
|
||||
import ProgressLoading from '@/components/common/ProgressLoading/download.vue'
|
||||
import ProgressLoading from '@/components/common/ProgressLoading/index.vue'
|
||||
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useCanvasStore, useControlStore, useHistoryStore, useWidgetStore, useGroupStore } from '@/store'
|
||||
import Moveable from '@/components/business/moveable/Moveable.vue'
|
||||
|
||||
type TState = {
|
||||
style: CSSProperties
|
||||
downloadPercent: number // 下载进度
|
||||
downloadText: string
|
||||
downloadMsg: string | undefined
|
||||
isContinue: boolean
|
||||
APP_NAME: string
|
||||
showLineGuides: boolean
|
||||
@ -95,7 +85,6 @@ const { dZoom } = storeToRefs(useCanvasStore())
|
||||
const { dHistoryParams } = storeToRefs(useHistoryStore())
|
||||
const { dActiveElement, dCopyElement } = storeToRefs(widgetStore)
|
||||
|
||||
|
||||
const state = reactive<TState>({
|
||||
style: {
|
||||
left: '0px',
|
||||
@ -103,7 +92,6 @@ const state = reactive<TState>({
|
||||
// openDraw: false,
|
||||
downloadPercent: 0, // 下载进度
|
||||
downloadText: '',
|
||||
downloadMsg: '',
|
||||
isContinue: true,
|
||||
APP_NAME: _config.APP_NAME,
|
||||
showLineGuides: false,
|
||||
@ -115,8 +103,8 @@ const route = useRoute()
|
||||
|
||||
const beforeUnload = function (e: Event): any {
|
||||
if (dHistoryParams.value.length > 0) {
|
||||
const confirmationMessage: string = '系统不会自动保存您未修改的内容';
|
||||
(e || window.event).returnValue = (confirmationMessage as any) // Gecko and Trident
|
||||
const confirmationMessage: string = '系统不会自动保存您未修改的内容'
|
||||
;(e || window.event).returnValue = confirmationMessage as any // Gecko and Trident
|
||||
return confirmationMessage // Gecko and WebKit
|
||||
} else return false
|
||||
}
|
||||
@ -134,9 +122,7 @@ defineExpose({
|
||||
})
|
||||
|
||||
const undoable = computed(() => {
|
||||
return !(
|
||||
dHistoryParams.value.index === -1 ||
|
||||
(dHistoryParams.value.index === 0 && dHistoryParams.value.length === dHistoryParams.value.maxLength))
|
||||
return !(dHistoryParams.value.index === -1 || (dHistoryParams.value.index === 0 && dHistoryParams.value.length === dHistoryParams.value.maxLength))
|
||||
})
|
||||
|
||||
const redoable = computed(() => {
|
||||
@ -182,7 +168,7 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
// ...mapActions(['selectWidget', 'initGroupJson', 'handleHistory']),
|
||||
|
||||
function handleHistory(data: "undo" | "redo") {
|
||||
function handleHistory(data: 'undo' | 'redo') {
|
||||
historyStore.handleHistory(data)
|
||||
// store.dispatch('handleHistory', data)
|
||||
}
|
||||
@ -220,10 +206,9 @@ function fixTopBarScroll() {
|
||||
// console.log('click listener', e)
|
||||
// }
|
||||
|
||||
function optionsChange({ downloadPercent, downloadText, downloadMsg }: { downloadPercent: number, downloadText: string, downloadMsg?: string }) {
|
||||
function optionsChange({ downloadPercent, downloadText }: { downloadPercent: number; downloadText: string }) {
|
||||
state.downloadPercent = downloadPercent
|
||||
state.downloadText = downloadText
|
||||
state.downloadMsg = downloadMsg
|
||||
}
|
||||
</script>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user