mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
rebuilt: canvas design store to pinia
This commit is contained in:
parent
3106562174
commit
54b9338e52
@ -13,11 +13,15 @@
|
|||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import html2canvas from 'html2canvas'
|
import html2canvas from 'html2canvas'
|
||||||
import Qiniu from '@/common/methods/QiNiu'
|
import Qiniu from '@/common/methods/QiNiu'
|
||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
// import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useCanvasStore } from '@/pinia';
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const { dZoom } = useSetupMapGetters(['dZoom'])
|
// const { dZoom } = useSetupMapGetters(['dZoom'])
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
|
const { dZoom } = storeToRefs(canvasStore)
|
||||||
|
|
||||||
|
|
||||||
// props: ['modelValue'],
|
// props: ['modelValue'],
|
||||||
@ -29,7 +33,8 @@ async function createCover(cb: any) {
|
|||||||
store.dispatch('selectWidget', {
|
store.dispatch('selectWidget', {
|
||||||
uuid: '-1',
|
uuid: '-1',
|
||||||
})
|
})
|
||||||
store.dispatch('updateZoom', 100)
|
canvasStore.updateZoom(100)
|
||||||
|
// store.dispatch('updateZoom', 100)
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
useCORS: true, // 跨域图片
|
useCORS: true, // 跨域图片
|
||||||
@ -51,7 +56,8 @@ async function createCover(cb: any) {
|
|||||||
'image/jpeg',
|
'image/jpeg',
|
||||||
0.15,
|
0.15,
|
||||||
)
|
)
|
||||||
store.dispatch('updateZoom', nowZoom)
|
canvasStore.updateZoom(nowZoom)
|
||||||
|
// store.dispatch('updateZoom', nowZoom)
|
||||||
clonePage.remove()
|
clonePage.remove()
|
||||||
})
|
})
|
||||||
}, 10)
|
}, 10)
|
||||||
|
@ -70,7 +70,7 @@ import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
|||||||
import { debounce } from 'throttle-debounce'
|
import { debounce } from 'throttle-debounce'
|
||||||
import { move, moveInit } from '@/mixins/move'
|
import { move, moveInit } from '@/mixins/move'
|
||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
import { usePageStore } from '@/pinia'
|
import { useCanvasStore, usePageStore } from '@/pinia'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
// 页面设计组件
|
// 页面设计组件
|
||||||
type TProps = {
|
type TProps = {
|
||||||
@ -92,11 +92,12 @@ type TSetting = {
|
|||||||
const store = useStore()
|
const store = useStore()
|
||||||
const { pageDesignCanvasId } = defineProps<TProps>()
|
const { pageDesignCanvasId } = defineProps<TProps>()
|
||||||
const {
|
const {
|
||||||
dPaddingTop, dZoom, dScreen, dWidgets,
|
dWidgets,
|
||||||
dActiveElement, dSelectWidgets, dAltDown, dDraging,
|
dActiveElement, dSelectWidgets, dAltDown, dDraging,
|
||||||
dHoverUuid, showRotatable
|
dHoverUuid, showRotatable
|
||||||
} = useSetupMapGetters(['dPaddingTop', 'dZoom', 'dScreen', 'dWidgets', 'dActiveElement', 'dHoverUuid', 'dSelectWidgets', 'dAltDown', 'dDraging', 'showRotatable'])
|
} = useSetupMapGetters(['dWidgets', 'dActiveElement', 'dHoverUuid', 'dSelectWidgets', 'dAltDown', 'dDraging', 'showRotatable'])
|
||||||
const { dPage } = storeToRefs(usePageStore())
|
const { dPage } = storeToRefs(usePageStore())
|
||||||
|
const { dZoom, dPaddingTop, dScreen } = storeToRefs(useCanvasStore())
|
||||||
|
|
||||||
|
|
||||||
let _dropIn: string | null = ''
|
let _dropIn: string | null = ''
|
||||||
@ -188,24 +189,24 @@ async function drop(e: MouseEvent) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const half = {
|
const half = {
|
||||||
x: parent.width ? (parent.width * store.getters.dZoom) / 100 / 2 : 0,
|
x: parent.width ? (parent.width * dZoom.value) / 100 / 2 : 0,
|
||||||
y: parent.height ? (parent.height * store.getters.dZoom) / 100 / 2 : 0
|
y: parent.height ? (parent.height * dZoom.value) / 100 / 2 : 0
|
||||||
}
|
}
|
||||||
componentItem.forEach((element) => {
|
componentItem.forEach((element) => {
|
||||||
element.left += (lost ? lostX - half.x : e.layerX - half.x) * (100 / store.getters.dZoom)
|
element.left += (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||||
element.top += (lost ? lostY - half.y : e.layerY - half.y) * (100 / store.getters.dZoom)
|
element.top += (lost ? lostY - half.y : e.layerY - half.y) * (100 / dZoom.value)
|
||||||
})
|
})
|
||||||
store.dispatch('addGroup', componentItem)
|
store.dispatch('addGroup', componentItem)
|
||||||
// addGroup(item)
|
// addGroup(item)
|
||||||
}
|
}
|
||||||
// 设置坐标
|
// 设置坐标
|
||||||
const half = {
|
const half = {
|
||||||
x: setting.width ? (setting.width * store.getters.dZoom) / 100 / 2 : 0,
|
x: setting.width ? (setting.width * dZoom.value) / 100 / 2 : 0,
|
||||||
y: setting.height ? (setting.height * store.getters.dZoom) / 100 / 2 : 0
|
y: setting.height ? (setting.height * dZoom.value) / 100 / 2 : 0
|
||||||
}
|
}
|
||||||
// const half = { x: (this.dDragInitData.offsetX * this.dZoom) / 100, y: (this.dDragInitData.offsetY * this.dZoom) / 100 }
|
// const half = { x: (this.dDragInitData.offsetX * this.dZoom) / 100, y: (this.dDragInitData.offsetY * this.dZoom) / 100 }
|
||||||
setting.left = (lost ? lostX - half.x : e.layerX - half.x) * (100 / store.getters.dZoom)
|
setting.left = (lost ? lostX - half.x : e.layerX - half.x) * (100 / dZoom.value)
|
||||||
setting.top = (lost ? lostY - half.y : e.layerY - half.y) * (100 / store.getters.dZoom)
|
setting.top = (lost ? lostY - half.y : e.layerY - half.y) * (100 / dZoom.value)
|
||||||
if (lost && type === 'image') {
|
if (lost && type === 'image') {
|
||||||
// 如果不从画布加入,且不是图片类型,则判断是否加入到svg中
|
// 如果不从画布加入,且不是图片类型,则判断是否加入到svg中
|
||||||
const target = await getTarget(eventTarget)
|
const target = await getTarget(eventTarget)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { watch } from 'vue'
|
import { watch } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import Guides, { GuideOptions } from '@scena/guides'
|
import Guides, { GuideOptions } from '@scena/guides'
|
||||||
|
import { useCanvasStore } from '@/pinia';
|
||||||
|
|
||||||
type TProps = {
|
type TProps = {
|
||||||
show: boolean
|
show: boolean
|
||||||
@ -35,6 +36,7 @@ const props = withDefaults(defineProps<TProps>(), {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
const container = 'page-design' // page-design out-page
|
const container = 'page-design' // page-design out-page
|
||||||
let guidesTop: TGuidesData | null = null
|
let guidesTop: TGuidesData | null = null
|
||||||
let guidesLeft: TGuidesData | null = null
|
let guidesLeft: TGuidesData | null = null
|
||||||
@ -47,7 +49,7 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.getters.dZoom,
|
() => canvasStore.dZoom,
|
||||||
() => {
|
() => {
|
||||||
changeScroll()
|
changeScroll()
|
||||||
},
|
},
|
||||||
@ -113,7 +115,7 @@ function render() {
|
|||||||
|
|
||||||
function changeScroll() {
|
function changeScroll() {
|
||||||
if (guidesTop && guidesLeft) {
|
if (guidesTop && guidesLeft) {
|
||||||
const zoom = store.getters.dZoom / 100
|
const zoom = canvasStore.dZoom / 100
|
||||||
guidesTop.zoom = zoom
|
guidesTop.zoom = zoom
|
||||||
guidesLeft.zoom = zoom
|
guidesLeft.zoom = zoom
|
||||||
if (zoom < 0.9) {
|
if (zoom < 0.9) {
|
||||||
|
@ -27,7 +27,7 @@ import { OtherList, TZoomData, ZoomList } from './data';
|
|||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { usePageStore } from '@/pinia';
|
import { useCanvasStore, usePageStore } from '@/pinia';
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
@ -48,8 +48,10 @@ const otherIndex = ref(-1)
|
|||||||
const bestZoom = ref(0)
|
const bestZoom = ref(0)
|
||||||
const curAction = ref('')
|
const curAction = ref('')
|
||||||
|
|
||||||
const { dScreen, zoomScreenChange, dZoom } = useSetupMapGetters(['dScreen', 'zoomScreenChange', 'dZoom'])
|
const { zoomScreenChange } = useSetupMapGetters(['zoomScreenChange'])
|
||||||
|
const canvasStore = useCanvasStore()
|
||||||
const { dPage } = storeToRefs(usePageStore())
|
const { dPage } = storeToRefs(usePageStore())
|
||||||
|
const { dZoom, dScreen } = storeToRefs(canvasStore)
|
||||||
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -79,7 +81,8 @@ watch(
|
|||||||
if (realValue === -1) {
|
if (realValue === -1) {
|
||||||
realValue = calcZoom()
|
realValue = calcZoom()
|
||||||
}
|
}
|
||||||
store.dispatch('updateZoom', realValue)
|
canvasStore.updateZoom(realValue)
|
||||||
|
// store.dispatch('updateZoom', realValue)
|
||||||
// updateZoom(realValue)
|
// updateZoom(realValue)
|
||||||
autoFixTop()
|
autoFixTop()
|
||||||
}
|
}
|
||||||
@ -152,7 +155,8 @@ function changeScreen() {
|
|||||||
function screenChange() {
|
function screenChange() {
|
||||||
// 弹性尺寸即时修改
|
// 弹性尺寸即时修改
|
||||||
if (activezoomIndex.value === zoomList.value.length - 1) {
|
if (activezoomIndex.value === zoomList.value.length - 1) {
|
||||||
store.dispatch('updateZoom', calcZoom())
|
canvasStore.updateZoom(calcZoom())
|
||||||
|
// store.dispatch('updateZoom', calcZoom())
|
||||||
// this.updateZoom(this.calcZoom())
|
// this.updateZoom(this.calcZoom())
|
||||||
autoFixTop()
|
autoFixTop()
|
||||||
}
|
}
|
||||||
@ -221,7 +225,8 @@ function sub() {
|
|||||||
function mousewheelZoom(down: boolean) {
|
function mousewheelZoom(down: boolean) {
|
||||||
const value = Number(dZoom.value.toFixed(0))
|
const value = Number(dZoom.value.toFixed(0))
|
||||||
if (down && value <= 1) return
|
if (down && value <= 1) return
|
||||||
store.dispatch('updateZoom', down ? value - 1 : value + 1)
|
canvasStore.updateZoom(down ? value - 1 : value + 1)
|
||||||
|
// store.dispatch('updateZoom', down ? value - 1 : value + 1)
|
||||||
// updateZoom(down ? value - 1 : value + 1)
|
// updateZoom(down ? value - 1 : value + 1)
|
||||||
zoom.value.text = (value + '%') as any
|
zoom.value.text = (value + '%') as any
|
||||||
autoFixTop()
|
autoFixTop()
|
||||||
|
@ -41,7 +41,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, toRefs, onMounted } from 'vue'
|
import { reactive, toRefs, onMounted } from 'vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import wImage from '../../widgets/wImage/wImage.vue'
|
// import wImage from '../../widgets/wImage/wImage.vue'
|
||||||
|
import wImageSetting from '../../widgets/wImage/wImageSetting'
|
||||||
import wSvg from '../../widgets/wSvg/wSvg.vue'
|
import wSvg from '../../widgets/wSvg/wSvg.vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import setImageData from '@/common/methods/DesignFeatures/setImage'
|
import setImageData from '@/common/methods/DesignFeatures/setImage'
|
||||||
@ -187,7 +188,7 @@ async function selectItem(item: TGetListData) {
|
|||||||
}
|
}
|
||||||
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
||||||
// this.$store.commit('setShowMoveable', false)
|
// this.$store.commit('setShowMoveable', false)
|
||||||
let setting = item.type === 'svg' ? JSON.parse(JSON.stringify(wSvg.setting)) : JSON.parse(JSON.stringify(wImage.setting))
|
let setting = item.type === 'svg' ? JSON.parse(JSON.stringify(wSvg.setting)) : JSON.parse(JSON.stringify(wImageSetting))
|
||||||
const img = await setImageData(item)
|
const img = await setImageData(item)
|
||||||
|
|
||||||
setting.width = img.width
|
setting.width = img.width
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
// 图片列表
|
// 图片列表
|
||||||
// const NAME = 'img-list-wrap'
|
// const NAME = 'img-list-wrap'
|
||||||
import { toRefs, reactive, computed, onMounted } from 'vue'
|
import { toRefs, reactive, computed, onMounted } from 'vue'
|
||||||
import wImage from '../../widgets/wImage/wImage.vue'
|
// import wImage from '../../widgets/wImage/wImage.vue'
|
||||||
|
import wImageSetting from '../../widgets/wImage/wImageSetting'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import setImageData from '@/common/methods/DesignFeatures/setImage'
|
import setImageData from '@/common/methods/DesignFeatures/setImage'
|
||||||
@ -81,7 +82,7 @@ onMounted(async () => {
|
|||||||
const selectImg = async (index: number, list: TGetImageListResult[]) => {
|
const selectImg = async (index: number, list: TGetImageListResult[]) => {
|
||||||
const item = list ? list[index] : state.recommendImgList[index]
|
const item = list ? list[index] : state.recommendImgList[index]
|
||||||
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
||||||
let setting = JSON.parse(JSON.stringify(wImage.setting))
|
let setting = JSON.parse(JSON.stringify(wImageSetting))
|
||||||
const img = await setImageData(item) // await getImage(item.url)
|
const img = await setImageData(item) // await getImage(item.url)
|
||||||
setting.width = img.width
|
setting.width = img.width
|
||||||
setting.height = img.height // parseInt(100 / item.value.ratio, 10)
|
setting.height = img.height // parseInt(100 / item.value.ratio, 10)
|
||||||
|
@ -42,7 +42,8 @@ import { useRouter } from 'vue-router'
|
|||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import uploader from '@/components/common/Uploader'
|
import uploader from '@/components/common/Uploader'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import wImage from '../../widgets/wImage/wImage.vue'
|
// import wImage from '../../widgets/wImage/wImage.vue'
|
||||||
|
import wImageSetting from '../../widgets/wImage/wImageSetting'
|
||||||
import setImageData, { TItem2DataParam } from '@/common/methods/DesignFeatures/setImage'
|
import setImageData, { TItem2DataParam } from '@/common/methods/DesignFeatures/setImage'
|
||||||
import useConfirm from '@/common/methods/confirm'
|
import useConfirm from '@/common/methods/confirm'
|
||||||
import { TGetImageListResult, TMyPhotoResult } from '@/api/material'
|
import { TGetImageListResult, TMyPhotoResult } from '@/api/material'
|
||||||
@ -162,7 +163,7 @@ onMounted(() => {
|
|||||||
const selectImg = async (index: number) => {
|
const selectImg = async (index: number) => {
|
||||||
const item = state.imgList[index]
|
const item = state.imgList[index]
|
||||||
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
||||||
let setting = JSON.parse(JSON.stringify(wImage.setting))
|
let setting = JSON.parse(JSON.stringify(wImageSetting))
|
||||||
const img = await setImageData(item)
|
const img = await setImageData(item)
|
||||||
setting.width = img.width
|
setting.width = img.width
|
||||||
setting.height = img.height // parseInt(100 / item.value.ratio, 10)
|
setting.height = img.height // parseInt(100 / item.value.ratio, 10)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:id="params.uuid"
|
:id="params.uuid"
|
||||||
ref="widget"
|
ref="widgetRef"
|
||||||
:class="['w-image', { 'layer-lock': params.lock }]"
|
:class="['w-image', { 'layer-lock': params.lock }]"
|
||||||
:style="{
|
:style="{
|
||||||
position,
|
position: state.position,
|
||||||
left: params.left - parent.left + 'px',
|
left: params.left - parent.left + 'px',
|
||||||
top: params.top - parent.top + 'px',
|
top: params.top - parent.top + 'px',
|
||||||
width: params.width + 'px',
|
width: params.width + 'px',
|
||||||
@ -12,12 +12,18 @@
|
|||||||
opacity: params.opacity,
|
opacity: params.opacity,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div v-if="cropEdit" :ref="params.uuid + '_ebox'" :style="editBoxStyle" class="svg__edit__wrap">
|
<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" />
|
<img class="edit__model" :src="params.imgUrl" />
|
||||||
</div>
|
</div>
|
||||||
<div :style="{ transform: params.flip ? `rotate${params.flip}(180deg)` : undefined, borderRadius: params.radius + 'px', '-webkit-mask-image': `${params.mask ? `url('${params.mask}')` : undefined}` }" :class="['img__box', { mask: params.mask }]">
|
<div :style="{ transform: params.flip ? `rotate${params.flip}(180deg)` : undefined, borderRadius: params.radius + 'px', '-webkit-mask-image': `${params.mask ? `url('${params.mask}')` : undefined}` }" :class="['img__box', { mask: params.mask }]">
|
||||||
<div v-if="params.isNinePatch" ref="target" class="target" :style="{ border: `${(params.height * params.sliceData.ratio) / 2}px solid transparent`, borderImage: `url('${params.imgUrl}') ${params.sliceData.left} round` }"></div>
|
<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="target" class="target" style="transform-origin: center" :src="params.imgUrl" />
|
<img v-else ref="targetRef" class="target" style="transform-origin: center" :src="params.imgUrl" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isMask" class="drop__mask">
|
<div v-if="isMask" class="drop__mask">
|
||||||
<div putIn="true" :style="{ fontSize: params.width / 12 + 'px' }" class="drop__btn">拖入</div>
|
<div putIn="true" :style="{ fontSize: params.width / 12 + 'px' }" class="drop__btn">拖入</div>
|
||||||
@ -25,90 +31,116 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
// 图片组件
|
// 图片组件
|
||||||
const NAME = 'w-image'
|
// const NAME = 'w-image'
|
||||||
|
import { CSSProperties, StyleValue, computed, nextTick, onBeforeUnmount, onMounted, onUpdated, reactive, ref, watch } from 'vue'
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
import { mapGetters, mapActions, useStore } from 'vuex'
|
||||||
import { getMatrix } from '@/common/methods/handleTransform'
|
import { getMatrix } from '@/common/methods/handleTransform'
|
||||||
|
import setting from "./wImageSetting"
|
||||||
import PointImg from '@/utils/plugins/pointImg'
|
import PointImg from '@/utils/plugins/pointImg'
|
||||||
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useCanvasStore } from '@/pinia'
|
||||||
|
|
||||||
export default {
|
type TProps = {
|
||||||
name: NAME,
|
params: typeof setting
|
||||||
setting: {
|
parent: {
|
||||||
name: '图片',
|
left: number
|
||||||
type: NAME,
|
top: number
|
||||||
uuid: -1,
|
}
|
||||||
width: 300,
|
}
|
||||||
height: 300,
|
|
||||||
left: 0,
|
type TState = {
|
||||||
top: 0,
|
position: 'absolute' | 'relative', // 'absolute'relative
|
||||||
zoom: 1,
|
editBoxStyle: CSSProperties,
|
||||||
transform: '',
|
cropWidgetXY: {
|
||||||
radius: 0,
|
x: number
|
||||||
opacity: 1,
|
y: number
|
||||||
parent: '-1',
|
}
|
||||||
imgUrl: '',
|
holdPosition: {
|
||||||
mask: '',
|
left: number
|
||||||
setting: [],
|
top: number
|
||||||
record: {
|
}
|
||||||
width: 0,
|
}
|
||||||
height: 0,
|
|
||||||
minWidth: 10,
|
const props = defineProps<TProps>()
|
||||||
minHeight: 10,
|
const state = reactive<TState>({
|
||||||
dir: 'all',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
props: ['params', 'parent'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
position: 'absolute', // 'absolute'relative
|
position: 'absolute', // 'absolute'relative
|
||||||
editBoxStyle: {
|
editBoxStyle: {
|
||||||
transformOrigin: 'center',
|
transformOrigin: 'center',
|
||||||
transform: '',
|
transform: '',
|
||||||
},
|
},
|
||||||
|
cropWidgetXY: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
holdPosition: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
computed: {
|
const route = useRoute()
|
||||||
...mapGetters(['dActiveElement', 'dWidgets', 'dZoom', 'dMouseXY', 'dDropOverUuid', 'dCropUuid']),
|
const store = useStore()
|
||||||
cropEdit() {
|
const widgetRef = ref<HTMLElement | null>(null)
|
||||||
return this.params.uuid === this.dCropUuid
|
const targetRef = ref<HTMLImageElement | null>(null)
|
||||||
},
|
|
||||||
tZoom() {
|
|
||||||
return this.params.zoom
|
|
||||||
},
|
|
||||||
isMask() {
|
|
||||||
return this.params.mask && this.dDropOverUuid === this.params.uuid
|
|
||||||
},
|
|
||||||
isDraw() {
|
|
||||||
return this.$route.name === 'Draw'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
cropEdit(val) {
|
|
||||||
// TODO 移动事件绑定
|
|
||||||
if (val) {
|
|
||||||
document.getElementById(this.params.uuid).addEventListener('mousedown', this.touchstart, false)
|
|
||||||
} else {
|
|
||||||
document.getElementById(this.params.uuid).removeEventListener('mousedown', this.touchstart, false)
|
|
||||||
}
|
|
||||||
this.fixRotate()
|
|
||||||
this.lockOthers()
|
|
||||||
},
|
|
||||||
async tZoom() {
|
|
||||||
await this.$nextTick()
|
|
||||||
this.updateRecord()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
updated() {
|
|
||||||
this.updateRecord()
|
|
||||||
this.$store.commit('updateRect')
|
|
||||||
},
|
|
||||||
|
|
||||||
async mounted() {
|
let rotateTemp: number | null = null
|
||||||
this.updateRecord()
|
let flipTemp: string | null = null
|
||||||
await this.$nextTick()
|
let locksTemp: string[] | null = null
|
||||||
document.addEventListener('mouseup', this.touchend, false)
|
|
||||||
|
const {
|
||||||
|
dActiveElement, dWidgets, dMouseXY, dDropOverUuid, dCropUuid
|
||||||
|
} = useSetupMapGetters(['dActiveElement', 'dWidgets', 'dMouseXY', 'dDropOverUuid', 'dCropUuid'])
|
||||||
|
const { dZoom } = storeToRefs(useCanvasStore())
|
||||||
|
|
||||||
|
// ...mapGetters(['dActiveElement', 'dWidgets', 'dZoom', 'dMouseXY', 'dDropOverUuid', 'dCropUuid']),
|
||||||
|
const cropEdit = computed(() => {
|
||||||
|
return props.params.uuid === dCropUuid.value
|
||||||
|
})
|
||||||
|
const tZoom = computed(() => {
|
||||||
|
return props.params.zoom
|
||||||
|
})
|
||||||
|
const isMask = computed(() => {
|
||||||
|
return props.params.mask && dDropOverUuid.value === props.params.uuid
|
||||||
|
})
|
||||||
|
const isDraw = computed(() => {
|
||||||
|
return route.name === 'Draw'
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => cropEdit.value,
|
||||||
|
(val) => {
|
||||||
|
// TODO 移动事件绑定
|
||||||
|
const el = document.getElementById(`${props.params.uuid}`)
|
||||||
|
if (val) {
|
||||||
|
el?.addEventListener('mousedown', touchstart, false)
|
||||||
|
} else {
|
||||||
|
el?.removeEventListener('mousedown', touchstart, false)
|
||||||
|
}
|
||||||
|
fixRotate()
|
||||||
|
lockOthers()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => tZoom.value,
|
||||||
|
async () => {
|
||||||
|
await nextTick()
|
||||||
|
updateRecord()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
updateRecord()
|
||||||
|
store.commit('updateRect')
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
updateRecord()
|
||||||
|
await nextTick()
|
||||||
|
document.addEventListener('mouseup', touchend, false)
|
||||||
// if (this.params.transformData) {
|
// if (this.params.transformData) {
|
||||||
// // this.$refs.widget.style.transform += `scale(${this.params.transformData.a}, ${this.params.transformData.d})`
|
// // this.$refs.widget.style.transform += `scale(${this.params.transformData.a}, ${this.params.transformData.d})`
|
||||||
// this.$refs.widget.style.transform += `matrix(${String(getMatrix(this.params.transformData))})`
|
// this.$refs.widget.style.transform += `matrix(${String(getMatrix(this.params.transformData))})`
|
||||||
@ -118,149 +150,175 @@ export default {
|
|||||||
// }
|
// }
|
||||||
// console.log(this.params, this.params.filter)
|
// console.log(this.params, this.params.filter)
|
||||||
// this.$refs.widget.style.filter = 'hue-rotate(100deg) blur(50px)'
|
// this.$refs.widget.style.filter = 'hue-rotate(100deg) blur(50px)'
|
||||||
this.$refs.widget.style.transform += this.params.rotate && (this.$refs.widget.style.transform += `rotate(${this.params.rotate})`)
|
if (widgetRef.value) {
|
||||||
},
|
widgetRef.value.style.transform += props.params.rotate && (widgetRef.value.style.transform += `rotate(${props.params.rotate})`)
|
||||||
beforeUnmount() {
|
}
|
||||||
document.removeEventListener('mouseup', this.touchend, false)
|
})
|
||||||
},
|
|
||||||
methods: {
|
onBeforeUnmount(() => {
|
||||||
...mapActions(['updateWidgetData']),
|
document.removeEventListener('mouseup', touchend, false)
|
||||||
touchstart(e) {
|
})
|
||||||
const editBox = this.$refs[this.params.uuid + '_ebox']
|
|
||||||
this.cropWidgetXY = {
|
// ...mapActions(['updateWidgetData']),
|
||||||
x: Number(editBox.style.left.replace('px', '')) || 0,
|
function touchstart(e: MouseEvent) {
|
||||||
y: Number(editBox.style.top.replace('px', '')) || 0,
|
// const editBox = this.$refs[props.params.uuid + '_ebox']
|
||||||
|
const editBox = document.getElementById(props.params.uuid + '_ebox')
|
||||||
|
state.cropWidgetXY = {
|
||||||
|
x: Number(editBox?.style.left.replace('px', '')) || 0,
|
||||||
|
y: Number(editBox?.style.top.replace('px', '')) || 0,
|
||||||
}
|
}
|
||||||
// 绑定鼠标移动事件
|
// 绑定鼠标移动事件
|
||||||
document.addEventListener('mousemove', this.handlemousemove, true)
|
document.addEventListener('mousemove', handlemousemove, true)
|
||||||
},
|
}
|
||||||
touchend() {
|
|
||||||
// 取消鼠标移动事件
|
/** 取消鼠标移动事件 */
|
||||||
document.removeEventListener('mousemove', this.handlemousemove, true)
|
function touchend() {
|
||||||
|
document.removeEventListener('mousemove', handlemousemove, true)
|
||||||
// const left = Number(this.editBoxStyle.left.replace('px', ''))
|
// const left = Number(this.editBoxStyle.left.replace('px', ''))
|
||||||
// const flow = (this.params.width * (1 - this.tZoom)) / 2
|
// const flow = (this.params.width * (1 - this.tZoom)) / 2
|
||||||
// if (left + flow < 0) {
|
// if (left + flow < 0) {
|
||||||
// }
|
// }
|
||||||
},
|
}
|
||||||
handlemousemove(e) {
|
|
||||||
if (!this.move(e)) {
|
function handlemousemove(e?: MouseEvent) {
|
||||||
|
if (!move(e)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
e && e.stopPropagation()
|
e && e.stopPropagation()
|
||||||
e && e.preventDefault()
|
e && e.preventDefault()
|
||||||
const { left, top } = this.move(e)
|
const { left, top } = move(e)
|
||||||
// TODO 触发位置刷新
|
// TODO 触发位置刷新
|
||||||
this.holdPosition = { left, top }
|
state.holdPosition = { left, top }
|
||||||
this.editBoxStyle.left = left + 'px'
|
state.editBoxStyle.left = left + 'px'
|
||||||
this.editBoxStyle.top = top + 'px'
|
state.editBoxStyle.top = top + 'px'
|
||||||
this.changeFinish(left / this.params.zoom, top / this.params.zoom)
|
changeFinish(left / props.params.zoom, top / props.params.zoom)
|
||||||
},
|
}
|
||||||
changeFinish(x, y) {
|
|
||||||
this.setTransform('translate', `${x}px, ${y}px`)
|
function changeFinish(x: number, y: number) {
|
||||||
},
|
setTransform('translate', `${x}px, ${y}px`)
|
||||||
move(payload) {
|
}
|
||||||
|
|
||||||
|
function move(payload?: MouseEvent) {
|
||||||
if (payload) {
|
if (payload) {
|
||||||
const widgetXY = { x: this.cropWidgetXY.x, y: this.cropWidgetXY.y }
|
const widgetXY = { x: state.cropWidgetXY.x, y: state.cropWidgetXY.y }
|
||||||
const dx = Number(payload.pageX) - this.dMouseXY.x
|
const dx = Number(payload.pageX) - dMouseXY.value.x
|
||||||
const dy = Number(payload.pageY) - this.dMouseXY.y
|
const dy = Number(payload.pageY) - dMouseXY.value.y
|
||||||
let left = Number(widgetXY.x) + Math.floor((dx * 100) / this.dZoom)
|
let left = Number(widgetXY.x) + Math.floor((dx * 100) / dZoom.value)
|
||||||
let top = Number(widgetXY.y) + Math.floor((dy * 100) / this.dZoom)
|
let top = Number(widgetXY.y) + Math.floor((dy * 100) / dZoom.value)
|
||||||
// TODO: 旋转后计算坐标
|
// TODO: 旋转后计算坐标
|
||||||
// const rotate = Number(this.params.rotate.replace('deg', ''))
|
// const rotate = Number(this.params.rotate.replace('deg', ''))
|
||||||
// console.log(Math.sin(rotate), Math.cos(rotate))
|
// console.log(Math.sin(rotate), Math.cos(rotate))
|
||||||
return { left, top }
|
return { left, top }
|
||||||
} else {
|
} else {
|
||||||
return this.holdPosition
|
return state.holdPosition
|
||||||
}
|
}
|
||||||
},
|
|
||||||
updateRecord() {
|
|
||||||
if (this.dActiveElement.uuid === this.params.uuid) {
|
|
||||||
let record = this.dActiveElement.record
|
|
||||||
record.width = this.$refs.widget.offsetWidth
|
|
||||||
record.height = this.$refs.widget.offsetHeight
|
|
||||||
}
|
}
|
||||||
this.updateZoom()
|
|
||||||
|
function updateRecord() {
|
||||||
|
if (dActiveElement.value.uuid === props.params.uuid) {
|
||||||
|
let record = dActiveElement.value.record
|
||||||
|
if (widgetRef.value) {
|
||||||
|
record.width = widgetRef.value.offsetWidth
|
||||||
|
record.height = widgetRef.value.offsetHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateZoom()
|
||||||
// 获取点位
|
// 获取点位
|
||||||
if (!this.isDraw) {
|
if (!isDraw.value) {
|
||||||
const read = new PointImg(this.$refs.target)
|
if (targetRef.value) {
|
||||||
|
const read = new PointImg(targetRef.value)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
setTransform(attrName, value) {
|
}
|
||||||
const iof = this.params.transform.indexOf(attrName)
|
|
||||||
|
function setTransform(attrName: string, value: string | number) {
|
||||||
|
const iof = props.params.transform.indexOf(attrName)
|
||||||
let setValue = ''
|
let setValue = ''
|
||||||
if (iof != -1) {
|
if (iof != -1) {
|
||||||
const index = iof + attrName.length
|
const index = iof + attrName.length
|
||||||
const tf = this.params.transform
|
const tf = props.params.transform
|
||||||
const FRONT = tf.slice(0, index + 1)
|
const FRONT = tf.slice(0, index + 1)
|
||||||
const half = tf.substring(index + 1)
|
const half = tf.substring(index + 1)
|
||||||
const END = half.substring(half.indexOf(')'))
|
const END = half.substring(half.indexOf(')'))
|
||||||
setValue = FRONT + value + END
|
setValue = FRONT + value + END
|
||||||
} else {
|
} else {
|
||||||
setValue = this.params.transform + ` ${attrName}(${value})`
|
setValue = props.params.transform + ` ${attrName}(${value})`
|
||||||
}
|
}
|
||||||
this.updateWidgetData({
|
store.dispatch("updateWidgetData", {
|
||||||
uuid: this.params.uuid,
|
uuid: props.params.uuid,
|
||||||
key: 'transform',
|
key: 'transform',
|
||||||
value: setValue,
|
value: setValue,
|
||||||
pushHistory: false,
|
pushHistory: false,
|
||||||
})
|
})
|
||||||
this.params.transform && (this.$refs.target.style.transform = this.params.transform)
|
// updateWidgetData({
|
||||||
},
|
// uuid: this.params.uuid,
|
||||||
setEditBox(attrName, value) {
|
// key: 'transform',
|
||||||
const iof = this.editBoxStyle.transform.indexOf(attrName)
|
// value: setValue,
|
||||||
|
// pushHistory: false,
|
||||||
|
// })
|
||||||
|
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)
|
||||||
let setValue = ''
|
let setValue = ''
|
||||||
if (iof != -1) {
|
if (iof != -1 && iof != undefined) {
|
||||||
const index = iof + attrName.length
|
const index = iof + attrName.length
|
||||||
const tf = this.editBoxStyle.transform
|
const tf = state.editBoxStyle.transform ?? ''
|
||||||
const FRONT = tf.slice(0, index + 1)
|
const FRONT = tf.slice(0, index + 1)
|
||||||
const half = tf.substring(index + 1)
|
const half = tf.substring(index + 1)
|
||||||
const END = half.substring(half.indexOf(')'))
|
const END = half.substring(half.indexOf(')'))
|
||||||
setValue = FRONT + value + END
|
setValue = FRONT + value + END
|
||||||
} else {
|
} else {
|
||||||
setValue = this.editBoxStyle.transform + ` ${attrName}(${value})`
|
setValue = state.editBoxStyle.transform + ` ${attrName}(${value})`
|
||||||
}
|
}
|
||||||
this.editBoxStyle.transform = setValue
|
state.editBoxStyle.transform = setValue
|
||||||
},
|
}
|
||||||
updateZoom() {
|
|
||||||
this.setEditBox('scale', this.params.zoom)
|
function updateZoom() {
|
||||||
this.setTransform('scale', this.params.zoom)
|
setEditBox('scale', props.params.zoom)
|
||||||
|
setTransform('scale', props.params.zoom)
|
||||||
// this.$refs.target.style.transform = this.params.transform
|
// this.$refs.target.style.transform = this.params.transform
|
||||||
this.handlemousemove()
|
handlemousemove()
|
||||||
},
|
}
|
||||||
fixRotate() {
|
|
||||||
|
function fixRotate() {
|
||||||
// 裁切时修正角度
|
// 裁切时修正角度
|
||||||
if (this.rotateTemp) {
|
if (rotateTemp) {
|
||||||
this.$refs.widget.style.transform = `rotate(${this.rotateTemp})`
|
widgetRef.value && (widgetRef.value.style.transform = `rotate(${rotateTemp})`)
|
||||||
this.params.flip = this.flipTemp
|
props.params.flip = flipTemp
|
||||||
this.rotateTemp = null
|
rotateTemp = null
|
||||||
} else {
|
} else {
|
||||||
this.rotateTemp = this.params.rotate
|
rotateTemp = props.params.rotate
|
||||||
this.$refs.widget.style.transform = `rotate(0deg)`
|
widgetRef.value && (widgetRef.value.style.transform = `rotate(0deg)`)
|
||||||
this.flipTemp = this.params.flip
|
flipTemp = props.params.flip
|
||||||
this.params.flip = null
|
props.params.flip = null
|
||||||
}
|
}
|
||||||
this.$store.commit('setShowMoveable', false)
|
store.commit('setShowMoveable', false)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$store.commit('setShowMoveable', true)
|
store.commit('setShowMoveable', true)
|
||||||
}, 100)
|
}, 100)
|
||||||
},
|
}
|
||||||
lockOthers() {
|
|
||||||
|
function lockOthers() {
|
||||||
// 裁剪时锁定其他图层
|
// 裁剪时锁定其他图层
|
||||||
if (this.locksTemp && this.locksTemp.length > 0) {
|
if (locksTemp && locksTemp.length > 0) {
|
||||||
for (let i = 0; i < this.locksTemp.length; i++) {
|
for (let i = 0; i < locksTemp.length; i++) {
|
||||||
this.dWidgets[i].lock = this.locksTemp[i]
|
dWidgets.value[i].lock = locksTemp[i]
|
||||||
}
|
}
|
||||||
this.locksTemp = []
|
locksTemp = []
|
||||||
} else {
|
} else {
|
||||||
this.locksTemp = []
|
locksTemp = []
|
||||||
for (const widget of this.dWidgets) {
|
for (const widget of dWidgets.value) {
|
||||||
this.locksTemp.push(widget.lock)
|
locksTemp.push(widget.lock)
|
||||||
}
|
}
|
||||||
this.dWidgets.forEach((widget) => {
|
dWidgets.value.forEach((widget: any) => {
|
||||||
widget.uuid != this.params.uuid && (widget.lock = true)
|
widget.uuid != props.params.uuid && (widget.lock = true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
// cropDone(e) {
|
// cropDone(e) {
|
||||||
// e.stopPropagation()
|
// e.stopPropagation()
|
||||||
// e.preventDefault()
|
// e.preventDefault()
|
||||||
@ -271,8 +329,6 @@ export default {
|
|||||||
// pushHistory: false,
|
// pushHistory: false,
|
||||||
// })
|
// })
|
||||||
// },
|
// },
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
67
src/components/modules/widgets/wImage/wImageSetting.ts
Normal file
67
src/components/modules/widgets/wImage/wImageSetting.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
export type TImageSetting = {
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
uuid: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
left: number
|
||||||
|
top: number
|
||||||
|
zoom: number
|
||||||
|
transform: string
|
||||||
|
radius: number
|
||||||
|
opacity: number
|
||||||
|
parent: string
|
||||||
|
imgUrl: string
|
||||||
|
mask: string
|
||||||
|
setting: [],
|
||||||
|
rotate: number
|
||||||
|
record: {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
minWidth: number
|
||||||
|
minHeight: number
|
||||||
|
dir: string
|
||||||
|
},
|
||||||
|
lock: false,
|
||||||
|
isNinePatch: false,
|
||||||
|
flip: string | null
|
||||||
|
sliceData: {
|
||||||
|
ratio: number
|
||||||
|
left: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setting: TImageSetting = {
|
||||||
|
name: '图片',
|
||||||
|
type: 'w-image',
|
||||||
|
uuid: '-1',
|
||||||
|
width: 300,
|
||||||
|
height: 300,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
zoom: 1,
|
||||||
|
transform: '',
|
||||||
|
radius: 0,
|
||||||
|
opacity: 1,
|
||||||
|
parent: '-1',
|
||||||
|
imgUrl: '',
|
||||||
|
mask: '',
|
||||||
|
setting: [],
|
||||||
|
rotate: 0,
|
||||||
|
record: {
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
minWidth: 10,
|
||||||
|
minHeight: 10,
|
||||||
|
dir: 'all',
|
||||||
|
},
|
||||||
|
lock: false,
|
||||||
|
isNinePatch: false,
|
||||||
|
flip: '',
|
||||||
|
sliceData: {
|
||||||
|
ratio: 0,
|
||||||
|
left: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default setting
|
@ -62,7 +62,7 @@ const props = defineProps<TProps>()
|
|||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
qrCodeOptions: {}
|
qrCodeOptions: {}
|
||||||
})
|
})
|
||||||
const { dActiveElement, dZoom } = useSetupMapGetters(['dActiveElement', 'dZoom'])
|
const { dActiveElement } = useSetupMapGetters(['dActiveElement'])
|
||||||
const width = computed(() => Number(props.params.width))
|
const width = computed(() => Number(props.params.width))
|
||||||
const widgetRef = ref<HTMLElement | null>(null)
|
const widgetRef = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ import api from '@/api'
|
|||||||
import Qiniu from '@/common/methods/QiNiu'
|
import Qiniu from '@/common/methods/QiNiu'
|
||||||
import _config from '@/config'
|
import _config from '@/config'
|
||||||
import { getImage } from '@/common/methods/getImgDetail'
|
import { getImage } from '@/common/methods/getImgDetail'
|
||||||
import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
// import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
||||||
|
import wImageSetting from '@/components/modules/widgets/wImage/wImageSetting'
|
||||||
import { wTextSetting } from '@/components/modules/widgets/wText/wTextSetting'
|
import { wTextSetting } from '@/components/modules/widgets/wText/wTextSetting'
|
||||||
import eventBus from '@/utils/plugins/eventBus'
|
import eventBus from '@/utils/plugins/eventBus'
|
||||||
import { usePageStore } from '@/pinia'
|
import { usePageStore } from '@/pinia'
|
||||||
@ -45,7 +46,7 @@ export default () => {
|
|||||||
eventBus.emit('refreshUserImages')
|
eventBus.emit('refreshUserImages')
|
||||||
// 添加图片到画布中
|
// 添加图片到画布中
|
||||||
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
||||||
const setting = JSON.parse(JSON.stringify(wImage.setting))
|
const setting = JSON.parse(JSON.stringify(wImageSetting))
|
||||||
setting.width = width
|
setting.width = width
|
||||||
setting.height = height
|
setting.height = height
|
||||||
setting.imgUrl = url
|
setting.imgUrl = url
|
||||||
|
96
src/pinia/design/canvas/index.ts
Normal file
96
src/pinia/design/canvas/index.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
type TScreeData = {
|
||||||
|
/** 记录编辑界面的宽度 */
|
||||||
|
width: number
|
||||||
|
/** 记录编辑界面的高度 */
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type TGuidelinesData = {
|
||||||
|
verticalGuidelines: number[]
|
||||||
|
horizontalGuidelines: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type TCanvasStore = {
|
||||||
|
/** 画布缩放百分比 */
|
||||||
|
dZoom: number
|
||||||
|
/** 画布垂直居中修正值 */
|
||||||
|
dPaddingTop: number
|
||||||
|
/** 编辑界面 */
|
||||||
|
dScreen: TScreeData
|
||||||
|
/** 标尺辅助线 */
|
||||||
|
guidelines: TGuidelinesData
|
||||||
|
}
|
||||||
|
|
||||||
|
type TStoreGetter = {
|
||||||
|
dZoom: (state: TCanvasStore) => number
|
||||||
|
dPaddingTop: (state: TCanvasStore) => number
|
||||||
|
dScreen: (state: TCanvasStore) => TScreeData
|
||||||
|
guidelines: (state: TCanvasStore) => TGuidelinesData
|
||||||
|
}
|
||||||
|
|
||||||
|
type TStoreAction = {
|
||||||
|
/** 更新画布缩放百分比 */
|
||||||
|
updateZoom: (zoom: number) => void
|
||||||
|
/** 更新画布垂直居中修正值 */
|
||||||
|
updatePaddingTop: (num: number) => void
|
||||||
|
/** 更新编辑界面的宽高 */
|
||||||
|
updateScreen: (data: TScreeData) => void
|
||||||
|
/** 修改标尺线 */
|
||||||
|
updateGuidelines: (lines: TGuidelinesData) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineStore<"canvasStore", TCanvasStore, TStoreGetter, TStoreAction>("canvasStore", {
|
||||||
|
state: () => ({
|
||||||
|
dZoom: 0, // 画布缩放百分比
|
||||||
|
dPaddingTop: 0, // 画布垂直居中修正值
|
||||||
|
dScreen: {
|
||||||
|
width: 0, // 记录编辑界面的宽度
|
||||||
|
height: 0, // 记录编辑界面的高度
|
||||||
|
},
|
||||||
|
// gridSize: {
|
||||||
|
// width: 0, // 网格小格子的宽度
|
||||||
|
// height: 0, // 网格小格子的高度
|
||||||
|
// },
|
||||||
|
guidelines: {
|
||||||
|
// moveable 标尺辅助线
|
||||||
|
verticalGuidelines: [],
|
||||||
|
horizontalGuidelines: [],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
dZoom: state => state.dZoom,
|
||||||
|
dPaddingTop: state => state.dPaddingTop,
|
||||||
|
dScreen: state => state.dScreen,
|
||||||
|
guidelines: state => state.guidelines
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
/** 更新画布缩放百分比 */
|
||||||
|
updateZoom(zoom: number) {
|
||||||
|
this.dZoom = zoom
|
||||||
|
},
|
||||||
|
/** 更新画布垂直居中修正值 */
|
||||||
|
updatePaddingTop(num: number) {
|
||||||
|
this.dPaddingTop = num
|
||||||
|
},
|
||||||
|
/** 更新编辑界面的宽高 */
|
||||||
|
updateScreen({ width, height }: TScreeData) {
|
||||||
|
this.dScreen.width = width
|
||||||
|
this.dScreen.height = height
|
||||||
|
},
|
||||||
|
/** 修改标尺线 */
|
||||||
|
updateGuidelines(lines: TGuidelinesData) {
|
||||||
|
this.guidelines = { ...this.guidelines, ...lines }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* @Author: Jeremy Yu
|
||||||
|
* @Date: 2024-03-18 21:00:00
|
||||||
|
* @Description: Page全局配置
|
||||||
|
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||||
|
* @LastEditTime: 2024-03-18 21:00:00
|
||||||
|
*/
|
||||||
|
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export type TPageStore = {
|
export type TPageStore = {
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
import useBaseStore from "./base";
|
import useBaseStore from "./base";
|
||||||
import useUserStore from "./base/user";
|
import useUserStore from "./base/user";
|
||||||
import usePageStore from "./design/page/index"
|
import usePageStore from "./design/page"
|
||||||
|
import useCanvasStore from "./design/canvas"
|
||||||
|
|
||||||
export {
|
export {
|
||||||
useBaseStore,
|
useBaseStore,
|
||||||
useUserStore,
|
useUserStore,
|
||||||
usePageStore,
|
usePageStore,
|
||||||
|
useCanvasStore,
|
||||||
}
|
}
|
||||||
|
@ -23,25 +23,29 @@ export default {
|
|||||||
// 激活组件默认为page
|
// 激活组件默认为page
|
||||||
store.state.dActiveElement = store.state.dPage
|
store.state.dActiveElement = store.state.dPage
|
||||||
},
|
},
|
||||||
updateZoom(store, zoom) {
|
|
||||||
store.state.dZoom = zoom
|
// updateZoom(store, zoom) {
|
||||||
},
|
// store.state.dZoom = zoom
|
||||||
updateScreen(store, { width, height }) {
|
// },
|
||||||
store.state.dScreen.width = width
|
// updateScreen(store, { width, height }) {
|
||||||
store.state.dScreen.height = height
|
// store.state.dScreen.width = width
|
||||||
},
|
// store.state.dScreen.height = height
|
||||||
|
// },
|
||||||
|
|
||||||
// updateGridSize(store, { width, height }) {
|
// updateGridSize(store, { width, height }) {
|
||||||
// store.state.gridSize.width = width
|
// store.state.gridSize.width = width
|
||||||
// store.state.gridSize.height = height
|
// store.state.gridSize.height = height
|
||||||
// },
|
// },
|
||||||
updatePageData(store, { key, value, pushHistory }) {
|
|
||||||
const page = store.state.dPage
|
// updatePageData(store, { key, value, pushHistory }) {
|
||||||
if (page[key] !== value || pushHistory) {
|
// const page = store.state.dPage
|
||||||
page[key] = value
|
// if (page[key] !== value || pushHistory) {
|
||||||
// 画布修改先不压入历史栈,因为替换模板后会重复压栈
|
// page[key] = value
|
||||||
// store.dispatch('pushHistory', 'updatePageData')
|
// // 画布修改先不压入历史栈,因为替换模板后会重复压栈
|
||||||
}
|
// // store.dispatch('pushHistory', 'updatePageData')
|
||||||
},
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
updateWidgetData(store, { uuid, key, value, pushHistory }: any) {
|
updateWidgetData(store, { uuid, key, value, pushHistory }: any) {
|
||||||
const widget = store.state.dWidgets.find((item) => item.uuid === uuid)
|
const widget = store.state.dWidgets.find((item) => item.uuid === uuid)
|
||||||
if (widget && (widget[key] !== value || pushHistory)) {
|
if (widget && (widget[key] !== value || pushHistory)) {
|
||||||
|
@ -2,12 +2,12 @@ import mutations from './mutations'
|
|||||||
import actions from './actions'
|
import actions from './actions'
|
||||||
const all = {
|
const all = {
|
||||||
state: {
|
state: {
|
||||||
dZoom: 0, // 画布缩放百分比
|
// dZoom: 0, // 画布缩放百分比
|
||||||
dPaddingTop: 0, // 画布垂直居中修正值
|
// dPaddingTop: 0, // 画布垂直居中修正值
|
||||||
dScreen: {
|
// dScreen: {
|
||||||
width: 0, // 记录编辑界面的宽度
|
// width: 0, // 记录编辑界面的宽度
|
||||||
height: 0, // 记录编辑界面的高度
|
// height: 0, // 记录编辑界面的高度
|
||||||
},
|
// },
|
||||||
// gridSize: {
|
// gridSize: {
|
||||||
// width: 0, // 网格小格子的宽度
|
// width: 0, // 网格小格子的宽度
|
||||||
// height: 0, // 网格小格子的高度
|
// height: 0, // 网格小格子的高度
|
||||||
@ -38,28 +38,28 @@ const all = {
|
|||||||
dCopyElement: [], // 复制的组件(可能是单个也可能是数组)
|
dCopyElement: [], // 复制的组件(可能是单个也可能是数组)
|
||||||
dHoverUuid: '-1', // 鼠标在这个图层上
|
dHoverUuid: '-1', // 鼠标在这个图层上
|
||||||
dDropOverUuid: '', // 拖动时放在哪个图层上
|
dDropOverUuid: '', // 拖动时放在哪个图层上
|
||||||
dPage: {
|
// dPage: {
|
||||||
name: '背景页面',
|
// name: '背景页面',
|
||||||
type: 'page',
|
// type: 'page',
|
||||||
uuid: '-1',
|
// uuid: '-1',
|
||||||
left: 0,
|
// left: 0,
|
||||||
top: 0,
|
// top: 0,
|
||||||
width: 1920, // 画布宽度
|
// width: 1920, // 画布宽度
|
||||||
height: 1080, // 画布高度
|
// height: 1080, // 画布高度
|
||||||
backgroundColor: '#ffffff', // 画布背景颜色
|
// backgroundColor: '#ffffff', // 画布背景颜色
|
||||||
backgroundImage: '', // 画布背景图片
|
// backgroundImage: '', // 画布背景图片
|
||||||
backgroundTransform: {},
|
// backgroundTransform: {},
|
||||||
opacity: 1, // 透明度
|
// opacity: 1, // 透明度
|
||||||
tag: 0, // 强制刷新用
|
// tag: 0, // 强制刷新用
|
||||||
setting: [
|
// setting: [
|
||||||
{
|
// {
|
||||||
label: '背景颜色',
|
// label: '背景颜色',
|
||||||
parentKey: 'backgroundColor',
|
// parentKey: 'backgroundColor',
|
||||||
value: false,
|
// value: false,
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
record: {},
|
// record: {},
|
||||||
},
|
// },
|
||||||
dWidgets: [], // 已使用的组件
|
dWidgets: [], // 已使用的组件
|
||||||
dHistory: [], // 记录历史操作(保存整个画布的json数据)
|
dHistory: [], // 记录历史操作(保存整个画布的json数据)
|
||||||
dActiveUuidHistory: [], // 记录历史操作对应的激活的组件的uuid
|
dActiveUuidHistory: [], // 记录历史操作对应的激活的组件的uuid
|
||||||
@ -87,15 +87,15 @@ const all = {
|
|||||||
selectItem(state: any) {
|
selectItem(state: any) {
|
||||||
return state.selectItem
|
return state.selectItem
|
||||||
},
|
},
|
||||||
dZoom(state) {
|
// dZoom(state) {
|
||||||
return state.dZoom
|
// return state.dZoom
|
||||||
},
|
// },
|
||||||
dPaddingTop(state: any) {
|
// dPaddingTop(state: any) {
|
||||||
return state.dPaddingTop
|
// return state.dPaddingTop
|
||||||
},
|
// },
|
||||||
dScreen(state) {
|
// dScreen(state) {
|
||||||
return state.dScreen
|
// return state.dScreen
|
||||||
},
|
// },
|
||||||
// gridSize(state) {
|
// gridSize(state) {
|
||||||
// return state.gridSize
|
// return state.gridSize
|
||||||
// },
|
// },
|
||||||
@ -114,9 +114,9 @@ const all = {
|
|||||||
dActiveElement(state) {
|
dActiveElement(state) {
|
||||||
return state.dActiveElement
|
return state.dActiveElement
|
||||||
},
|
},
|
||||||
dPage(state) {
|
// dPage(state) {
|
||||||
return state.dPage
|
// return state.dPage
|
||||||
},
|
// },
|
||||||
dWidgets(state) {
|
dWidgets(state) {
|
||||||
return state.dWidgets
|
return state.dWidgets
|
||||||
},
|
},
|
||||||
|
@ -13,9 +13,9 @@ interface Iprops {
|
|||||||
state: {}
|
state: {}
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
updatePaddingTop(state: Type.Object, num: number) {
|
// updatePaddingTop(state: Type.Object, num: number) {
|
||||||
state.dPaddingTop = num
|
// state.dPaddingTop = num
|
||||||
},
|
// },
|
||||||
selectItem(state: Type.Object, { data, type }: any) {
|
selectItem(state: Type.Object, { data, type }: any) {
|
||||||
state.selectItem.data = data
|
state.selectItem.data = data
|
||||||
state.selectItem.type = type
|
state.selectItem.type = type
|
||||||
@ -36,9 +36,11 @@ export default {
|
|||||||
setDWidgets(state: Type.Object, e: any) {
|
setDWidgets(state: Type.Object, e: any) {
|
||||||
state.dWidgets = e
|
state.dWidgets = e
|
||||||
},
|
},
|
||||||
setDPage(state: Type.Object, e: any) {
|
|
||||||
state.dPage = e
|
// setDPage(state: Type.Object, e: any) {
|
||||||
},
|
// state.dPage = e
|
||||||
|
// },
|
||||||
|
|
||||||
setShowMoveable(state: Type.Object, show: any) {
|
setShowMoveable(state: Type.Object, show: any) {
|
||||||
state.showMoveable = show
|
state.showMoveable = show
|
||||||
// if (!show) {
|
// if (!show) {
|
||||||
@ -61,10 +63,10 @@ export default {
|
|||||||
// 强制触发元素选择
|
// 强制触发元素选择
|
||||||
state.updateSelect = Math.random()
|
state.updateSelect = Math.random()
|
||||||
},
|
},
|
||||||
updateGuidelines(state: Type.Object, lines: any) {
|
// updateGuidelines(state: Type.Object, lines: any) {
|
||||||
// 修改标尺线
|
// // 修改标尺线
|
||||||
state.guidelines = { ...state.guidelines, ...lines }
|
// state.guidelines = { ...state.guidelines, ...lines }
|
||||||
},
|
// },
|
||||||
setCropUuid(state: Type.Object, uuid: any) {
|
setCropUuid(state: Type.Object, uuid: any) {
|
||||||
// 设置正在裁剪or编辑的组件
|
// 设置正在裁剪or编辑的组件
|
||||||
state.dCropUuid = uuid
|
state.dCropUuid = uuid
|
||||||
|
@ -74,7 +74,7 @@ import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { usePageStore } from '@/pinia'
|
import { useCanvasStore, usePageStore } from '@/pinia'
|
||||||
|
|
||||||
type TState = {
|
type TState = {
|
||||||
style: CSSProperties
|
style: CSSProperties
|
||||||
@ -96,9 +96,10 @@ const beforeUnload = function (e: Event): string {
|
|||||||
!_config.isDev && window.addEventListener('beforeunload', beforeUnload)
|
!_config.isDev && window.addEventListener('beforeunload', beforeUnload)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
dActiveElement, dHistoryParams, dCopyElement, dZoom
|
dActiveElement, dHistoryParams, dCopyElement
|
||||||
} = useSetupMapGetters(['dActiveElement', 'dHistoryParams', 'dCopyElement', 'dZoom'])
|
} = useSetupMapGetters(['dActiveElement', 'dHistoryParams', 'dCopyElement'])
|
||||||
const { dPage } = storeToRefs(usePageStore())
|
const { dPage } = storeToRefs(usePageStore())
|
||||||
|
const { dZoom } = storeToRefs(useCanvasStore())
|
||||||
|
|
||||||
|
|
||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
|
@ -61,7 +61,8 @@ import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue'
|
|||||||
import Moveable from '@/components/business/moveable/Moveable.vue'
|
import Moveable from '@/components/business/moveable/Moveable.vue'
|
||||||
import shortcuts from '@/mixins/shortcuts'
|
import shortcuts from '@/mixins/shortcuts'
|
||||||
// import wText from '@/components/modules/widgets/wText/wText.vue'
|
// import wText from '@/components/modules/widgets/wText/wText.vue'
|
||||||
import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
// import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
||||||
|
import wImageSetting from '@/components/modules/widgets/wImage/wImageSetting'
|
||||||
import useLoading from '@/common/methods/loading'
|
import useLoading from '@/common/methods/loading'
|
||||||
import uploader from '@/components/common/Uploader/index.vue'
|
import uploader from '@/components/common/Uploader/index.vue'
|
||||||
import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
import designBoard from '@/components/modules/layout/designBoard/index.vue'
|
||||||
@ -72,7 +73,7 @@ import ProgressLoading from '@/components/common/ProgressLoading/index.vue'
|
|||||||
import { processPSD2Page } from '@/utils/plugins/psd'
|
import { processPSD2Page } from '@/utils/plugins/psd'
|
||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
import { wTextSetting } from '@/components/modules/widgets/wText/wTextSetting'
|
import { wTextSetting } from '@/components/modules/widgets/wText/wTextSetting'
|
||||||
import { usePageStore } from '@/pinia'
|
import { useCanvasStore, usePageStore } from '@/pinia'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
type TState = {
|
type TState = {
|
||||||
@ -94,9 +95,10 @@ const state = reactive<TState>({
|
|||||||
const store = useStore()
|
const store = useStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const { dZoom } = useSetupMapGetters(['dZoom'])
|
// const { dZoom } = useSetupMapGetters(['dZoom'])
|
||||||
const pageStore = usePageStore()
|
const pageStore = usePageStore()
|
||||||
const { dPage } = storeToRefs(pageStore)
|
const { dPage } = storeToRefs(pageStore)
|
||||||
|
const { dZoom } = storeToRefs(useCanvasStore())
|
||||||
|
|
||||||
const zoomControlRef = ref<typeof zoomControl | null>()
|
const zoomControlRef = ref<typeof zoomControl | null>()
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ async function loadPSD(file: File) {
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const types: any = {
|
const types: any = {
|
||||||
text: wTextSetting,
|
text: wTextSetting,
|
||||||
image: wImage.setting,
|
image: wImageSetting,
|
||||||
}
|
}
|
||||||
for (let i = 0; i < data.clouds.length; i++) {
|
for (let i = 0; i < data.clouds.length; i++) {
|
||||||
const x: any = data.clouds[i]
|
const x: any = data.clouds[i]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user