diff --git a/README.md b/README.md index 6bbed97..5e4872a 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,15 @@ npm run serve - [qr-code-styling](https://qr-code-styling.com/): 风格化二维码 - [rembg](https://github.com/danielgatis/rembg): 图片抠图,使用 u2net 预训练模型 -或许你在工作中有类似的需求,或许你对开发编辑器感兴趣,也希望这个项目能给到你一些微薄帮助! +### 友情赞助商 + +[![](https://xp.palxp.cn/images/2024-3-1-1709306907030.png)](https://dooring.vip/) + +### 交流群 + +| 作者微信:备注加群 | 公众号 | +| --- | --- | +| ![](https://xp.palxp.cn/images/2024-3-1-1709306328344.png) | ![](https://xp.palxp.cn/images/2024-3-1-1709306365949.png) | ### `Star` diff --git a/src/api/album.ts b/src/api/album.ts index 1cb677f..14425c6 100644 --- a/src/api/album.ts +++ b/src/api/album.ts @@ -21,7 +21,12 @@ export const init = (params: Type.Object = {}) => fetch(API.init, params, 'post' export const getPicList = (params: Type.Object = {}) => fetch(API.getList, params) -export const getToken = (params: Type.Object = {}) => fetch(API.getToken, params) +type TGetTokenParam = { + bucket: string, + name: string +} + +export const getToken = (params: TGetTokenParam) => fetch(API.getToken, params) export const deletePic = (params: Type.Object = {}) => fetch(API.delOne, params, 'post') diff --git a/src/api/material.ts b/src/api/material.ts index 2f28160..8d452e5 100644 --- a/src/api/material.ts +++ b/src/api/material.ts @@ -43,8 +43,23 @@ type TGetListResult = TCommResResult<{ // 获取素材列表: export const getList = (params: TGetListParam) => fetch('design/material', params) +export type TGetFontParam = { + pageSize?: number +} + +/** 字体item数据 */ +export type TGetFontItemData = { + id: number + alias: string + oid: string + value: string + preview: string + woff: string + lang: string +} + // 获取字体 -export const getFonts = (params: Type.Object = {}) => fetch('design/fonts', params) +export const getFonts = (params: TGetFontParam = {}) => fetch>('design/fonts', params) export const getFontSub = (params: Type.Object = {}, extra: any = {}) => fetch('design/font_sub', params, 'get', {}, extra) // 图库列表 diff --git a/src/common/methods/DesignFeatures/setComponents.ts b/src/common/methods/DesignFeatures/setComponents.ts index d718b13..4152131 100644 --- a/src/common/methods/DesignFeatures/setComponents.ts +++ b/src/common/methods/DesignFeatures/setComponents.ts @@ -2,19 +2,19 @@ * @Author: ShawnPhang * @Date: 2022-02-22 15:06:14 * @Description: 设置图片类型元素 - * @LastEditors: ShawnPhang - * @LastEditTime: 2022-03-07 14:57:51 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ import store from '@/store' -export default async function setCompData(item: any) { - const group = typeof item === 'string' ? JSON.parse(item) : JSON.parse(JSON.stringify(item)) - let parent: any = {} +export default async function setCompData(item: TCommonItemData[] | string) { + const group: TCommonItemData[] = typeof item === 'string' ? JSON.parse(item) : JSON.parse(JSON.stringify(item)) + let parent: Partial = {} Array.isArray(group) && - group.forEach((element: any) => { + group.forEach((element) => { element.type === 'w-group' && (parent = element) }) const { width: screenWidth, height: screenHeight } = store.getters.dPage - const { width: imgWidth, height: imgHeight } = parent + const { width: imgWidth = 0, height: imgHeight = 0 } = parent let ratio = 1 // 先限制在画布内,保证不超过边界 if (imgWidth > screenWidth || imgHeight > screenHeight) { @@ -23,7 +23,7 @@ export default async function setCompData(item: any) { // 根据画布缩放比例再进行一次调整 if (ratio < 1) { ratio *= store.getters.dZoom / 100 - group.forEach((element: any) => { + group.forEach((element) => { element.fontSize && (element.fontSize *= ratio) element.width *= ratio element.height *= ratio diff --git a/src/common/methods/QiNiu.ts b/src/common/methods/QiNiu.ts index 31dd1e7..18de8fd 100644 --- a/src/common/methods/QiNiu.ts +++ b/src/common/methods/QiNiu.ts @@ -2,8 +2,8 @@ * @Author: ShawnPhang * @Date: 2021-08-29 20:35:31 * @Description: 七牛上传方法 - * @LastEditors: ShawnPhang - * @LastEditTime: 2023-10-05 16:11:55 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ import dayjs from 'dayjs' import api from '@/api/album' @@ -15,13 +15,13 @@ interface Options { } export default { - upload: async (file: File, options: Options, cb?: Function) => { - const win: any = window + upload: async (file: File, options: Options, cb?: IQiniuSubscribeCb) => { + const win = window let name = '' const suffix = file.type.split('/')[1] || 'png' // 文件后缀 if (!options.fullPath) { // const DT: any = await exifGetTime(file) // 照片时间 - const DT: any = new Date() + const DT = new Date() const YM = `${dayjs(DT).format('YYYY')}/${dayjs(DT).format('MM')}/` // 文件时间分类 const keyName = YM + new Date(DT).getTime() const prePath = options.prePath ? options.prePath + '/' : '' @@ -32,15 +32,15 @@ export default { useCdnDomain: true, // 使用cdn加速 } const observable = win.qiniu.upload(file, name, token, {}, exOption) - return new Promise((resolve: Function, reject: Function) => { + return new Promise((resolve: IQiniuSubscribeCb, reject: (err: string) => void) => { observable.subscribe({ - next: (result: any) => { - cb && cb(result) // result.total.percent -> 展示进度 + next: (result) => { + cb?.(result) // result.total.percent -> 展示进度 }, - error: (e: any) => { + error: (e) => { reject(e) }, - complete: (result: any) => { + complete: (result) => { resolve(result) // cb && cb(result) // result.total.percent -> 展示进度 }, diff --git a/src/common/methods/addMouseWheel.ts b/src/common/methods/addMouseWheel.ts index 20a730c..6be1dae 100644 --- a/src/common/methods/addMouseWheel.ts +++ b/src/common/methods/addMouseWheel.ts @@ -2,12 +2,19 @@ * @Author: ShawnPhang * @Date: 2022-03-25 13:43:07 * @Description: 添加滚动监听 - * @LastEditors: ShawnPhang - * @LastEditTime: 2022-03-25 14:32:19 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ import store from '@/store' -export default function(el: Element | string, cb: Function, altLimit: boolean = true) { + +type TAddEventCb = (e: Event) => void +type TAddEventObj = { + attachEvent?: HTMLElement["addEventListener"] +} & HTMLElement + +export default function(el: HTMLElement | string, cb: Function, altLimit: boolean = true) { const box = typeof el === 'string' ? document.getElementById(el) : el + if (!box) return; addEvent(box, 'mousewheel', (e: any) => { const ev = e || window.event const down = ev.wheelDelta ? ev.wheelDelta < 0 : ev.detail > 0 @@ -16,10 +23,7 @@ export default function(el: Element | string, cb: Function, altLimit: boolean = // } else { // console.log('鼠标滚轮向上++++++++++') // } - if (altLimit && store.getters.dAltDown) { - ev.preventDefault() - cb(down) - } else if (!altLimit) { + if ((altLimit && store.getters.dAltDown) || !altLimit) { ev.preventDefault() cb(down) } @@ -27,7 +31,7 @@ export default function(el: Element | string, cb: Function, altLimit: boolean = }) } -function addEvent(obj: any, xEvent: string, fn: Function) { +function addEvent(obj: TAddEventObj, xEvent: keyof HTMLElementEventMap, fn: TAddEventCb) { if (obj.attachEvent) { obj.attachEvent('on' + xEvent, fn) } else { diff --git a/src/common/methods/confirm.ts b/src/common/methods/confirm.ts index 49d3b51..fac9901 100644 --- a/src/common/methods/confirm.ts +++ b/src/common/methods/confirm.ts @@ -2,11 +2,11 @@ * @Author: ShawnPhang * @Date: 2022-02-03 16:30:18 * @Description: Type: success / info / warning / error - * @LastEditors: ShawnPhang - * @LastEditTime: 2022-02-03 16:43:01 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ -import { ElMessageBox } from 'element-plus' -export default (title: string = '提示', message: string = '', type: any = 'success') => { +import { ElMessageBox, messageType } from 'element-plus' +export default (title: string = '提示', message: string = '', type: messageType = 'success') => { return new Promise((resolve: Function) => { ElMessageBox.confirm(message, title, { confirmButtonText: '确定', diff --git a/src/common/methods/download/download.ts b/src/common/methods/download/download.ts index 9a82513..8dfa43d 100644 --- a/src/common/methods/download/download.ts +++ b/src/common/methods/download/download.ts @@ -2,11 +2,14 @@ * @Author: ShawnPhang * @Date: 2021-09-30 15:52:59 * @Description: 下载远程图片 - * @LastEditors: ShawnPhang - * @LastEditTime: 2023-07-12 16:54:51 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ -export default (src: string, cb: Function) => { - return new Promise((resolve: any) => { + +type TCallBack = (progress: number, xhr: XMLHttpRequest) => void + +export default (src: string, cb: TCallBack) => { + return new Promise((resolve) => { // const image = new Image() // // 解决跨域 Canvas 污染问题 // image.setAttribute('crossOrigin', 'anonymous') @@ -32,10 +35,10 @@ export default (src: string, cb: Function) => { fetchImageDataFromUrl(src, (progress: number, xhr: XMLHttpRequest) => { cb(progress, xhr) - }).then((res: any) => { + }).then((res) => { const reader = new FileReader() reader.onload = function (event) { - const txt: any = event?.target?.result + const txt = event?.target?.result as string // image.src = txt const a = document.createElement('a') const mE = new MouseEvent('click') @@ -55,17 +58,17 @@ export default (src: string, cb: Function) => { }) } -function fetchImageDataFromUrl(url: string, cb: Function) { - return new Promise((resolve) => { +function fetchImageDataFromUrl(url: string, cb: TCallBack) { + return new Promise((resolve) => { const xhr = new XMLHttpRequest() - let totalLength: any = '' + let totalLength: string | number = '' xhr.open('GET', url) xhr.responseType = 'blob' xhr.onreadystatechange = function () { totalLength = Number(xhr.getResponseHeader('content-length')) // 'cache-control' } xhr.onprogress = function (event) { - cb((event.loaded / totalLength) * 100, xhr) + cb((event.loaded / Number(totalLength)) * 100, xhr) } xhr.onload = function () { if (xhr.status < 400) resolve(this.response) diff --git a/src/common/methods/fonts/index.ts b/src/common/methods/fonts/index.ts index 8e38d12..9f5dacc 100644 --- a/src/common/methods/fonts/index.ts +++ b/src/common/methods/fonts/index.ts @@ -6,11 +6,14 @@ * @LastEditTime: 2023-10-13 01:30:33 */ // import { isSupportFontFamily, blob2Base64 } from './utils' -import { getFonts } from '@/api/material' +import { TGetFontItemData, getFonts } from '@/api/material' const nowVersion = '2' // 当前字体文件版本更新,将刷新前端缓存 -const fontList: any = [] +/** 字体item类型 */ +export type TFontItemData = { url: string } & Omit + +const fontList: TFontItemData[] = [] // const download: any = {} export const useFontStore = { list: fontList, @@ -18,7 +21,7 @@ export const useFontStore = { async init() { this.list = [] localStorage.getItem('FONTS_VERSION') !== nowVersion && localStorage.removeItem('FONTS') - const localFonts: any = localStorage.getItem('FONTS') ? JSON.parse(localStorage.getItem('FONTS') || '') : [] + const localFonts: TFontItemData[] = localStorage.getItem('FONTS') ? JSON.parse(localStorage.getItem('FONTS') || '') : [] if (localFonts.length > 0) { this.list.push(...localFonts) } @@ -26,7 +29,7 @@ export const useFontStore = { if (this.list.length === 0) { const res = await getFonts({ pageSize: 400 }) this.list.unshift( - ...res.list.map((x: any) => { + ...res.list.map((x) => { const { id, alias, oid, value, preview, woff, lang } = x return { id, oid, value, preview, alias, url: woff, lang } }), diff --git a/src/common/methods/fonts/utils.ts b/src/common/methods/fonts/utils.ts index b5fc953..3407a18 100644 --- a/src/common/methods/fonts/utils.ts +++ b/src/common/methods/fonts/utils.ts @@ -70,27 +70,27 @@ export function generateFontStyle(name: string, url: string): HTMLStyleElement { } // 找到使用到的所有字体 -export function filterSkyFonts() { - const fonts: string[] = [] - // const textClouds = sky.state.clouds.filter( - // (cloud) => cloud.type === CLOUD_TYPE.text, - // ); - const textClouds: any = [] +// export function filterSkyFonts() { +// const fonts: string[] = [] +// // const textClouds = sky.state.clouds.filter( +// // (cloud) => cloud.type === CLOUD_TYPE.text, +// // ); +// const textClouds: any = [] - ;(textClouds as unknown as CloudText[]).forEach((cloud) => { - // 找到文字组件字体 - if (cloud.fontFamily && !fonts.includes(cloud.fontFamily)) { - fonts.push(cloud.fontFamily) - } - // 找到文字组件子级字体 - cloud.texts.forEach((text) => { - if (text.fontFamily && !fonts.includes(text.fontFamily)) { - fonts.push(text.fontFamily) - } - }) - }) - return fonts -} +// ;(textClouds as unknown as CloudText[]).forEach((cloud) => { +// // 找到文字组件字体 +// if (cloud.fontFamily && !fonts.includes(cloud.fontFamily)) { +// fonts.push(cloud.fontFamily) +// } +// // 找到文字组件子级字体 +// cloud.texts.forEach((text) => { +// if (text.fontFamily && !fonts.includes(text.fontFamily)) { +// fonts.push(text.fontFamily) +// } +// }) +// }) +// return fonts +// } export function base642Blob(b64Data: string, contentType = '', sliceSize = 512) { const byteCharacters = atob(b64Data) diff --git a/src/common/methods/handleTransform.ts b/src/common/methods/handleTransform.ts index aced976..32a64c0 100644 --- a/src/common/methods/handleTransform.ts +++ b/src/common/methods/handleTransform.ts @@ -2,17 +2,17 @@ * @Author: ShawnPhang * @Date: 2022-01-31 10:45:53 * @Description: 用于修改transform字符串 - * @LastEditors: ShawnPhang - * @LastEditTime: 2022-02-18 16:54:13 + * @LastEditors: ShawnPhang , Jeremy Yu + * @LastEditTime: 2024-03-02 11:50:00 */ -export function getTransformAttribute(target: any, attr: string = '') { +export function getTransformAttribute(target: HTMLElement, attr: string = '') { const tf = target.style.transform const iof = tf.indexOf(attr) const half = tf.substring(iof + attr.length + 1) return half.substring(0, half.indexOf(')')) } -export function setTransformAttribute(target: any, attr: string, value: string | number = 0) { +export function setTransformAttribute(target: HTMLElement, attr: string, value: string | number = 0) { const tf = target?.style.transform if (!tf) { return @@ -24,10 +24,10 @@ export function setTransformAttribute(target: any, attr: string, value: string | target.style.transform = FRONT + value + END } -export function getMatrix(params: any) { +export function getMatrix(params: Record) { const result = [] for (const key in params) { - if (Object.prototype.hasOwnProperty.call(params, key)) { + if (Object.hasOwn(params, key)) { result.push(params[key]) } } diff --git a/src/common/methods/target.ts b/src/common/methods/target.ts index 6a7bd50..90d1c60 100644 --- a/src/common/methods/target.ts +++ b/src/common/methods/target.ts @@ -8,17 +8,17 @@ // TODO: Group类型比较特殊,所以需要全量循环并判断是否为group const arr = ['w-text', 'w-image', 'w-svg', 'w-group', 'w-qrcode'] -export function getTarget(currentTarget: any) { - let collector: any[] = [] - let groupTarger: any = null - let saveTarger: any = null +export function getTarget(currentTarget: HTMLElement) { + let collector: string[] = [] + let groupTarger: HTMLElement | null = null + let saveTarger: HTMLElement | null = null return new Promise((resolve) => { - function findTarget(target: any) { + function findTarget(target: HTMLElement | null) { if (!target || target.id === 'page-design') { if (collector.length > 1) { resolve(groupTarger) } else { - resolve(saveTarger || currentTarget) + resolve(saveTarger ?? currentTarget) } return } @@ -37,12 +37,12 @@ export function getTarget(currentTarget: any) { }) } -export function getFinalTarget(currentTarget: any) { - let collector: any[] = [] - let groupTarger: any = null - let saveTarger: any = null +export function getFinalTarget(currentTarget: HTMLElement) { + let collector: string[] = [] + // let groupTarger: HTMLElement | null = null + // let saveTarger: HTMLElement | null = null return new Promise((resolve) => { - function findTarget(target: any) { + function findTarget(target: HTMLElement | null) { if (!target || target.id === 'page-design') { resolve(target) return @@ -51,8 +51,8 @@ export function getFinalTarget(currentTarget: any) { collector = collector.concat( t.filter((x) => { - arr.includes(x) && (saveTarger = target) - x === 'w-group' && (groupTarger = target) + // arr.includes(x) && (saveTarger = target) + // x === 'w-group' && (groupTarger = target) return arr.includes(x) }), ) diff --git a/src/components/business/cropper/CropImage.vue b/src/components/business/cropper/CropImage/CropImage.vue similarity index 98% rename from src/components/business/cropper/CropImage.vue rename to src/components/business/cropper/CropImage/CropImage.vue index 2f5f83c..de50847 100644 --- a/src/components/business/cropper/CropImage.vue +++ b/src/components/business/cropper/CropImage/CropImage.vue @@ -8,7 +8,7 @@