From 1b16514984c764c652e55504ff5e0609b442102c Mon Sep 17 00:00:00 2001 From: pipipi-pikachu Date: Wed, 10 Feb 2021 16:35:11 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Contextmenu/index.vue | 10 +++++----- src/main.ts | 23 +++++++++++++---------- src/plugins/contextmenu.ts | 4 ++++ src/utils/clipboard.ts | 5 ++++- src/utils/common.ts | 11 +++++++++-- src/utils/crypto.ts | 10 ++++++++-- src/utils/element.ts | 28 +++++++++++++++++++--------- src/utils/fontFamily.ts | 11 ++++++++--- src/utils/image.ts | 10 ++++++++-- src/utils/selection.ts | 1 + 10 files changed, 79 insertions(+), 34 deletions(-) diff --git a/src/components/Contextmenu/index.vue b/src/components/Contextmenu/index.vue index cff392b8..6a1b262d 100644 --- a/src/components/Contextmenu/index.vue +++ b/src/components/Contextmenu/index.vue @@ -26,11 +26,6 @@ import { ContextmenuItem, Axis } from './types' import MenuContent from './MenuContent.vue' -const MENU_WIDTH = 170 -const MENU_HEIGHT = 30 -const DIVIDER_HEIGHT = 11 -const PADDING = 5 - export default defineComponent({ name: 'contextmenu', components: { @@ -56,6 +51,11 @@ export default defineComponent({ }, setup(props) { const style = computed(() => { + const MENU_WIDTH = 170 + const MENU_HEIGHT = 30 + const DIVIDER_HEIGHT = 11 + const PADDING = 5 + const { x, y } = props.axis const menuCount = props.menus.filter(menu => !(menu.divider || menu.hide)).length const dividerCount = props.menus.filter(menu => menu.divider).length diff --git a/src/main.ts b/src/main.ts index 6b731d65..f0f10948 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,16 +10,19 @@ import '@/assets/styles/antd.scss' import '@/assets/styles/font.scss' import 'animate.css' +// 自定义插件 import Contextmenu from './plugins/contextmenu' import ClickOutside from './plugins/clickOutside' import IconPark from './plugins/iconPark' +// 自定义组件 import FileInput from '@/components/FileInput.vue' import SvgWrapper from '@/components/SvgWrapper.vue' import CheckboxButton from '@/components/CheckboxButton.vue' import CheckboxButtonGroup from '@/components/CheckboxButtonGroup.vue' import ColorPicker from '@/components/ColorPicker/index.vue' +// antd 组件 import { InputNumber, Divider, @@ -40,6 +43,16 @@ import { const app = createApp(App) +app.directive('contextmenu', Contextmenu) +app.directive('click-outside', ClickOutside) +app.use(IconPark) + +app.component('FileInput', FileInput) +app.component('SvgWrapper', SvgWrapper) +app.component('CheckboxButton', CheckboxButton) +app.component('CheckboxButtonGroup', CheckboxButtonGroup) +app.component('ColorPicker', ColorPicker) + app.component('InputNumber', InputNumber) app.component('Divider', Divider) app.component('Button', Button) @@ -63,15 +76,5 @@ app.component('MenuItem', Menu.Item) app.component('Checkbox', Checkbox) app.component('Drawer', Drawer) -app.directive('contextmenu', Contextmenu) -app.directive('click-outside', ClickOutside) -app.use(IconPark) - -app.component('FileInput', FileInput) -app.component('SvgWrapper', SvgWrapper) -app.component('CheckboxButton', CheckboxButton) -app.component('CheckboxButtonGroup', CheckboxButtonGroup) -app.component('ColorPicker', ColorPicker) - app.use(store, key) app.mount('#app') diff --git a/src/plugins/contextmenu.ts b/src/plugins/contextmenu.ts index 46204dfb..21457b97 100644 --- a/src/plugins/contextmenu.ts +++ b/src/plugins/contextmenu.ts @@ -12,6 +12,7 @@ const contextmenuListener = (el: HTMLElement, event: MouseEvent, binding: Direct let container: HTMLDivElement | null = null + // 移除右键菜单并取消相关的事件监听 const removeContextmenu = () => { if (container) { document.body.removeChild(container) @@ -22,6 +23,7 @@ const contextmenuListener = (el: HTMLElement, event: MouseEvent, binding: Direct window.removeEventListener('resize', removeContextmenu) } + // 创建自定义菜单 const options = { axis: { x: event.x, y: event.y }, el, @@ -33,8 +35,10 @@ const contextmenuListener = (el: HTMLElement, event: MouseEvent, binding: Direct render(vm, container) document.body.appendChild(container) + // 为目标节点添加菜单激活状态的className el.classList.add('contextmenu-active') + // 页面变化时移除菜单 document.body.addEventListener('scroll', removeContextmenu) window.addEventListener('resize', removeContextmenu) } diff --git a/src/utils/clipboard.ts b/src/utils/clipboard.ts index 2772936d..6dc1607f 100644 --- a/src/utils/clipboard.ts +++ b/src/utils/clipboard.ts @@ -1,6 +1,9 @@ import Clipboard from 'clipboard' -// 复制文本到剪贴板 +/** + * 复制文本到剪贴板 + * @param text 文本内容 + */ export const copyText = (text: string) => { return new Promise((resolve, reject) => { const fakeElement = document.createElement('button') diff --git a/src/utils/common.ts b/src/utils/common.ts index 257452c9..ce0c09c6 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,6 +1,9 @@ import padStart from 'lodash/padStart' -// 生成随机码 +/** + * 生成随机码 + * @param len 随机码长度 + */ export const createRandomCode = (len = 6) => { const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz` const maxLen = charset.length @@ -12,7 +15,11 @@ export const createRandomCode = (len = 6) => { return ret } -// 数字补足位数,例如将6补足3位 -> 003 +/** + * 补足数字位数 + * @param digit 数字 + * @param len 位数 + */ export const fillDigit = (digit: number, len: number) => { return padStart('' + digit, len, '0') } \ No newline at end of file diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts index 9278af63..21b78213 100644 --- a/src/utils/crypto.ts +++ b/src/utils/crypto.ts @@ -2,12 +2,18 @@ import CryptoJS from 'crypto-js' const CRYPTO_KEY = 'pptist' -// 加密函数 +/** + * 加密 + * @param msg 待加密字符串 + */ export const encrypt = (msg: string) => { return CryptoJS.AES.encrypt(msg, CRYPTO_KEY).toString() } -// 解密函数 +/** + * 解密 + * @param ciphertext 待解密字符串 + */ export const decrypt = (ciphertext: string) => { const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY) return bytes.toString(CryptoJS.enc.Utf8) diff --git a/src/utils/element.ts b/src/utils/element.ts index 567c3516..3e6dd64f 100644 --- a/src/utils/element.ts +++ b/src/utils/element.ts @@ -1,6 +1,5 @@ import { PPTElement } from '@/types/slides' -// 获取矩形旋转后在画布中的位置范围 interface RotatedElementData { left: number; top: number; @@ -8,6 +7,11 @@ interface RotatedElementData { height: number; rotate: number; } + +/** + * 计算元素在画布中的矩形范围旋转后的新位置范围 + * @param element 元素的位置大小和旋转角度信息 + */ export const getRectRotatedRange = (element: RotatedElementData) => { const { left, top, width, height, rotate = 0 } = element @@ -17,11 +21,8 @@ export const getRectRotatedRange = (element: RotatedElementData) => { const tlbraRadian = (180 - rotate - auxiliaryAngle) * Math.PI / 180 const trblaRadian = (auxiliaryAngle - rotate) * Math.PI / 180 - const halfWidth = width / 2 - const halfHeight = height / 2 - - const middleLeft = left + halfWidth - const middleTop = top + halfHeight + const middleLeft = left + width / 2 + const middleTop = top + height / 2 const xAxis = [ middleLeft + radius * Math.cos(tlbraRadian), @@ -42,7 +43,10 @@ export const getRectRotatedRange = (element: RotatedElementData) => { } } -// 获取元素在画布中的位置范围 +/** + * 计算元素在画布中的位置范围 + * @param element 元素信息 + */ export const getElementRange = (element: PPTElement) => { let minX, maxX, minY, maxY @@ -69,7 +73,10 @@ export const getElementRange = (element: PPTElement) => { return { minX, maxX, minY, maxY } } -// 获取元素集合在画布中的位置范围 +/** + * 计算一组元素在画布中的位置范围 + * @param elementList 一组元素信息 + */ export const getElementListRange = (elementList: PPTElement[]) => { const leftValues: number[] = [] const topValues: number[] = [] @@ -97,7 +104,10 @@ export interface AlignLine { range: [number, number]; } -// 对齐参考线去重,对于相同位置的多条参考线,取长度范围的最小值和最大值,并基于此范围将多条参考线合并为一条 +/** + * 将一组参考线进行去重:同位置的的多条参考线仅留下一条,取该位置所有参考线的最大值和最小值为新的范围 + * @param lines 一组参考线信息 + */ export const uniqAlignLines = (lines: AlignLine[]) => { const uniqLines: AlignLine[] = [] lines.forEach(line => { diff --git a/src/utils/fontFamily.ts b/src/utils/fontFamily.ts index a6531405..75188e5e 100644 --- a/src/utils/fontFamily.ts +++ b/src/utils/fontFamily.ts @@ -1,12 +1,17 @@ -// 判断用户的操作系统是否安装了某字体 +/** + * 判断操作系统是否存在某字体 + * @param fontFamily 字体名 + */ export const isSupportFontFamily = (fontFamily: string) => { if (typeof fontFamily !== 'string') return false + const arial = 'Arial' if (fontFamily.toLowerCase() === arial.toLowerCase()) return true - const a = 'a' + const size = 100 const width = 100 const height = 100 + const str = 'a' const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') @@ -22,7 +27,7 @@ export const isSupportFontFamily = (fontFamily: string) => { const getDotArray = (_fontFamily: string) => { ctx.clearRect(0, 0, width, height) ctx.font = `${size}px ${_fontFamily}, ${arial}` - ctx.fillText(a, width / 2, height / 2) + ctx.fillText(str, width / 2, height / 2) const imageData = ctx.getImageData(0, 0, width, height).data return [].slice.call(imageData).filter(item => item !== 0) } diff --git a/src/utils/image.ts b/src/utils/image.ts index 84e7f806..ac7881b4 100644 --- a/src/utils/image.ts +++ b/src/utils/image.ts @@ -3,7 +3,10 @@ interface ImageSize { height: number; } -// 获取图片的原始宽高 +/** + * 获取图片的原始宽高 + * @param src 图片地址 + */ export const getImageSize = (src: string): Promise => { return new Promise(resolve => { const img = document.createElement('img') @@ -30,7 +33,10 @@ export const getImageSize = (src: string): Promise => { }) } -// 获取图片文件的dataURL +/** + * 读取图片文件的dataURL + * @param file 图片文件 + */ export const getImageDataURL = (file: File): Promise => { return new Promise(resolve => { const reader = new FileReader() diff --git a/src/utils/selection.ts b/src/utils/selection.ts index 01b2de1f..3ab533fc 100644 --- a/src/utils/selection.ts +++ b/src/utils/selection.ts @@ -1,3 +1,4 @@ +// 清除文字选区 export const removeAllRanges = () => { const selection = window.getSelection() selection && selection.removeAllRanges()