update
This commit is contained in:
parent
7f301cadfd
commit
c218a4ba5a
|
@ -1,4 +1,4 @@
|
|||
const DEFAULT_COLOR = '#888'
|
||||
const DEFAULT_COLOR = '#41464b'
|
||||
|
||||
export const DEFAULT_TEXT = {
|
||||
type: 'text',
|
||||
|
@ -6,12 +6,10 @@ export const DEFAULT_TEXT = {
|
|||
top: 0,
|
||||
width: 300,
|
||||
height: 0,
|
||||
padding: 5,
|
||||
opacity: 1,
|
||||
lineHeight: 1.5,
|
||||
segmentSpacing: 5,
|
||||
textType: 'content',
|
||||
content: '<div>“单击此处添加文本”</div>',
|
||||
content: '请输入内容',
|
||||
}
|
||||
|
||||
export const DEFAULT_IMAGE = {
|
||||
|
@ -27,25 +25,6 @@ export const DEFAULT_SHAPE = {
|
|||
lockRatio: false,
|
||||
}
|
||||
|
||||
export const DEFAULT_SHAPE_LINE = {
|
||||
type: 'shape',
|
||||
borderStyle: 'solid',
|
||||
borderWidth: 2,
|
||||
borderColor: DEFAULT_COLOR,
|
||||
fill: 'rgba(0, 0, 0, 0)',
|
||||
lockRatio: false,
|
||||
}
|
||||
|
||||
export const DEFAULT_ICON = {
|
||||
type: 'icon',
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 80,
|
||||
height: 80,
|
||||
color: DEFAULT_COLOR,
|
||||
lockRatio: true,
|
||||
}
|
||||
|
||||
export const DEFAULT_LINE = {
|
||||
type: 'line',
|
||||
style: 'solid',
|
||||
|
@ -62,14 +41,6 @@ export const DEFAULT_CHART = {
|
|||
height: 500,
|
||||
}
|
||||
|
||||
export const DEFAULT_IFRAME = {
|
||||
type: 'iframe',
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 800,
|
||||
height: 480,
|
||||
}
|
||||
|
||||
export const DEFAULT_TABLE = {
|
||||
type: 'table',
|
||||
left: 0,
|
||||
|
|
|
@ -18,12 +18,10 @@ export const slides: Slide[] = [
|
|||
borderColor: '#5b7d89',
|
||||
fill: 'rgba(220,220,220,0.8)',
|
||||
shadow: '1px 1px 3px rgba(10,10,10,.5)',
|
||||
padding: 10,
|
||||
opacity: 1,
|
||||
lineHeight: 1.5,
|
||||
segmentSpacing: 10,
|
||||
isLock: false,
|
||||
textType: 'title',
|
||||
content: '<div style=\'text-align: center;\'><span style=\'font-size: 28px;\'><span style=\'color: rgb(232, 107, 153); font-weight: bold;\'>一段测试文字</span>,字号固定为<span style=\'font-weight: bold; font-style: italic; text-decoration-line: underline;\'>28px</span></span></div>',
|
||||
},
|
||||
{
|
||||
|
@ -79,12 +77,10 @@ export const slides: Slide[] = [
|
|||
width: 220,
|
||||
height: 188,
|
||||
rotate: 0,
|
||||
padding: 10,
|
||||
opacity: 1,
|
||||
lineHeight: 1.5,
|
||||
segmentSpacing: 10,
|
||||
isLock: false,
|
||||
textType: 'content',
|
||||
content: '<div>😀 😐 😶 😜 🔔 ⭐ ⚡ 🔥 👍 💡 🔰 🎀 🎁 🥇 🏅 🏆 🎈 🎉 💎 🚧 ⛔ 📢 ⌛ ⏰ 🕒 🧩 🎵 📎 🔒 🔑 ⛳ 📌 📍 💬 📅 📈 📋 📜 📁 📱 💻 💾 🌏 🚚 🚡 🚢💧 🌐 🧭 💰 💳 🛒</div>',
|
||||
},
|
||||
],
|
||||
|
|
|
@ -2,7 +2,7 @@ import { MutationTypes } from './constants'
|
|||
import { State } from './state'
|
||||
import { Slide, PPTElement } from '@/types/slides'
|
||||
import { FONT_NAMES } from '@/configs/fontName'
|
||||
import { isSupportFontFamily } from '@/utils/index'
|
||||
import { isSupportFontFamily } from '@/utils/fontFamily'
|
||||
|
||||
interface AddSlidesData {
|
||||
index?: number;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export type ElementType = 'text' | 'image' | 'shape' | 'line' | 'chart' | 'table'
|
||||
|
||||
export interface PPTElementBaseProps {
|
||||
elId: string;
|
||||
isLock: boolean;
|
||||
|
@ -51,8 +53,6 @@ export interface PPTShapeElement extends PPTElementBaseProps, PPTElementSizeProp
|
|||
rotate?: number;
|
||||
opacity?: number;
|
||||
shadow?: string;
|
||||
text?: string;
|
||||
textAlign?: string;
|
||||
}
|
||||
|
||||
export interface PPTLineElement extends PPTElementBaseProps {
|
||||
|
@ -73,7 +73,7 @@ export interface PPTChartElement extends PPTElementBaseProps, PPTElementSizeProp
|
|||
data: Object;
|
||||
}
|
||||
|
||||
export interface TableCell {
|
||||
export interface TableElementCell {
|
||||
colspan: number;
|
||||
rowspan: number;
|
||||
content: string;
|
||||
|
@ -85,7 +85,7 @@ export interface PPTTableElement extends PPTElementBaseProps, PPTElementSizeProp
|
|||
theme: string;
|
||||
rowSizes: number[];
|
||||
colSizes: number[];
|
||||
data: TableCell[][];
|
||||
data: TableElementCell[][];
|
||||
}
|
||||
|
||||
export type PPTElement = PPTTextElement |
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import Clipboard from 'clipboard'
|
||||
|
||||
// 复制文本到剪贴板
|
||||
export const copyText = (text: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fakeElement = document.createElement('button')
|
||||
const clipboard = new Clipboard(fakeElement, {
|
||||
text: () => text,
|
||||
action: () => 'copy',
|
||||
container: document.body,
|
||||
})
|
||||
clipboard.on('success', e => {
|
||||
clipboard.destroy()
|
||||
resolve(e)
|
||||
})
|
||||
clipboard.on('error', e => {
|
||||
clipboard.destroy()
|
||||
reject(e)
|
||||
})
|
||||
document.body.appendChild(fakeElement)
|
||||
fakeElement.click()
|
||||
document.body.removeChild(fakeElement)
|
||||
})
|
||||
}
|
||||
|
||||
// 读取剪贴板
|
||||
export const readClipboard = () => {
|
||||
if(navigator.clipboard) {
|
||||
navigator.clipboard.readText().then(text => {
|
||||
if(!text) return { err: '剪贴板为空或者不包含文本' }
|
||||
return { text }
|
||||
})
|
||||
}
|
||||
return { err: '浏览器不支持或禁止访问剪贴板' }
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import padStart from 'lodash/padStart'
|
||||
|
||||
// 生成随机码
|
||||
export const createRandomCode = (len = 6) => {
|
||||
const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
|
||||
const maxLen = charset.length
|
||||
let ret = ''
|
||||
for(let i = 0; i < len; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * maxLen)
|
||||
ret += charset[randomIndex]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 数字补足位数,例如将6补足3位 -> 003
|
||||
export const fillDigit = (digit: number, len: number) => {
|
||||
return padStart('' + digit, len, '0')
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const CRYPTO_KEY = 'zxc_ppt_online_editor'
|
||||
|
||||
// 加密函数
|
||||
export const encrypt = (msg: string) => {
|
||||
return CryptoJS.AES.encrypt(msg, CRYPTO_KEY).toString()
|
||||
}
|
||||
|
||||
// 解密函数
|
||||
export const decrypt = (ciphertext: string) => {
|
||||
const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY)
|
||||
return bytes.toString(CryptoJS.enc.Utf8)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// 判断用户的操作系统是否安装了某字体
|
||||
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 canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
if(!ctx) return false
|
||||
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const getDotArray = (_fontFamily: string) => {
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
ctx.font = `${size}px ${_fontFamily}, ${arial}`
|
||||
ctx.fillText(a, width / 2, height / 2)
|
||||
const imageData = ctx.getImageData(0, 0, width, height).data
|
||||
return [].slice.call(imageData).filter(item => item !== 0)
|
||||
}
|
||||
|
||||
return getDotArray(arial).join('') !== getDotArray(fontFamily).join('')
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// 进入全屏
|
||||
export const enterFullscreen = document.documentElement.requestFullscreen
|
||||
|
||||
// 退出全屏
|
||||
export const exitFullscreen = document.exitFullscreen
|
||||
|
||||
// 判断是否全屏
|
||||
export const isFullscreen = () => document.fullscreenEnabled
|
|
@ -0,0 +1,42 @@
|
|||
interface ImageSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
// 获取图片的原始宽高
|
||||
export const getImageSize = (imgUrl: string): Promise<ImageSize> => {
|
||||
return new Promise(resolve => {
|
||||
const img = document.createElement('img')
|
||||
img.src = imgUrl
|
||||
img.style.opacity = '0'
|
||||
document.body.appendChild(img)
|
||||
|
||||
img.onload = () => {
|
||||
const imgWidth = img.clientWidth
|
||||
const imgHeight = img.clientHeight
|
||||
|
||||
img.onload = null
|
||||
img.onerror = null
|
||||
|
||||
document.body.removeChild(img)
|
||||
|
||||
resolve({ width: imgWidth, height: imgHeight })
|
||||
}
|
||||
|
||||
img.onerror = () => {
|
||||
img.onload = null
|
||||
img.onerror = null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取图片文件的dataURL
|
||||
export const getImageDataURL = (file: File): Promise<string> => {
|
||||
return new Promise(resolve => {
|
||||
const reader = new FileReader()
|
||||
reader.addEventListener('load', () => {
|
||||
resolve(reader.result as string)
|
||||
})
|
||||
reader.readAsDataURL(file)
|
||||
})
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
import padStart from 'lodash/padStart'
|
||||
import Clipboard from 'clipboard'
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const CRYPTO_KEY = 'zxc_ppt_online_editor'
|
||||
|
||||
// 生成随机数
|
||||
export const createRandomNumber = (min: number, max: number) => {
|
||||
return Math.floor(min + Math.random() * (max - min))
|
||||
}
|
||||
|
||||
// 生成随机码
|
||||
export const createRandomCode = (len = 6) => {
|
||||
const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
|
||||
const maxLen = charset.length
|
||||
let ret = ''
|
||||
for(let i = 0; i < len; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * maxLen)
|
||||
ret += charset[randomIndex]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 生成uuid
|
||||
export const createUUID = () => {
|
||||
const url = URL.createObjectURL(new Blob())
|
||||
const uuid = url.toString()
|
||||
URL.revokeObjectURL(url)
|
||||
return uuid.substr(uuid.lastIndexOf('/') + 1)
|
||||
}
|
||||
|
||||
// 获取当前日期字符串
|
||||
export const getDateTime = (format = 'yyyy-MM-dd hh:mm:ss') => {
|
||||
const date = new Date()
|
||||
|
||||
const formatMap = {
|
||||
'y+': date.getFullYear(),
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds(),
|
||||
}
|
||||
|
||||
for(const item of Object.keys(formatMap)) {
|
||||
if(new RegExp('(' + item + ')').test(format)) {
|
||||
const formated = (formatMap[item] + '').length < RegExp.$1.length ? padStart('' + formatMap[item], RegExp.$1.length, '0') : formatMap[item]
|
||||
format = format.replace(RegExp.$1, formated)
|
||||
}
|
||||
}
|
||||
return format
|
||||
}
|
||||
|
||||
// 数字转中文,如1049 -> 一千零四十九
|
||||
export const digitalToChinese = (n: number) => {
|
||||
const str = n + ''
|
||||
const len = str.length - 1
|
||||
const idxs = ['', '十', '百', '千']
|
||||
const num = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
|
||||
return str.replace(/([1-9]|0+)/g, ($, $1, idx) => {
|
||||
const pos = len - idx
|
||||
if($1 !== 0) {
|
||||
if(idx === 0 && $1 === 1 && idxs[pos] === '十') return idxs[pos]
|
||||
return num[$1] + idxs[pos]
|
||||
}
|
||||
if(idx + $1.length >= str.length) return ''
|
||||
return '零'
|
||||
})
|
||||
}
|
||||
|
||||
// 数字补足位数,例如将6补足3位 -> 003
|
||||
export const fillDigit = (digit: number, len: number) => {
|
||||
return padStart('' + digit, len, '0')
|
||||
}
|
||||
|
||||
// 进入全屏
|
||||
export const enterFullscreen = () => {
|
||||
const docElm = document.documentElement
|
||||
docElm.requestFullscreen()
|
||||
}
|
||||
|
||||
// 退出全屏
|
||||
export const exitFullscreen = document.exitFullscreen
|
||||
|
||||
// 判断是否全屏
|
||||
export const isFullscreen = () => document.fullscreenEnabled
|
||||
|
||||
// 判断用户的操作系统是否安装了某字体
|
||||
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 canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
if(!ctx) return false
|
||||
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.textBaseline = 'middle'
|
||||
|
||||
const getDotArray = (_fontFamily: string) => {
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
ctx.font = `${size}px ${_fontFamily}, ${arial}`
|
||||
ctx.fillText(a, width / 2, height / 2)
|
||||
const imageData = ctx.getImageData(0, 0, width, height).data
|
||||
return [].slice.call(imageData).filter(item => item !== 0)
|
||||
}
|
||||
|
||||
return getDotArray(arial).join('') !== getDotArray(fontFamily).join('')
|
||||
}
|
||||
|
||||
// 获取图片的原始宽高
|
||||
export const getImageSize = (imgUrl: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = document.createElement('img')
|
||||
img.src = imgUrl
|
||||
img.style.opacity = '0'
|
||||
document.body.appendChild(img)
|
||||
|
||||
img.onload = () => {
|
||||
const imgWidth = img.clientWidth
|
||||
const imgHeight = img.clientHeight
|
||||
|
||||
img.onload = null
|
||||
img.onerror = null
|
||||
|
||||
document.body.removeChild(img)
|
||||
|
||||
resolve({ imgWidth, imgHeight })
|
||||
}
|
||||
|
||||
img.onerror = () => {
|
||||
img.onload = null
|
||||
img.onerror = null
|
||||
|
||||
reject('图片加载失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 复制文本到剪贴板
|
||||
export const copyText = (text: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fakeElement = document.createElement('button')
|
||||
const clipboard = new Clipboard(fakeElement, {
|
||||
text: () => text,
|
||||
action: () => 'copy',
|
||||
container: document.body,
|
||||
})
|
||||
clipboard.on('success', e => {
|
||||
clipboard.destroy()
|
||||
resolve(e)
|
||||
})
|
||||
clipboard.on('error', e => {
|
||||
clipboard.destroy()
|
||||
reject(e)
|
||||
})
|
||||
document.body.appendChild(fakeElement)
|
||||
fakeElement.click()
|
||||
document.body.removeChild(fakeElement)
|
||||
})
|
||||
}
|
||||
|
||||
// 读取剪贴板
|
||||
export const readClipboard = () => {
|
||||
if(navigator.clipboard) {
|
||||
navigator.clipboard.readText().then(text => {
|
||||
if(!text) return { err: '剪贴板为空或者不包含文本' }
|
||||
return { text }
|
||||
})
|
||||
}
|
||||
return { err: '浏览器不支持或禁止访问剪贴板' }
|
||||
}
|
||||
|
||||
// 加密函数
|
||||
export const encrypt = (msg: string) => {
|
||||
return CryptoJS.AES.encrypt(msg, CRYPTO_KEY).toString()
|
||||
}
|
||||
|
||||
// 解密函数
|
||||
export const decrypt = (ciphertext: string) => {
|
||||
const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY)
|
||||
return bytes.toString(CryptoJS.enc.Utf8)
|
||||
}
|
||||
|
||||
// 获取DOM节点样式
|
||||
export const getStyle = (el: HTMLElement, style: string) => {
|
||||
if(!el) return null
|
||||
return window.getComputedStyle(el, null).getPropertyValue(style)
|
||||
}
|
||||
|
||||
// 检查元素是否处在可视区域内
|
||||
export const checkElementInViewport = (el: HTMLElement) => {
|
||||
const rect = el.getBoundingClientRect()
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
rect.left >= 0 &&
|
||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||
)
|
||||
}
|
|
@ -46,6 +46,7 @@ import { State } from '@/store/state'
|
|||
import { MutationTypes } from '@/store/constants'
|
||||
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||
import { getImageDataURL } from '@/utils/image'
|
||||
|
||||
import useDropImage from '@/hooks/useDropImage'
|
||||
|
||||
|
@ -67,7 +68,11 @@ export default defineComponent({
|
|||
|
||||
const dropImageFile = useDropImage(viewportRef)
|
||||
watch(dropImageFile, () => {
|
||||
console.log(dropImageFile.value)
|
||||
if(dropImageFile.value) {
|
||||
getImageDataURL(dropImageFile.value).then(dataURL => {
|
||||
console.log(dataURL)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const viewportStyles = reactive({
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import { createRandomCode } from '@/utils/common'
|
||||
import { getImageSize } from '@/utils/image'
|
||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||
import { TableElementCell } from '@/types/slides'
|
||||
import {
|
||||
DEFAULT_IMAGE,
|
||||
DEFAULT_TEXT,
|
||||
DEFAULT_SHAPE,
|
||||
DEFAULT_LINE,
|
||||
DEFAULT_CHART,
|
||||
DEFAULT_TABLE,
|
||||
} from '@/configs/defaultElement'
|
||||
|
||||
interface CommonElementPosition {
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface LineElementPosition {
|
||||
top: number;
|
||||
left: number;
|
||||
start: [number, number];
|
||||
end: [number, number];
|
||||
}
|
||||
|
||||
export const insertImage = (imgUrl: string) => {
|
||||
getImageSize(imgUrl).then(({ width, height }) => {
|
||||
const scale = width / height
|
||||
|
||||
if(scale < VIEWPORT_ASPECT_RATIO && width > VIEWPORT_SIZE) {
|
||||
width = VIEWPORT_SIZE
|
||||
height = width * scale
|
||||
}
|
||||
else if(height > VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO) {
|
||||
height = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO
|
||||
width = height / scale
|
||||
}
|
||||
|
||||
return {
|
||||
...DEFAULT_IMAGE,
|
||||
elId: createRandomCode(),
|
||||
imgUrl,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const insertChart = (chartType: string, data: Object) => {
|
||||
return {
|
||||
...DEFAULT_CHART,
|
||||
elId: createRandomCode(),
|
||||
chartType,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
export const insertTable = (rowCount: number, colCount: number) => {
|
||||
const row: TableElementCell[] = new Array(colCount).fill({ colspan: 1, rowspan: 1, content: '' })
|
||||
const data: TableElementCell[][] = new Array(rowCount).fill(row)
|
||||
|
||||
const DEFAULT_CELL_WIDTH = 80
|
||||
const DEFAULT_CELL_HEIGHT = 35
|
||||
const DEFAULT_BORDER_WIDTH = 2
|
||||
|
||||
const colSizes: number[] = new Array(colCount).fill(DEFAULT_CELL_WIDTH)
|
||||
const rowSizes: number[] = new Array(rowCount).fill(DEFAULT_CELL_HEIGHT)
|
||||
|
||||
return {
|
||||
...DEFAULT_TABLE,
|
||||
elId: createRandomCode(),
|
||||
width: colCount * DEFAULT_CELL_WIDTH + DEFAULT_BORDER_WIDTH,
|
||||
height: rowCount * DEFAULT_CELL_HEIGHT + DEFAULT_BORDER_WIDTH,
|
||||
colSizes,
|
||||
rowSizes,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
export const insertText = (position: CommonElementPosition) => {
|
||||
const { left, top, width, height } = position
|
||||
return {
|
||||
...DEFAULT_TEXT,
|
||||
elId: createRandomCode(),
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
export const insertShape = (position: CommonElementPosition, svgCode: string) => {
|
||||
const { left, top, width, height } = position
|
||||
return {
|
||||
...DEFAULT_SHAPE,
|
||||
elId: createRandomCode(),
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
svgCode,
|
||||
}
|
||||
}
|
||||
|
||||
export const insertLine = (position: LineElementPosition, marker: [string, string], lineType: string) => {
|
||||
const { left, top, start, end } = position
|
||||
|
||||
return {
|
||||
...DEFAULT_LINE,
|
||||
elId: createRandomCode(),
|
||||
left,
|
||||
top,
|
||||
start,
|
||||
end,
|
||||
marker,
|
||||
lineType,
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { createRandomCode } from '@/utils/index'
|
||||
import { createRandomCode } from '@/utils/common'
|
||||
import { PPTElement } from '@/types/slides'
|
||||
|
||||
// 组合元素(为当前所有激活元素添加一个相同的groupId)
|
||||
|
|
|
@ -17,7 +17,8 @@ import { computed, defineComponent, onMounted, onUnmounted, ref } from 'vue'
|
|||
import { useStore } from 'vuex'
|
||||
import { State } from '@/store/state'
|
||||
import { KEYCODE } from '@/configs/keyCode'
|
||||
import { decrypt } from '@/utils/index'
|
||||
import { decrypt } from '@/utils/crypto'
|
||||
import { getImageDataURL } from '@/utils/image'
|
||||
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
|
@ -151,7 +152,9 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const pasteImageFile = (imageFile: File) => {
|
||||
console.log(imageFile)
|
||||
getImageDataURL(imageFile).then(dataURL => {
|
||||
console.log(dataURL)
|
||||
})
|
||||
}
|
||||
|
||||
const pasteText = (text: string) => {
|
||||
|
|
Loading…
Reference in New Issue