Merge: main branch

This commit is contained in:
IchliebedichZhu 2024-03-27 22:24:27 +00:00
commit 503e182172
17 changed files with 450 additions and 466 deletions

View File

@ -13,7 +13,7 @@
### 特点 ### 特点
- 丝滑的页面操作体验,丰富的交互细节,基础功能完善 - 丝滑的页面操作体验,丰富的交互细节,基础功能完善
- 采用服务端生成图片,能确保多端出图统一性,支持各种 CSS 特性 - 采用服务端生成图片,确保多端出图统一性,支持各种 HTML5 特性
- 简易 AI 抠图工具,上传图片一键去除背景 - 简易 AI 抠图工具,上传图片一键去除背景
- 技术栈Vue3 、Vite5 、Vuex 、ElementPlus开发体验畅快 - 技术栈Vue3 、Vite5 、Vuex 、ElementPlus开发体验畅快
- 图片生成Puppeteer、Express - 图片生成Puppeteer、Express
@ -54,13 +54,9 @@ npm run dev
后端需要自己开发,目前本项目演示 Demo 中的后端接口参考:[接口 API 文档](https://xp.palxp.cn/apidoc/index.html)。 后端需要自己开发,目前本项目演示 Demo 中的后端接口参考:[接口 API 文档](https://xp.palxp.cn/apidoc/index.html)。
## 其它 ## 交流群
我们尝试沉淀一个高质量内容社区,形成可持续学习的平台,同时解决开发者在项目中遇到的疑难和困惑,帮大家少走一些弯路。 关注公众号:品味前端,回复 “加群” 获取二维码,更新公告不错过。
<img style="width: 380px;" src="https://github.com/palxiao/poster-design/assets/21021314/643dcc8b-ef73-4c76-a78c-a7c377b5f268" />
也欢迎关注公众号:品味前端,回复“加群”进行交流。
<img style="width: 380px;" src="https://xp.palxp.cn/images/2024-3-1-1709306365949.png" /> <img style="width: 380px;" src="https://xp.palxp.cn/images/2024-3-1-1709306365949.png" />

View File

@ -1,16 +1,14 @@
@import './color.less'; @import './color.less';
// design index page // design index page
// Color variables (appears count calculates by raw css) @color4: #50555b;
@color4: #50555b; // Appears 2 times @color5: #808080;
@color5: #808080; // Appears 2 times
// Width variables (appears count calculates by raw css) @width0: 1180px;
@width0: 1180px; // Appears 3 times @width1: 120px;
@width1: 120px; // Appears 2 times @width2: 100%;
@width2: 100%; // Appears 8 times
@height2: 54px; // Appears 5 times @height2: 54px;
.page-design-bg-color { .page-design-bg-color {
// background-color: #4b678c; // background-color: #4b678c;

View File

@ -9,41 +9,32 @@
<div id="empty" class="moveable__remove-item zk-moveable-style"></div> <div id="empty" class="moveable__remove-item zk-moveable-style"></div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Events, defineComponent, nextTick, onMounted, watch } from 'vue' import { defineComponent, nextTick, onMounted, watch } from 'vue'
import Moveable, { EVENTS, OnRotate, WithEventStop } from 'moveable' // PROPERTIES, METHODS, import Moveable, { EVENTS } from 'moveable' // PROPERTIES, METHODS,
import MoveableHelper from 'moveable-helper' import MoveableHelper from 'moveable-helper'
import { mapGetters, mapActions, useStore } from 'vuex' import { mapGetters, mapActions, useStore } from 'vuex'
// import { setTransformAttribute } from '@/common/methods/handleTransform' // import { setTransformAttribute } from '@/common/methods/handleTransform'
import useSelecto from './Selecto' import useSelecto from './Selecto'
import { useSetupMapGetters } from '@/common/hooks/mapGetters' import { useSetupMapGetters } from '@/common/hooks/mapGetters'
import { storeToRefs } from 'pinia'
import { useCanvasStore, useControlStore } from '@/pinia'
const {
dSelectWidgets, dActiveElement, activeMouseEvent,
dWidgets,
updateRect, updateSelect,
} = useSetupMapGetters(['dSelectWidgets', 'dActiveElement', 'activeMouseEvent', 'dWidgets', 'updateRect', 'updateSelect'])
const store = useStore() const store = useStore()
const controlStore = useControlStore() // computed: mapGetters(['dSelectWidgets', 'dActiveElement', 'activeMouseEvent', 'showMoveable', 'showRotatable', 'dWidgets', 'updateRect', 'updateSelect', 'guidelines']),
const { guidelines } = storeToRefs(useCanvasStore()) const {
const { showMoveable, showRotatable } = storeToRefs(controlStore) dSelectWidgets, dActiveElement, activeMouseEvent, showMoveable, showRotatable, dWidgets, updateRect, updateSelect, guidelines
// computed: mapGetters(['dSelectWidgets', 'dActiveElement', 'activeMouseEvent', 'showMoveable', 'showRotatable', 'dWidgets', 'updateRect', 'updateSelect', 'guidelines']) } = useSetupMapGetters(['dSelectWidgets', 'dActiveElement', 'activeMouseEvent', 'showMoveable', 'showRotatable', 'dWidgets', 'updateRect', 'updateSelect', 'guidelines'])
let _target: string = "" let _target: string | null = null
let moveable: Moveable | null = null
let holdPosition: { left: number, top: number } | null = null
let startHL: number = 0
let startLS: number = 0
let resetRatio: number = 0
let resizeTempData: { width: number, height: number } | null = null
watch( watch(
() => dActiveElement.value, () => dActiveElement.value,
async (val) => { async (val) => {
setTimeout(async () => {
await nextTick()
checkMouseEvent()
}, 10);
if (!val.record) { if (!val.record) {
return return
} }
@ -73,19 +64,13 @@ watch(
// // Set Move Auto // // Set Move Auto
moveable.setState({ target: _target }, () => { moveable.setState({ target: _target }, () => {
// mouseevent // mouseevent
if (activeMouseEvent.value) { checkMouseEvent()
moveable?.dragStart(activeMouseEvent.value)
// TODO 使mouseevent
store.commit('setMouseEvent', null)
}
}) })
// // End // // End
// controlStore.setShowMoveable(true) store.commit('setShowMoveable', true)
controlStore.setShowMoveable(true)
// 线 // 线
if (!moveable.elementGuidelines?.includes(target)) { if (moveable.elementGuidelines && !moveable.elementGuidelines.includes(target)) {
moveable.elementGuidelines?.push(target) moveable.elementGuidelines.push(target)
} }
} else { } else {
moveable.target = `[id="empty"]` moveable.target = `[id="empty"]`
@ -96,43 +81,42 @@ watch(
}, 210) }, 210)
} }
// feature: 线 // feature: 线
if (moveable.elementGuidelines) { moveable.elementGuidelines && (moveable.elementGuidelines.length = 0)
moveable.elementGuidelines.length = 0
}
} }
} }
) )
watch( watch(
() => showMoveable.value, () => showMoveable.value,
val => { (val) => {
if (!moveable) return if (!moveable) return
if (val) { if (val) {
moveable.target = _target moveable.target = _target
} else { } else {
moveable.target = `[id="empty"]` moveable.target = `[id="empty"]`
} }
} }
) )
watch( watch(
() => showRotatable.value, () => showRotatable.value,
val => { (val) => {
// TODO:
if (!moveable) return if (!moveable) return
// TODO:
moveable.renderDirections = val ? ['nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se'] : [] moveable.renderDirections = val ? ['nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se'] : []
moveable.resizable = val moveable.resizable = val
moveable.scalable = val // this.moveable.scalable = val
const el = document.getElementsByClassName('moveable-rotation')[0] as HTMLElement const el = document.getElementsByClassName('moveable-rotation')
el.style.display = val ? 'block' : 'none' if (el && el[0]) {
(el[0] as HTMLElement).style.display = val ? 'block' : 'none'
}
} }
) )
watch( watch(
() => updateRect.value, () => updateRect.value,
() => { () => {
moveable?.updateRect() moveable && moveable.updateRect()
} }
) )
@ -146,7 +130,6 @@ watch(
await nextTick() await nextTick()
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
console.log(items[i].uuid) console.log(items[i].uuid)
document.getElementById(items[i].uuid)?.classList.add('widget-selected') document.getElementById(items[i].uuid)?.classList.add('widget-selected')
} }
moveable.renderDirections = [] moveable.renderDirections = []
@ -199,9 +182,57 @@ watch(
} }
) )
type TMoveableOptions = {
target: HTMLElement | null
container?: HTMLElement | null
zoom: number
draggable: boolean
clippable: boolean //
throttleDrag: number
resizable: boolean
throttleResize: number
scalable: boolean
throttleScale: number
keepRatio: boolean
rotatable: boolean
throttleRotate: number
renderDirections: string[] // ['nw', 'ne', 'sw', 'se'] // 'e'
pinchable: boolean // ["draggable", "resizable", "scalable", "rotatable"]
origin: boolean
defaultGroupOrigin: string,
/* 样式相关 */
rotationPosition: 'bottom',
className: 'zk-moveable-style',
/* -- 吸附对齐 Start -- */
snappable: boolean,
elementGuidelines: [],
verticalGuidelines: [],
horizontalGuidelines: [],
snapThreshold: 4,
isDisplaySnapDigit: boolean,
snapGap: boolean,
snapElement: boolean,
snapVertical: boolean,
snapHorizontal: boolean,
snapCenter: boolean,
snapDigit: number
// snapDirections={{"top":true,"right":true,"bottom":true,"left":true}}
// elementSnapDirections={{}}
// -- END --
triggerAblesSimultaneously: true,
}
let moveable: Moveable | null = null
let holdPosition: { left: number, top: number } | null = null
let startHL: number = 0
let startLS: number = 0
let resetRatio: number = 0
let resizeTempData: { width: number, height: number } | null = null
onMounted(() => { onMounted(() => {
let holdGroupPosition: Record<string, any> | null = null let holdGroupPosition: Record<string, any> | null = null
const moveableOptions: any = { const moveableOptions: TMoveableOptions = {
target: document.querySelector(`[id="empty"]`), target: document.querySelector(`[id="empty"]`),
// container: document.querySelector('#page-design'), // container: document.querySelector('#page-design'),
zoom: 0.8, zoom: 0.8,
@ -241,356 +272,339 @@ onMounted(() => {
// -- END -- // -- END --
triggerAblesSimultaneously: true, triggerAblesSimultaneously: true,
} }
const moveableInstance = new Moveable(document.body, moveableOptions)
moveable = moveableInstance
const helper: any = new MoveableHelper() moveable = new Moveable(document.body, moveableOptions)
const helper = new MoveableHelper()
EVENTS.forEach((event) => { EVENTS.forEach((event) => {
let helperEvent = event.replace(event[0], 'on' + event[0].toUpperCase()) let helperEvent = (event.replace(event[0], 'on' + event[0].toUpperCase()) as keyof MoveableHelper)
// console.log(event) // console.log(event)
// 'resizeStart', 'resize', 'resizeEnd', rotate, onScale, onScaleStart // 'resizeStart', 'resize', 'resizeEnd', rotate, onScale, onScaleStart
if (['resizeStart', 'rotate', 'resize'].includes(event)) { if (['resizeStart', 'rotate', 'resize'].includes(event)) {
moveable?.on(event as any, (...args) => { moveable?.on(event as any, (...args) => {
// this.$emit(event, ...args) // this.$emit(event, ...args)
helper[helperEvent] && helper[helperEvent](...args) if (helper[helperEvent] && typeof helper[helperEvent] === "function") {
(helper[helperEvent] as Function)(...args)
}
}) })
} }
}) })
/* draggable */ /* draggable */
let resizeStartWidth = 0 let resizeStartWidth = 0
moveable moveable
.on('dragStart', ({ inputEvent, target, stop }) => { .on('dragStart', ({ inputEvent, target, stop }) => {
if (inputEvent.target.nodeName === 'PRE') { if (inputEvent.target.nodeName === 'PRE') {
dActiveElement.value.editable && stop() dActiveElement.value.editable && stop()
} }
dActiveElement.value.lock && stop() dActiveElement.value.lock && stop()
}) })
.on('drag', ({ target, transform, left, top, inputEvent }) => { .on('drag', ({ target, transform, left, top, inputEvent }) => {
// target!.style.transform = transform] // target!.style.transform = transform]
target!.style.left = `${left}px` target!.style.left = `${left}px`
target!.style.top = `${top}px` target!.style.top = `${top}px`
holdPosition = { left, top } holdPosition = { left, top }
}) })
.on('dragEnd', ({ target, isDrag, inputEvent }) => { .on('dragEnd', ({ target, isDrag, inputEvent }) => {
// console.log('onDragEnd', inputEvent) // console.log('onDragEnd', inputEvent)
// TODO mouseevent // TODO mouseevent
store.commit('setMouseEvent', null) store.commit('setMouseEvent', null)
inputEvent.stopPropagation() inputEvent.stopPropagation()
inputEvent.preventDefault() inputEvent.preventDefault()
// console.log(this.holdPosition, inputEvent.pageX, inputEvent.pageY) // console.log(this.holdPosition, inputEvent.pageX, inputEvent.pageY)
if (holdPosition) { if (holdPosition) {
store.dispatch('updateWidgetData', { store.dispatch("updateWidgetData", {
uuid: dActiveElement.value.uuid, uuid: dActiveElement.value.uuid,
key: 'left', key: 'left',
value: Number(holdPosition?.left), value: Number(holdPosition?.left),
}) })
// this.updateWidgetData({ store.dispatch("updateWidgetData", {
// uuid: this.dActiveElement.uuid, uuid: dActiveElement.value.uuid,
// key: 'left', key: 'top',
// value: Number(this.holdPosition?.left), value: Number(holdPosition?.top),
// }) })
store.dispatch('updateWidgetData', { holdPosition = null // important
uuid: dActiveElement.value.uuid, setTimeout(() => {
key: 'top', store.dispatch("pushHistory")
value: Number(holdPosition?.top), // pushHistory()
}) }, 100)
// this.updateWidgetData({ }
// uuid: this.dActiveElement.uuid, })
// key: 'top', // .on('keyUp', (e) => {
// value: Number(this.holdPosition?.top), // moveable.updateRect()
// }) // })
holdPosition = null // important .on('rotate', ({ target, beforeDist, dist, transform }: any) => {
setTimeout(() => { // console.log('onRotate', Number(this.dActiveElement.rotate) + Number(beforeDist + dist))
store.dispatch('pushHistory') // target.style.transform = transform
// this.pushHistory() console.log(target.style.transform)
}, 100) })
} .on('rotateEnd', (e: any) => {
}) const tf = e.target.style.transform
// .on('keyUp', (e) => { const iof = tf.indexOf('rotate')
// moveable.updateRect() let rotate = ''
// }) if (iof != -1) {
// { target, beforeDist, dist, transform } const index = iof + 'rotate'.length
.on('rotate', ({ target, beforeDist, dist, transform }) => { const half = tf.substring(index + 1)
// console.log('onRotate', Number(this.dActiveElement.rotate) + Number(beforeDist + dist)) rotate = half.slice(0, half.indexOf(')'))
// target.style.transform = transform }
rotate &&
console.log(target.style.transform) store.dispatch("updateWidgetData", {
}) uuid: dActiveElement.value.uuid,
.on('rotateEnd', (e) => { key: 'rotate',
const tf = e.target.style.transform value: rotate,
const iof = tf.indexOf('rotate') })
let rotate = '' })
if (iof != -1) { .on('resizeStart', (args) => {
const index = iof + 'rotate'.length console.log(args.target.style.transform)
const half = tf.substring(index + 1) if (!moveable) return
rotate = half.slice(0, half.indexOf(')'))
} moveable.snappable = false
rotate && if (dActiveElement.value.type === 'w-text') {
store.dispatch("updateWidgetData", { if (String(args.direction) === '1,0') {
uuid: dActiveElement.value.uuid, moveable.keepRatio = false
key: 'rotate',
value: rotate,
})
// this.updateWidgetData({
// uuid: this.dActiveElement.uuid,
// key: 'rotate',
// value: rotate,
// })
})
.on('resizeStart', (args) => {
console.log(args.target.style.transform)
if (!moveable) return
moveable.snappable = false
if (dActiveElement.value.type === 'w-text') {
if (String(args.direction) === '1,0') {
moveable.keepRatio = false
moveable.scalable = false
}
if (String(args.direction) === '1,1') {
moveable.keepRatio = false
resizeStartWidth = (args.target as HTMLElement).offsetWidth
startHL = Number(args.target!.style.lineHeight.replace('px', ''))
startLS = Number(args.target!.style.letterSpacing.replace('px', ''))
resetRatio = 1
}
} else if (dActiveElement.value.type === 'w-image' || dActiveElement.value.type === 'w-qrcode' || dActiveElement.value.type === 'w-svg') {
const dirs = ['1,0', '0,-1', '-1,0', '0,1']
dirs.includes(String(args.direction)) && (moveable.keepRatio = false)
}
})
.on('resize', (args: any) => {
const { target, width, height, dist, delta, clientX, clientY, direction } = args
console.log(2, args)
if (dActiveElement.value.type === 'w-text') {
if (String(direction) === '1,1') {
resetRatio = width / resizeStartWidth
target!.style.fontSize = dActiveElement.value.fontSize * resetRatio + 'px'
target!.style.letterSpacing = startLS * resetRatio + 'px'
target!.style.lineHeight = startHL * resetRatio + 'px'
}
target.style.width = width
target.style.height = height
resizeTempData = { width, height }
// moveable.updateRect()
target.style.backgroundImage = 'none'
// moveable.keepRatio !== this.resetRatio > 1 && (moveable.keepRatio = this.resetRatio > 1)
} else if (dActiveElement.value.type == 'w-image' || dActiveElement.value.type === 'w-qrcode' || dActiveElement.value.type === 'w-svg') {
resizeTempData = { width, height }
} else if (dActiveElement.value.type == 'w-group') {
// let record = this.dActiveElement.record
// this.dActiveElement.tempScale = width / record.width
store.commit('resize', { width: width, height: height })
// this.resizeTempData = { width, height }
// let record = this.dActiveElement.record
// setTransformAttribute(target, 'scale', width / record.width)
} else {
store.commit('resize', { width: width, height: height })
}
dActiveElement.value.rotate && (target!.style.transform = target!.style.transform.replace('(0deg', `(${dActiveElement.value.rotate}`))
})
.on('resizeEnd', (e: any) => {
if (!moveable) return
moveable.resizable = true
// moveable.scalable = true
moveable.snappable = true
if (e.lastEvent) {
// setTimeout(() => {
// if (this.dActiveElement.type === 'w-group') {
// //
// return
// }
console.log('重置translate', dActiveElement.value)
//
// if (this.dActiveElement.cache && this.dActiveElement.cache.recordLeft) {
// const left = e.lastEvent.drag.translate[0] + Number(this.dActiveElement.cache.recordLeft)
// const top = e.lastEvent.drag.translate[1] + Number(this.dActiveElement.cache.recordTop)
// this.dActiveElement.cache = { left, top }
// } else {
// const left = e.lastEvent.drag.translate[0] + Number(this.dActiveElement.left)
// const top = e.lastEvent.drag.translate[1] + Number(this.dActiveElement.top)
// this.dActiveElement.cache = { left, top }
// }
const left = e.lastEvent.drag.translate[0]
const top = e.lastEvent.drag.translate[1]
store.dispatch("updateWidgetMultiple", {
uuid: dActiveElement.value.uuid,
data: [
{
key: 'left',
value: Number(dActiveElement.value.left) + left,
},
{
key: 'top',
value: Number(dActiveElement.value.top) + top,
},
],
})
// this.updateWidgetMultiple({
// uuid: this.dActiveElement.uuid,
// data: [
// {
// key: 'left',
// value: Number(this.dActiveElement.left) + left,
// },
// {
// key: 'top',
// value: Number(this.dActiveElement.top) + top,
// },
// ],
// })
// translate
const tf = e.target.style.transform
const iof = tf.indexOf('translate')
const FRONT = tf.slice(0, iof + 'translate'.length + 1)
const half = tf.substring(iof + 'translate'.length + 1)
const END = half.substring(half.indexOf(')'))
e.target.style.transform = FRONT + '0, 0' + END
// this.moveable.updateRect()
// }, 10)
}
if (resizeTempData) {
store.commit('resize', resizeTempData)
resizeTempData = null
setTimeout(async () => {
await nextTick()
if (moveable) {
moveable.updateRect()
}
}, 10)
}
try {
if (dActiveElement.value.type === 'w-text') {
const d = e.direction || e.lastEvent.direction
String(d) === '1,1' && (dActiveElement.value.fontSize = dActiveElement.value.fontSize * resetRatio)
}
} catch (err) {}
moveable.keepRatio = true
})
.on('scaleStart', (e) => {
if (dActiveElement.value.type === 'w-text') {
startHL = Number(e.target!.style.lineHeight.replace('px', ''))
startLS = Number(e.target!.style.letterSpacing.replace('px', ''))
resetRatio = 1
} else {
if (!moveable) return
moveable.scalable = false moveable.scalable = false
} }
}) if (String(args.direction) === '1,1') {
.on('scale', (e) => { moveable.keepRatio = false
if (!moveable) return resizeStartWidth = (args.target as HTMLElement).offsetWidth
moveable.resizable = false startHL = Number(args.target!.style.lineHeight.replace('px', ''))
const { target, scale, transform } = e startLS = Number(args.target!.style.letterSpacing.replace('px', ''))
resetRatio = scale[0] resetRatio = 1
target!.style.transform = transform
dActiveElement.value.rotate && (target!.style.transform = target!.style.transform.replace('0deg', dActiveElement.value.rotate))
})
.on('scaleEnd', (e: Record<string, any>) => {
if (!moveable) return
moveable.resizable = true
// moveable.scalable = true
moveable.keepRatio = true
console.log(e.target.style.transform)
try {
if (dActiveElement.value.type === 'w-text') {
const d = e.direction || e.lastEvent.direction
String(d) === '1,1' && (dActiveElement.value.fontSize = dActiveElement.value.fontSize * resetRatio)
}
} catch (err) {}
})
.on('dragGroup', (e) => {
e.inputEvent.stopPropagation()
e.inputEvent.preventDefault()
holdGroupPosition = {}
const events = e.events
for (let i = 0; i < events.length; i++) {
const ev = events[i]
const currentWidget = dWidgets.value.find((item: any) => item.uuid === ev.target.getAttribute('data-uuid'))
const left = Number(currentWidget.left) + ev.beforeTranslate[0]
// debug -- start --
if (i === 1) {
console.log(Number(currentWidget.left), ev.beforeTranslate[0])
}
// debug -- end --
const top = Number(currentWidget.top) + ev.beforeTranslate[1]
ev.target.style.left = `${left}px`
ev.target.style.top = `${top}px`
holdGroupPosition[`${ev.target.getAttribute('data-uuid')}`] = { left, top }
} }
}) } else if (dActiveElement.value.type === 'w-image' || dActiveElement.value.type === 'w-qrcode' || dActiveElement.value.type === 'w-svg') {
.on('dragGroupEnd', (e) => { const dirs = ['1,0', '0,-1', '-1,0', '0,1']
for (const key in holdGroupPosition) { dirs.includes(String(args.direction)) && (moveable.keepRatio = false)
if (Object.prototype.hasOwnProperty.call(holdGroupPosition, key)) { }
const item = holdGroupPosition[key] })
store.dispatch('updateWidgetData', { .on('resize', (args: any) => {
uuid: key, const { target, width, height, dist, delta, clientX, clientY, direction } = args
console.log(2, args)
if (dActiveElement.value.type === 'w-text') {
if (String(direction) === '1,1') {
resetRatio = width / resizeStartWidth
target!.style.fontSize = dActiveElement.value.fontSize * resetRatio + 'px'
target!.style.letterSpacing = startLS * resetRatio + 'px'
target!.style.lineHeight = startHL * resetRatio + 'px'
}
target.style.width = width
target.style.height = height
resizeTempData = { width, height }
// moveable.updateRect()
target.style.backgroundImage = 'none'
// moveable.keepRatio !== this.resetRatio > 1 && (moveable.keepRatio = this.resetRatio > 1)
} else if (dActiveElement.value.type == 'w-image' || dActiveElement.value.type === 'w-qrcode' || dActiveElement.value.type === 'w-svg') {
resizeTempData = { width, height }
} else if (dActiveElement.value.type == 'w-group') {
// let record = this.dActiveElement.record
// this.dActiveElement.tempScale = width / record.width
store.commit('resize', { width: width, height: height })
// this.resizeTempData = { width, height }
// let record = this.dActiveElement.record
// setTransformAttribute(target, 'scale', width / record.width)
} else {
store.commit('resize', { width: width, height: height })
}
dActiveElement.value.rotate && (target!.style.transform = target!.style.transform.replace('(0deg', `(${dActiveElement.value.rotate}`))
})
.on('resizeEnd', (e: any) => {
if (!moveable) return
moveable.resizable = true
// moveable.scalable = true
moveable.snappable = true
if (e.lastEvent) {
// setTimeout(() => {
// if (this.dActiveElement.type === 'w-group') {
// //
// return
// }
console.log('重置translate', dActiveElement.value)
//
// if (this.dActiveElement.cache && this.dActiveElement.cache.recordLeft) {
// const left = e.lastEvent.drag.translate[0] + Number(this.dActiveElement.cache.recordLeft)
// const top = e.lastEvent.drag.translate[1] + Number(this.dActiveElement.cache.recordTop)
// this.dActiveElement.cache = { left, top }
// } else {
// const left = e.lastEvent.drag.translate[0] + Number(this.dActiveElement.left)
// const top = e.lastEvent.drag.translate[1] + Number(this.dActiveElement.top)
// this.dActiveElement.cache = { left, top }
// }
const left = e.lastEvent.drag.translate[0]
const top = e.lastEvent.drag.translate[1]
store.dispatch("updateWidgetMultiple", {
uuid: dActiveElement.value.uuid,
data: [
{
key: 'left', key: 'left',
value: item.left, value: Number(dActiveElement.value.left) + left,
}) },
store.dispatch("updateWidgetData", { {
uuid: key,
key: 'top', key: 'top',
value: item.top, value: Number(dActiveElement.value.top) + top,
}) },
} ],
})
// translate
const tf = e.target.style.transform
const iof = tf.indexOf('translate')
const FRONT = tf.slice(0, iof + 'translate'.length + 1)
const half = tf.substring(iof + 'translate'.length + 1)
const END = half.substring(half.indexOf(')'))
e.target.style.transform = FRONT + '0, 0' + END
// this.moveable.updateRect()
// }, 10)
}
if (resizeTempData) {
store.commit('resize', resizeTempData)
resizeTempData = null
// await this.$nextTick()
moveable.updateRect()
// 线 https://github.com/palxiao/poster-design/issues/75
store.commit('setShowMoveable', false)
setTimeout(() => {
store.commit('setShowMoveable', true)
}, 10);
}
try {
if (dActiveElement.value.type === 'w-text') {
const d = e.direction || e.lastEvent.direction
String(d) === '1,1' && (dActiveElement.value.fontSize = dActiveElement.value.fontSize * resetRatio)
} }
holdGroupPosition = null } catch (err) {}
// background: linear-gradient(to right, #ccc 0%, #ccc 50%, transparent 50%); moveable.keepRatio = true
// background-size: 12px 1px; })
}) .on('scaleStart', (e) => {
.on('resizeGroupStart', ({ events }) => { if (dActiveElement.value.type === 'w-text') {
console.log(events) startHL = Number(e.target!.style.lineHeight.replace('px', ''))
// events.forEach((ev, i) => { startLS = Number(e.target!.style.letterSpacing.replace('px', ''))
// const frame = this.frames[i]; resetRatio = 1
// // Set origin if transform-origin use %. } else {
// ev.setOrigin(["%", "%"]); if (!moveable) return
moveable.scalable = false
}
})
.on('scale', (e) => {
if (!moveable) return
moveable.resizable = false
const { target, scale, transform } = e
resetRatio = scale[0]
target!.style.transform = transform
dActiveElement.value.rotate && (target!.style.transform = target!.style.transform.replace('0deg', dActiveElement.value.rotate))
})
.on('scaleEnd', (e: any) => {
if (!moveable) return
moveable.resizable = true
// moveable.scalable = true
moveable.keepRatio = true
console.log(e.target.style.transform)
try {
if (dActiveElement.value.type === 'w-text') {
const d = e.direction || e.lastEvent.direction
String(d) === '1,1' && (dActiveElement.value.fontSize = dActiveElement.value.fontSize * resetRatio)
}
} catch (err) {}
})
.on('dragGroup', (e) => {
e.inputEvent.stopPropagation()
e.inputEvent.preventDefault()
holdGroupPosition = {}
const events = e.events
for (let i = 0; i < events.length; i++) {
const ev = events[i]
const currentWidget = dWidgets.value.find((item: any) => item.uuid === ev.target.getAttribute('data-uuid'))
const left = Number(currentWidget.left) + ev.beforeTranslate[0]
// debug -- start --
if (i === 1) {
console.log(Number(currentWidget.left), ev.beforeTranslate[0])
}
// debug -- end --
const top = Number(currentWidget.top) + ev.beforeTranslate[1]
ev.target.style.left = `${left}px`
ev.target.style.top = `${top}px`
holdGroupPosition[`${ev.target.getAttribute('data-uuid')}`] = { left, top }
}
})
.on('dragGroupEnd', (e) => {
for (const key in holdGroupPosition) {
if (Object.prototype.hasOwnProperty.call(holdGroupPosition, key)) {
const item = holdGroupPosition[key]
store.dispatch("updateWidgetData", {
uuid: key,
key: 'left',
value: item.left,
})
store.dispatch("updateWidgetData", {
uuid: key,
key: 'top',
value: item.top,
})
}
}
holdGroupPosition = null
// background: linear-gradient(to right, #ccc 0%, #ccc 50%, transparent 50%);
// background-size: 12px 1px;
})
.on('resizeGroupStart', ({ events }: any) => {
console.log(events)
// events.forEach((ev, i) => {
// const frame = this.frames[i];
// // Set origin if transform-origin use %.
// ev.setOrigin(["%", "%"]);
// // If cssSize and offsetSize are different, set cssSize. // // If cssSize and offsetSize are different, set cssSize.
// const style = window.getComputedStyle(ev.target); // const style = window.getComputedStyle(ev.target);
// const cssWidth = parseFloat(style.width); // const cssWidth = parseFloat(style.width);
// const cssHeight = parseFloat(style.height); // const cssHeight = parseFloat(style.height);
// ev.set([cssWidth, cssHeight]); // ev.set([cssWidth, cssHeight]);
// // If a drag event has already occurred, there is no dragStart. // // If a drag event has already occurred, there is no dragStart.
// ev.dragStart && ev.dragStart.set(frame.translate); // ev.dragStart && ev.dragStart.set(frame.translate);
// }); // });
}) })
.on('resizeGroup', (e) => { .on('resizeGroup', (e: any) => {
// events.forEach(({ target, width, height, drag }, i) => { // events.forEach(({ target, width, height, drag }, i) => {
// const frame = this.frames[i]; // const frame = this.frames[i];
// target.style.width = `${width}px`; // target.style.width = `${width}px`;
// target.style.height = `${height}px`; // target.style.height = `${height}px`;
// // get drag event // // get drag event
// frame.translate = drag.beforeTranslate; // frame.translate = drag.beforeTranslate;
// target.style.transform // target.style.transform
// = `translate(${drag.beforeTranslate[0]}px, ${drag.beforeTranslate[1]}px)`; // = `translate(${drag.beforeTranslate[0]}px, ${drag.beforeTranslate[1]}px)`;
// }); // });
}) })
.on('resizeGroupEnd', ({ targets, isDrag }) => { .on('resizeGroupEnd', ({ targets, isDrag }: any) => {
console.log('onResizeGroupEnd', targets, isDrag) console.log('onResizeGroupEnd', targets, isDrag)
}) })
// -- Start -- // -- Start --
useSelecto(moveable) useSelecto(moveable)
// -- END -- // -- END --
})
})
async function created() { async function created() {
await nextTick() await nextTick()
const Ele = document.getElementById('page-design') const Ele = document.getElementById('main')
// TODO // TODO
Ele?.addEventListener('scroll', () => { Ele?.addEventListener('scroll', () => {
moveable && (moveable.updateRect()) if (!moveable) return
moveable.updateRect()
}) })
} }
created() created()
// ...mapActions(['updateWidgetData', 'updateWidgetMultiple', 'pushHistory']), // ...mapActions(['updateWidgetData', 'updateWidgetMultiple', 'pushHistory']),
function checkMouseEvent() {
if (activeMouseEvent.value && moveable) {
moveable.dragStart(activeMouseEvent.value)
// 使mouseevent
store.commit('setMouseEvent', null)
}
}
</script> </script>
<style lang="less"> <style lang="less">
@import url('./style/index.less'); @import url('./style/index.less');
</style> </style>

View File

@ -10,12 +10,12 @@
<el-tabs tab-position="left" style="height: 60vh" class="demo-tabs" @tab-change="tabChange"> <el-tabs tab-position="left" style="height: 60vh" class="demo-tabs" @tab-change="tabChange">
<el-tab-pane label="我的素材"> <el-tab-pane label="我的素材">
<div class="pic__box"> <div class="pic__box">
<photo-list :isDone="state.isDone" :listData="state.imgList" @load="load" @select="selectImg" /> <photo-list :canDrag="false" :isDone="state.isDone" :listData="state.imgList" @load="load" @select="selectImg" />
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="照片图库"> <el-tab-pane label="照片图库">
<div class="pic__box"> <div class="pic__box">
<photo-list :isDone="state.isPicsDone" :listData="state.recommendImgList" @load="loadPic" @select="selectImg($event, state.recommendImgList)" /> <photo-list :canDrag="false" :isDone="state.isPicsDone" :listData="state.recommendImgList" @load="loadPic" @select="selectImg($event, state.recommendImgList)" />
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

View File

@ -240,7 +240,6 @@ async function drop(e: MouseEvent) {
} else { } else {
store.dispatch('addWidget', setting) // store.dispatch('addWidget', setting) //
// addWidget(setting) //
} }
} }
} else if (type === 'bg') { } else if (type === 'bg') {
@ -248,7 +247,6 @@ async function drop(e: MouseEvent) {
} else if (type !== 'group') { } else if (type !== 'group') {
console.log(setting) console.log(setting)
store.dispatch('addWidget', setting) // store.dispatch('addWidget', setting) //
// addWidget(setting) //
} }
// //
// this.$store.commit('selectItem', {}) // this.$store.commit('selectItem', {})

View File

@ -268,7 +268,9 @@ async function autoFixTop() {
} }
defineExpose({ defineExpose({
screenChange screenChange,
add,
sub
}) })
</script> </script>
@ -276,7 +278,7 @@ defineExpose({
<style lang="less" scoped> <style lang="less" scoped>
@color-select: #1b1634; @color-select: #1b1634;
@color1: #ffffff; // @color1: #ffffff; //
@color2: #ffffff; // Appears 3 times @color2: #ffffff;
@color3: #666666; // @color3: #666666; //
@color4: #c2c2c2; // @color4: #c2c2c2; //
@color5: rgba(0, 0, 0, 0.12); // @color5: rgba(0, 0, 0, 0.12); //

View File

@ -157,9 +157,9 @@ export default defineComponent({
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@color0: #ffffff; // Appears 5 times @color0: #ffffff;
@color1: #999999; // Appears 3 times @color1: #999999;
@color2: rgba(0, 0, 0, 0.05); // Appears 2 times @color2: rgba(0, 0, 0, 0.05);
.widget-list { .widget-list {
width: 100%; width: 100%;

View File

@ -59,29 +59,13 @@ watch(
}, },
) )
// const { proxy } = getCurrentInstance() as ComponentInternalInstance
// watch(
// () => state.active,
// () => {
// let screen = document.getElementById('page-design')
// nextTick(() => {
// proxy?.updateScreen({
// width: screen.offsetWidth,
// height: screen.offsetHeight,
// })
// })
// },
// )
defineExpose({ defineExpose({
clickClassify clickClassify
}) })
// ...mapActions(['updateScreen']),
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
// Color variables (appears count calculates by raw css) @color1: #3e4651;
@color1: #3e4651; // Appears 2 times
#widget-panel { #widget-panel {
transition: all 1s; transition: all 1s;

View File

@ -10,13 +10,12 @@
<div class="list"> <div class="list">
<div <div
v-for="(item, i) in state.list" :key="i + 'i'" v-for="(item, i) in state.list" :key="i + 'i'"
:style="{ width: item.listWidth + 'px', marginRight: item.gap + 'px' }" :style="{ width: item.listWidth + 'px', marginRight: item.gap + 'px', cursor: canDrag ? 'grab' : 'pointer' }"
class="list__img" draggable="false" class="list__img" draggable="false"
@mousedown="dragStart($event, i)" @mousedown="dragStart($event, i)"
@mousemove="mousemove" @mousemove="mousemove"
@mouseup="mouseup" @mouseup="mouseup"
@click.stop="select(i)" @click.stop="select(i)"
@dragstart="dragStart($event, i)"
> >
<edit-model v-if="props.edit" :options="props.edit" :data="{ item, i }"> <edit-model v-if="props.edit" :options="props.edit" :data="{ item, i }">
<div v-if="item.isDelect" class="list__mask">已删除</div> <div v-if="item.isDelect" class="list__mask">已删除</div>
@ -49,13 +48,13 @@ type TProps = {
edit?: Record<string, any> edit?: Record<string, any>
isDone?: boolean isDone?: boolean
isShort?: boolean isShort?: boolean
canDrag?: boolean
} }
type TEmits = { type TEmits = {
(event: 'load'): void (event: 'load'): void
(event: 'select', data: number): void (event: 'select', data: number): void
(event: 'drag', data: number): void (event: 'drag', data: number): void
} }
type TState = { type TState = {
@ -65,6 +64,7 @@ type TState = {
const props = withDefaults(defineProps<TProps>(), { const props = withDefaults(defineProps<TProps>(), {
isShort: false, isShort: false,
canDrag: true,
listData: () => ([]) listData: () => ([])
}) })
const emit = defineEmits<TEmits>() const emit = defineEmits<TEmits>()
@ -176,6 +176,9 @@ const select = (i: number) => {
const dragStart = async (e: Event | any, i: number) => { const dragStart = async (e: Event | any, i: number) => {
e.preventDefault() e.preventDefault()
if (!props.canDrag) {
return
}
startPoint = { x: e.x, y: e.y } startPoint = { x: e.x, y: e.y }
if (!state.list[i].isDelect) { if (!state.list[i].isDelect) {
const setImageParams: TItem2DataParam = { const setImageParams: TItem2DataParam = {
@ -242,7 +245,6 @@ defineExpose({
&__img { &__img {
// background: #f1f2f4; // background: #f1f2f4;
display: inline-block; display: inline-block;
cursor: grab;
// margin: 0 6px 2px 0; // margin: 0 6px 2px 0;
margin-bottom: 3px; margin-bottom: 3px;
border-radius: 2px; border-radius: 2px;

View File

@ -173,8 +173,8 @@ function blurInput() {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@color0: #e1e1e1; // Appears 2 times @color0: #e1e1e1;
@color1: #d1d1d1; // Appears 2 times @color1: #d1d1d1;
.number-input { .number-input {
height: 60px; height: 60px;

View File

@ -133,6 +133,7 @@ function updateRecord(tempScale ?: number) {
// TODO DOM Change // TODO DOM Change
// this.dActiveElement.scale = this.ratio // this.dActiveElement.scale = this.ratio
if (widget.value) { if (widget.value) {
//
widget.value.style.transformOrigin = 'left top' // scale widget.value.style.transformOrigin = 'left top' // scale
setTransformAttribute(widget.value, 'scale', ratio.value) setTransformAttribute(widget.value, 'scale', ratio.value)
} }
@ -180,7 +181,7 @@ function touchend() {
setTimeout(() => { setTimeout(() => {
if (!widget.value) return if (!widget.value) return
widget.value.style.opacity = `${props.params.opacity}` widget.value.style.opacity = `${props.params.opacity}`
// this.$refs.widget.style.transformOrigin = 'center' // scale // widget.value.style.transformOrigin = 'center' // scale
}, 100) }, 100)
// const opacity = this.$refs.widget.style.opacity // const opacity = this.$refs.widget.style.opacity

View File

@ -308,8 +308,11 @@ function openCropper() {
// } // }
function selectDone(img: TGetImageListResult) { async function selectDone(img: TGetImageListResult) {
state.innerElement.imgUrl = img.url state.innerElement.imgUrl = img.url
const loadImg = await getImage(img.url)
state.innerElement.width = loadImg.width * store.getters.dZoom / 100
state.innerElement.height = loadImg.height * store.getters.dZoom / 100
// this.imgCrop(true) // this.imgCrop(true)
} }

View File

@ -78,11 +78,11 @@ export default () => {
setting.text = await navigator.clipboard.readText() setting.text = await navigator.clipboard.readText()
store.dispatch('addWidget', setting) store.dispatch('addWidget', setting)
break break
} } else resolve()
} }
}) })
.catch((error) => { .catch((error) => {
// 剪贴板内容为空 // 剪贴板内容为空, 直接返回
resolve() resolve()
}) })
}) })

View File

@ -6,11 +6,8 @@
* @LastEditTime: 2023-09-19 17:29:06 * @LastEditTime: 2023-09-19 17:29:06
*/ */
import store from '@/store' import store from '@/store'
const _this: any = {} // const _this: any = {}
_this.dHistoryParams = store.getters.dHistoryParams // _this.dHistoryParams = store.getters.dHistoryParams
// _this.dActiveElement = store.getters.dActiveElement
// _this.dPage = store.getters.dPage
// _this.handleHistory = store.dispatch.ha
import keyCodeOptions from './methods/keyCodeOptions' import keyCodeOptions from './methods/keyCodeOptions'
import dealWithCtrl from './methods/dealWithCtrl' import dealWithCtrl from './methods/dealWithCtrl'

View File

@ -281,10 +281,8 @@ export default {
} else { } else {
copyElement[i].parent = '-1' copyElement[i].parent = '-1'
} }
if (!container) { copyElement[i].top += 30
copyElement[i].top += 50 copyElement[i].left += 30
copyElement[i].left += 50
}
} }
store.state.dWidgets = store.state.dWidgets.concat(copyElement) store.state.dWidgets = store.state.dWidgets.concat(copyElement)
store.state.dActiveElement = copyElement[0] store.state.dActiveElement = copyElement[0]

View File

@ -28,7 +28,6 @@ type TState = {
style: StyleValue style: StyleValue
} }
// mixins: [shortcuts],
const store = useStore() const store = useStore()
const route = useRoute() const route = useRoute()
const state = reactive<TState>({ const state = reactive<TState>({
@ -48,8 +47,8 @@ onMounted(() => {
}) })
}) })
// ...mapActions(['initGroupJson', 'setTemplate', 'addGroup']),
async function load() { async function load() {
let backgroundImage = ''
let loadFlag = false let loadFlag = false
const { id, tempid, tempType: type } = route.query const { id, tempid, tempType: type } = route.query
if (id || tempid) { if (id || tempid) {
@ -70,6 +69,10 @@ async function load() {
} else { } else {
pageStore.setDPage(content.page) pageStore.setDPage(content.page)
// store.commit('setDPage', content.page) // store.commit('setDPage', content.page)
//
backgroundImage = content.page?.backgroundImage
backgroundImage && delete content.page.backgroundImage
store.commit('setDPage', content.page)
if (id) { if (id) {
store.commit('setDWidgets', widgets) store.commit('setDWidgets', widgets)
} else { } else {
@ -111,10 +114,11 @@ async function load() {
} }
} catch (e) {} } catch (e) {}
}) })
// TODO: //
if (content.page?.backgroundImage) { if (backgroundImage) {
const preloadBg = new Preload([content.page.backgroundImage]) const preloadBg = new Preload([backgroundImage])
await preloadBg.imgs() await preloadBg.imgs()
store.commit('setDPage', {...content.page, ...{backgroundImage}})
} }
try { try {
fontWithDraw && (await font2style(fontContent, fontData)) fontWithDraw && (await font2style(fontContent, fontData))

View File

@ -57,7 +57,6 @@ import _config from '../config'
import { import {
CSSProperties, computed, nextTick, CSSProperties, computed, nextTick,
onBeforeUnmount, onMounted, reactive, ref, onBeforeUnmount, onMounted, reactive, ref,
getCurrentInstance
} from 'vue' } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue' import RightClickMenu from '@/components/business/right-click-menu/RcMenu.vue'
@ -65,7 +64,6 @@ import Moveable from '@/components/business/moveable/Moveable.vue'
import designBoard from '@/components/modules/layout/designBoard/index.vue' import designBoard from '@/components/modules/layout/designBoard/index.vue'
import zoomControl from '@/components/modules/layout/zoomControl/index.vue' import zoomControl from '@/components/modules/layout/zoomControl/index.vue'
import lineGuides from '@/components/modules/layout/lineGuides.vue' import lineGuides from '@/components/modules/layout/lineGuides.vue'
import shortcuts from '@/mixins/shortcuts' import shortcuts from '@/mixins/shortcuts'
// import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue' // import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
import HeaderOptions from './components/HeaderOptions.vue' import HeaderOptions from './components/HeaderOptions.vue'
@ -85,16 +83,6 @@ type TState = {
showLineGuides: boolean showLineGuides: boolean
} }
const beforeUnload = function (e: Event): string {
const confirmationMessage: string = '系统不会自动保存您未修改的内容';
(e || window.event).returnValue = (confirmationMessage as any) // Gecko and Trident
return confirmationMessage // Gecko and WebKit
}
// mixins: [shortcuts],
!_config.isDev && window.addEventListener('beforeunload', beforeUnload)
const { const {
dActiveElement, dHistoryParams, dCopyElement dActiveElement, dHistoryParams, dCopyElement
} = useSetupMapGetters(['dActiveElement', 'dHistoryParams', 'dCopyElement']) } = useSetupMapGetters(['dActiveElement', 'dHistoryParams', 'dCopyElement'])
@ -118,9 +106,15 @@ const zoomControlRef = ref<typeof zoomControl | null>(null)
const store = useStore() const store = useStore()
const route = useRoute() const route = useRoute()
// const draw = () => { const beforeUnload = function (e: Event): any {
// state.openDraw = true if (store.getters.dHistoryParams.length > 0) {
// } const confirmationMessage: string = '系统不会自动保存您未修改的内容';
(e || window.event).returnValue = (confirmationMessage as any) // Gecko and Trident
return confirmationMessage // Gecko and WebKit
} else return false
}
!_config.isDev && window.addEventListener('beforeunload', beforeUnload)
function jump2home() { function jump2home() {
// const fullPath = window.location.href.split('/') // const fullPath = window.location.href.split('/')
@ -141,32 +135,40 @@ const undoable = computed(() => {
const redoable = computed(() => { const redoable = computed(() => {
return !(dHistoryParams.value.index === dHistoryParams.value.length - 1) return !(dHistoryParams.value.index === dHistoryParams.value.length - 1)
}) })
// watch: {
// $route() { function zoomSub() {
// console.log('change route', this.$route.query) if (!zoomControlRef.value) return
// this.loadData() zoomControlRef.value.sub()
// }, }
// },
function zoomAdd() {
if (!zoomControlRef.value) return
zoomControlRef.value.add()
}
function save() {
if (!optionsRef.value) return
optionsRef.value.save()
}
const { handleKeydowm, handleKeyup, dealCtrl } = shortcuts.methods const { handleKeydowm, handleKeyup, dealCtrl } = shortcuts.methods
let checkCtrl: number | undefined let checkCtrl: number | undefined
const instanceFn = { save, zoomAdd, zoomSub }
onMounted(() => { onMounted(() => {
store.dispatch('initGroupJson', JSON.stringify(wGroupSetting)) store.dispatch('initGroupJson', JSON.stringify(wGroupSetting))
// initGroupJson(JSON.stringify(wGroup.setting)) // initGroupJson(JSON.stringify(wGroup.setting))
window.addEventListener('scroll', fixTopBarScroll) window.addEventListener('scroll', fixTopBarScroll)
// window.addEventListener('click', this.clickListener) // window.addEventListener('click', this.clickListener)
const instance = getCurrentInstance() document.addEventListener('keydown', handleKeydowm(store, checkCtrl, instanceFn, dealCtrl), false)
document.addEventListener('keydown', handleKeydowm(store, checkCtrl, instance, dealCtrl), false)
document.addEventListener('keyup', handleKeyup(store, checkCtrl), false) document.addEventListener('keyup', handleKeyup(store, checkCtrl), false)
loadData() loadData()
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.removeEventListener('scroll', fixTopBarScroll) window.removeEventListener('scroll', fixTopBarScroll)
const instance = getCurrentInstance()
// window.removeEventListener('click', this.clickListener) // window.removeEventListener('click', this.clickListener)
document.removeEventListener('keydown', handleKeydowm(store, checkCtrl, instance, dealCtrl), false) document.removeEventListener('keydown', handleKeydowm(store, checkCtrl, instanceFn, dealCtrl), false)
document.removeEventListener('keyup', handleKeyup(store, checkCtrl), false) document.removeEventListener('keyup', handleKeyup(store, checkCtrl), false)
document.oncontextmenu = null document.oncontextmenu = null
}) })
@ -201,29 +203,14 @@ function loadData() {
}) })
} }
function zoomSub() {
if (!zoomControlRef.value) return
zoomControlRef.value.sub()
}
function zoomAdd() {
if (!zoomControlRef.value) return
zoomControlRef.value.add()
}
function save() {
if (!optionsRef.value) return
optionsRef.value.save()
}
function fixTopBarScroll() { function fixTopBarScroll() {
const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
state.style.left = `-${scrollLeft}px` state.style.left = `-${scrollLeft}px`
} }
function clickListener(e: Event) { // function clickListener(e: Event) {
console.log('click listener', e) // console.log('click listener', e)
} // }
function optionsChange({ downloadPercent, downloadText }: { downloadPercent: number, downloadText: string }) { function optionsChange({ downloadPercent, downloadText }: { downloadPercent: number, downloadText: string }) {
state.downloadPercent = downloadPercent state.downloadPercent = downloadPercent