mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
695 lines
14 KiB
TypeScript
695 lines
14 KiB
TypeScript
import type { BarChartOptions, LineChartOptions, PieChartOptions } from 'chartist'
|
||
|
||
export const enum ShapePathFormulasKeys {
|
||
ROUND_RECT = 'roundRect',
|
||
ROUND_RECT_DIAGONAL = 'roundRectDiagonal',
|
||
ROUND_RECT_SINGLE = 'roundRectSingle',
|
||
ROUND_RECT_SAMESIDE = 'roundRectSameSide',
|
||
CUT_RECT_DIAGONAL = 'cutRectDiagonal',
|
||
CUT_RECT_SINGLE = 'cutRectSingle',
|
||
CUT_RECT_SAMESIDE = 'cutRectSameSide',
|
||
CUT_ROUND_RECT = 'cutRoundRect',
|
||
MESSAGE = 'message',
|
||
ROUND_MESSAGE = 'roundMessage',
|
||
L = 'L',
|
||
RING_RECT = 'ringRect',
|
||
PLUS = 'plus',
|
||
TRIANGLE = 'triangle',
|
||
PARALLELOGRAM_LEFT = 'parallelogramLeft',
|
||
PARALLELOGRAM_RIGHT = 'parallelogramRight',
|
||
TRAPEZOID = 'trapezoid',
|
||
BULLET = 'bullet',
|
||
INDICATOR = 'indicator',
|
||
}
|
||
|
||
export const enum ElementTypes {
|
||
TEXT = 'text',
|
||
IMAGE = 'image',
|
||
SHAPE = 'shape',
|
||
LINE = 'line',
|
||
CHART = 'chart',
|
||
TABLE = 'table',
|
||
LATEX = 'latex',
|
||
VIDEO = 'video',
|
||
AUDIO = 'audio',
|
||
}
|
||
|
||
/**
|
||
* 元素阴影
|
||
*
|
||
* h: 水平偏移量
|
||
*
|
||
* v: 垂直偏移量
|
||
*
|
||
* blur: 模糊程度
|
||
*
|
||
* color: 阴影颜色
|
||
*/
|
||
export interface PPTElementShadow {
|
||
h: number
|
||
v: number
|
||
blur: number
|
||
color: string
|
||
}
|
||
|
||
/**
|
||
* 元素边框
|
||
*
|
||
* style?: 边框样式(实线或虚线)
|
||
*
|
||
* width?: 边框宽度
|
||
*
|
||
* color?: 边框颜色
|
||
*/
|
||
export interface PPTElementOutline {
|
||
style?: 'dashed' | 'solid'
|
||
width?: number
|
||
color?: string
|
||
}
|
||
|
||
/**
|
||
* 元素超链接
|
||
*
|
||
* type: 链接类型(网页、幻灯片页面)
|
||
*
|
||
* target: 目标地址(网页链接、幻灯片页面ID)
|
||
*/
|
||
export interface PPTElementLink {
|
||
type: 'web' | 'slide'
|
||
target: string
|
||
}
|
||
|
||
|
||
/**
|
||
* 元素通用属性
|
||
*
|
||
* id: 元素ID
|
||
*
|
||
* left: 元素水平方向位置(距离画布左侧)
|
||
*
|
||
* top: 元素垂直方向位置(距离画布顶部)
|
||
*
|
||
* lock?: 锁定元素
|
||
*
|
||
* groupId?: 组合ID(拥有相同组合ID的元素即为同一组合元素成员)
|
||
*
|
||
* width: 元素宽度
|
||
*
|
||
* height: 元素高度
|
||
*
|
||
* rotate: 旋转角度
|
||
*
|
||
* link?: 超链接
|
||
*
|
||
* name?: 元素名
|
||
*/
|
||
interface PPTBaseElement {
|
||
id: string
|
||
left: number
|
||
top: number
|
||
lock?: boolean
|
||
groupId?: string
|
||
width: number
|
||
height: number
|
||
rotate: number
|
||
link?: PPTElementLink
|
||
name?: string
|
||
}
|
||
|
||
|
||
/**
|
||
* 文本元素
|
||
*
|
||
* type: 元素类型(text)
|
||
*
|
||
* content: 文本内容(HTML字符串)
|
||
*
|
||
* defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
|
||
*
|
||
* defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
|
||
*
|
||
* outline?: 边框
|
||
*
|
||
* fill?: 填充色
|
||
*
|
||
* lineHeight?: 行高(倍),默认1.5
|
||
*
|
||
* wordSpace?: 字间距,默认0
|
||
*
|
||
* opacity?: 不透明度,默认1
|
||
*
|
||
* shadow?: 阴影
|
||
*
|
||
* paragraphSpace?: 段间距,默认 5px
|
||
*
|
||
* vertical?: 竖向文本
|
||
*/
|
||
export interface PPTTextElement extends PPTBaseElement {
|
||
type: 'text'
|
||
content: string
|
||
defaultFontName: string
|
||
defaultColor: string
|
||
outline?: PPTElementOutline
|
||
fill?: string
|
||
lineHeight?: number
|
||
wordSpace?: number
|
||
opacity?: number
|
||
shadow?: PPTElementShadow
|
||
paragraphSpace?: number
|
||
vertical?: boolean
|
||
}
|
||
|
||
|
||
/**
|
||
* 图片翻转、形状翻转
|
||
*
|
||
* flipH?: 水平翻转
|
||
*
|
||
* flipV?: 垂直翻转
|
||
*/
|
||
export interface ImageOrShapeFlip {
|
||
flipH?: boolean
|
||
flipV?: boolean
|
||
}
|
||
|
||
/**
|
||
* 图片滤镜
|
||
*
|
||
* https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
|
||
*
|
||
* 'blur'?: 模糊,默认0(px)
|
||
*
|
||
* 'brightness'?: 亮度,默认100(%)
|
||
*
|
||
* 'contrast'?: 对比度,默认100(%)
|
||
*
|
||
* 'grayscale'?: 灰度,默认0(%)
|
||
*
|
||
* 'saturate'?: 饱和度,默认100(%)
|
||
*
|
||
* 'hue-rotate'?: 色相旋转,默认0(deg)
|
||
*
|
||
* 'opacity'?: 不透明度,默认100(%)
|
||
*/
|
||
export type ImageElementFilterKeys = 'blur' | 'brightness' | 'contrast' | 'grayscale' | 'saturate' | 'hue-rotate' | 'opacity'
|
||
export interface ImageElementFilters {
|
||
'blur'?: string
|
||
'brightness'?: string
|
||
'contrast'?: string
|
||
'grayscale'?: string
|
||
'saturate'?: string
|
||
'hue-rotate'?: string
|
||
'opacity'?: string
|
||
}
|
||
|
||
export type ImageClipDataRange = [[number, number], [number, number]]
|
||
|
||
/**
|
||
* 图片裁剪
|
||
*
|
||
* range: 裁剪范围,例如:[[10, 10], [90, 90]] 表示裁取原图从左上角 10%, 10% 到 90%, 90% 的范围
|
||
*
|
||
* shape: 裁剪形状,见 configs/imageClip.ts CLIPPATHS
|
||
*/
|
||
export interface ImageElementClip {
|
||
range: ImageClipDataRange
|
||
shape: string
|
||
}
|
||
|
||
/**
|
||
* 图片元素
|
||
*
|
||
* type: 元素类型(image)
|
||
*
|
||
* fixedRatio: 固定图片宽高比例
|
||
*
|
||
* src: 图片地址
|
||
*
|
||
* outline?: 边框
|
||
*
|
||
* filters?: 图片滤镜
|
||
*
|
||
* clip?: 裁剪信息
|
||
*
|
||
* flipH?: 水平翻转
|
||
*
|
||
* flipV?: 垂直翻转
|
||
*
|
||
* shadow?: 阴影
|
||
*/
|
||
export interface PPTImageElement extends PPTBaseElement {
|
||
type: 'image'
|
||
fixedRatio: boolean
|
||
src: string
|
||
outline?: PPTElementOutline
|
||
filters?: ImageElementFilters
|
||
clip?: ImageElementClip
|
||
flipH?: boolean
|
||
flipV?: boolean
|
||
shadow?: PPTElementShadow
|
||
colorMask?: string
|
||
}
|
||
|
||
|
||
/**
|
||
* 形状渐变
|
||
*
|
||
* type: 渐变类型(径向、线性)
|
||
*
|
||
* color: 渐变颜色
|
||
*
|
||
* rotate: 渐变角度(线性渐变)
|
||
*/
|
||
export interface ShapeGradient {
|
||
type: 'linear' | 'radial'
|
||
color: [string, string]
|
||
rotate: number
|
||
}
|
||
|
||
/**
|
||
* 形状内文本
|
||
*
|
||
* content: 文本内容(HTML字符串)
|
||
*
|
||
* defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
|
||
*
|
||
* defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
|
||
*
|
||
* align: 文本对齐方向(垂直方向)
|
||
*/
|
||
export interface ShapeText {
|
||
content: string
|
||
defaultFontName: string
|
||
defaultColor: string
|
||
align: 'top' | 'middle' | 'bottom'
|
||
}
|
||
|
||
/**
|
||
* 形状元素
|
||
*
|
||
* type: 元素类型(shape)
|
||
*
|
||
* viewBox: SVG的viewBox属性,例如 [1000, 1000] 表示 '0 0 1000 1000'
|
||
*
|
||
* path: 形状路径,SVG path 的 d 属性
|
||
*
|
||
* fixedRatio: 固定形状宽高比例
|
||
*
|
||
* fill: 填充,不存在渐变时生效
|
||
*
|
||
* gradient?: 渐变,该属性存在时将优先作为填充
|
||
*
|
||
* outline?: 边框
|
||
*
|
||
* opacity?: 不透明度
|
||
*
|
||
* flipH?: 水平翻转
|
||
*
|
||
* flipV?: 垂直翻转
|
||
*
|
||
* shadow?: 阴影
|
||
*
|
||
* special?: 特殊形状(标记一些难以解析的形状,例如路径使用了 L Q C A 以外的类型,该类形状在导出后将变为图片的形式)
|
||
*
|
||
* text?: 形状内文本
|
||
*
|
||
* pathFormula?: 形状路径计算公式
|
||
* 一般情况下,形状的大小变化时仅由宽高基于 viewBox 的缩放比例来调整形状,而 viewBox 本身和 path 不会变化,
|
||
* 但也有一些形状希望能更精确的控制一些关键点的位置,此时就需要提供路径计算公式,通过在缩放时更新 viewBox 并重新计算 path 来重新绘制形状
|
||
*
|
||
* keypoint?: 关键点位置百分比
|
||
*/
|
||
export interface PPTShapeElement extends PPTBaseElement {
|
||
type: 'shape'
|
||
viewBox: [number, number]
|
||
path: string
|
||
fixedRatio: boolean
|
||
fill: string
|
||
gradient?: ShapeGradient
|
||
outline?: PPTElementOutline
|
||
opacity?: number
|
||
flipH?: boolean
|
||
flipV?: boolean
|
||
shadow?: PPTElementShadow
|
||
special?: boolean
|
||
text?: ShapeText
|
||
pathFormula?: ShapePathFormulasKeys
|
||
keypoint?: number
|
||
}
|
||
|
||
|
||
export type LinePoint = '' | 'arrow' | 'dot'
|
||
|
||
/**
|
||
* 线条元素
|
||
*
|
||
* type: 元素类型(line)
|
||
*
|
||
* start: 起点位置([x, y])
|
||
*
|
||
* end: 终点位置([x, y])
|
||
*
|
||
* style: 线条样式(实线、虚线)
|
||
*
|
||
* color: 线条颜色
|
||
*
|
||
* points: 端点样式([起点样式, 终点样式],可选:无、箭头、圆点)
|
||
*
|
||
* shadow?: 阴影
|
||
*
|
||
* broken?: 折线控制点位置([x, y])
|
||
*
|
||
* curve?: 二次曲线控制点位置([x, y])
|
||
*
|
||
* cubic?: 三次曲线控制点位置([[x1, y1], [x2, y2]])
|
||
*/
|
||
export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'> {
|
||
type: 'line'
|
||
start: [number, number]
|
||
end: [number, number]
|
||
style: 'solid' | 'dashed'
|
||
color: string
|
||
points: [LinePoint, LinePoint]
|
||
shadow?: PPTElementShadow
|
||
broken?: [number, number]
|
||
curve?: [number, number]
|
||
cubic?: [[number, number], [number, number]]
|
||
}
|
||
|
||
|
||
export type PresetChartType = 'bar' | 'horizontalBar' | 'line' | 'area' | 'scatter' | 'pie' | 'ring'
|
||
export type ChartType = 'bar' | 'line' | 'pie'
|
||
export type ChartOptions = LineChartOptions & BarChartOptions & PieChartOptions
|
||
export interface ChartData {
|
||
labels: string[]
|
||
legends: string[]
|
||
series: number[][]
|
||
}
|
||
|
||
/**
|
||
* 图表元素
|
||
*
|
||
* type: 元素类型(chart)
|
||
*
|
||
* fill?: 填充色
|
||
*
|
||
* chartType: 图表基础类型(bar/line/pie),所有图表类型都是由这三种基本类型衍生而来
|
||
*
|
||
* data: 图表数据
|
||
*
|
||
* options?: 图表配置项
|
||
*
|
||
* outline?: 边框
|
||
*
|
||
* themeColor: 主题色
|
||
*
|
||
* gridColor?: 网格&坐标颜色
|
||
*
|
||
* legend?: 图例/位置
|
||
*/
|
||
export interface PPTChartElement extends PPTBaseElement {
|
||
type: 'chart'
|
||
fill?: string
|
||
chartType: ChartType
|
||
data: ChartData
|
||
options?: ChartOptions
|
||
outline?: PPTElementOutline
|
||
themeColor: string[]
|
||
gridColor?: string
|
||
legend?: '' | 'top' | 'bottom'
|
||
}
|
||
|
||
|
||
/**
|
||
* 表格单元格样式
|
||
*
|
||
* bold?: 加粗
|
||
*
|
||
* em?: 斜体
|
||
*
|
||
* underline?: 下划线
|
||
*
|
||
* strikethrough?: 删除线
|
||
*
|
||
* color?: 字体颜色
|
||
*
|
||
* backcolor?: 填充色
|
||
*
|
||
* fontsize?: 字体大小
|
||
*
|
||
* fontname?: 字体
|
||
*
|
||
* align?: 对齐方式
|
||
*/
|
||
export interface TableCellStyle {
|
||
bold?: boolean
|
||
em?: boolean
|
||
underline?: boolean
|
||
strikethrough?: boolean
|
||
color?: string
|
||
backcolor?: string
|
||
fontsize?: string
|
||
fontname?: string
|
||
align?: 'left' | 'center' | 'right'
|
||
}
|
||
|
||
|
||
/**
|
||
* 表格单元格
|
||
*
|
||
* id: 单元格ID
|
||
*
|
||
* colspan: 合并列数
|
||
*
|
||
* rowspan: 合并行数
|
||
*
|
||
* text: 文字内容
|
||
*
|
||
* style?: 单元格样式
|
||
*/
|
||
export interface TableCell {
|
||
id: string
|
||
colspan: number
|
||
rowspan: number
|
||
text: string
|
||
style?: TableCellStyle
|
||
}
|
||
|
||
/**
|
||
* 表格主题
|
||
*
|
||
* color: 主题色
|
||
*
|
||
* rowHeader: 标题行
|
||
*
|
||
* rowFooter: 汇总行
|
||
*
|
||
* colHeader: 第一列
|
||
*
|
||
* colFooter: 最后一列
|
||
*/
|
||
export interface TableTheme {
|
||
color: string
|
||
rowHeader: boolean
|
||
rowFooter: boolean
|
||
colHeader: boolean
|
||
colFooter: boolean
|
||
}
|
||
|
||
/**
|
||
* 表格元素
|
||
*
|
||
* type: 元素类型(table)
|
||
*
|
||
* outline: 边框
|
||
*
|
||
* theme?: 主题
|
||
*
|
||
* colWidths: 列宽数组,如[30, 50, 20]表示三列宽度分别为30%, 50%, 20%
|
||
*
|
||
* cellMinHeight: 单元格最小高度
|
||
*
|
||
* data: 表格数据
|
||
*/
|
||
export interface PPTTableElement extends PPTBaseElement {
|
||
type: 'table'
|
||
outline: PPTElementOutline
|
||
theme?: TableTheme
|
||
colWidths: number[]
|
||
cellMinHeight: number
|
||
data: TableCell[][]
|
||
}
|
||
|
||
|
||
/**
|
||
* LaTeX元素(公式)
|
||
*
|
||
* type: 元素类型(latex)
|
||
*
|
||
* latex: latex代码
|
||
*
|
||
* path: svg path
|
||
*
|
||
* color: 颜色
|
||
*
|
||
* strokeWidth: 路径宽度
|
||
*
|
||
* viewBox: SVG的viewBox属性
|
||
*
|
||
* fixedRatio: 固定形状宽高比例
|
||
*/
|
||
export interface PPTLatexElement extends PPTBaseElement {
|
||
type: 'latex'
|
||
latex: string
|
||
path: string
|
||
color: string
|
||
strokeWidth: number
|
||
viewBox: [number, number]
|
||
fixedRatio: boolean
|
||
}
|
||
|
||
/**
|
||
* 视频元素
|
||
*
|
||
* type: 元素类型(video)
|
||
*
|
||
* src: 视频地址
|
||
*
|
||
* poster: 预览封面
|
||
*
|
||
* ext: 视频后缀,当资源链接缺少后缀时用该字段确认资源类型
|
||
*/
|
||
export interface PPTVideoElement extends PPTBaseElement {
|
||
type: 'video'
|
||
src: string
|
||
poster?: string
|
||
ext?: string
|
||
}
|
||
|
||
/**
|
||
* 音频元素
|
||
*
|
||
* type: 元素类型(audio)
|
||
*
|
||
* fixedRatio: 固定图标宽高比例
|
||
*
|
||
* color: 图标颜色
|
||
*
|
||
* loop: 循环播放
|
||
*
|
||
* autoplay: 自动播放
|
||
*
|
||
* src: 音频地址
|
||
*
|
||
* ext: 音频后缀,当资源链接缺少后缀时用该字段确认资源类型
|
||
*/
|
||
export interface PPTAudioElement extends PPTBaseElement {
|
||
type: 'audio'
|
||
fixedRatio: boolean
|
||
color: string
|
||
loop: boolean
|
||
autoplay: boolean
|
||
src: string
|
||
ext?: string
|
||
}
|
||
|
||
|
||
export type PPTElement = PPTTextElement | PPTImageElement | PPTShapeElement | PPTLineElement | PPTChartElement | PPTTableElement | PPTLatexElement | PPTVideoElement | PPTAudioElement
|
||
|
||
|
||
/**
|
||
* 元素动画
|
||
*
|
||
* id: 动画id
|
||
*
|
||
* elId: 元素ID
|
||
*
|
||
* effect: 动画效果
|
||
*
|
||
* type: 动画类型(入场、退场、强调)
|
||
*
|
||
* duration: 动画持续时间
|
||
*
|
||
* trigger: 动画触发方式(click - 单击时、meantime - 与上一动画同时、auto - 上一动画之后)
|
||
*/
|
||
export interface PPTAnimation {
|
||
id: string
|
||
elId: string
|
||
effect: string
|
||
type: 'in' | 'out' | 'attention'
|
||
duration: number
|
||
trigger: 'click' | 'meantime' | 'auto'
|
||
}
|
||
|
||
/**
|
||
* 幻灯片背景
|
||
*
|
||
* type: 背景类型(纯色、图片、渐变)
|
||
*
|
||
* color?: 背景颜色(纯色)
|
||
*
|
||
* image?: 图片地址(图片)
|
||
*
|
||
* imageSize?: 图片填充方式
|
||
*
|
||
* gradientType?: 渐变类型(线性、径向)
|
||
*
|
||
* gradientColor?: 渐变颜色
|
||
*
|
||
* gradientRotate?: 渐变角度(线性)
|
||
*/
|
||
export interface SlideBackground {
|
||
type: 'solid' | 'image' | 'gradient'
|
||
color?: string
|
||
image?: string
|
||
imageSize?: 'cover' | 'contain' | 'repeat'
|
||
gradientType?: 'linear' | 'radial'
|
||
gradientColor?: [string, string]
|
||
gradientRotate?: number
|
||
}
|
||
|
||
|
||
export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY' | 'random' | 'slideX3D' | 'slideY3D' | 'rotate' | 'scaleY' | 'scaleX' | 'scale' | 'scaleReverse'
|
||
|
||
/**
|
||
* 幻灯片页面
|
||
*
|
||
* id: 页面ID
|
||
*
|
||
* elements: 元素集合
|
||
*
|
||
* remark?: 备注
|
||
*
|
||
* background?: 页面背景
|
||
*
|
||
* animations?: 元素动画集合
|
||
*
|
||
* turningMode?: 翻页方式
|
||
*/
|
||
export interface Slide {
|
||
id: string
|
||
elements: PPTElement[]
|
||
remark?: string
|
||
background?: SlideBackground
|
||
animations?: PPTAnimation[]
|
||
turningMode?: TurningMode
|
||
}
|
||
|
||
/**
|
||
* 幻灯片主题
|
||
*
|
||
* backgroundColor: 页面背景颜色
|
||
*
|
||
* themeColor: 主题色,用于默认创建的形状颜色等
|
||
*
|
||
* fontColor: 字体颜色
|
||
*
|
||
* fontName: 字体
|
||
*/
|
||
export interface SlideTheme {
|
||
backgroundColor: string
|
||
themeColor: string
|
||
fontColor: string
|
||
fontName: string
|
||
}
|