mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
Merge: main branch
This commit is contained in:
commit
503e182172
10
README.md
10
README.md
@ -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" />
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
@ -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>
|
||||||
|
@ -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', {})
|
||||||
|
@ -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); // 高亮选项背景
|
||||||
|
@ -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%;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -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'
|
||||||
|
@ -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]
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user