OpenMAIC-React / src /lib /types /slides.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
raw
history blame
17.4 kB
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',
DONUT = 'donut',
DIAGSTRIPE = 'diagStripe',
}
export const enum ElementTypes {
TEXT = 'text',
IMAGE = 'image',
SHAPE = 'shape',
LINE = 'line',
CHART = 'chart',
TABLE = 'table',
LATEX = 'latex',
VIDEO = 'video',
AUDIO = 'audio',
CODE = 'code',
}
/**
* 渐变
*
* type: 渐变类型(径向、线性)
*
* colors: 渐变颜色列表(pos: 百分比位置;color: 颜色)
*
* rotate: 渐变角度(线性渐变)
*/
export type GradientType = 'linear' | 'radial';
export type GradientColor = {
pos: number;
color: string;
};
export interface Gradient {
type: GradientType;
colors: GradientColor[];
rotate: number;
}
export type LineStyleType = 'solid' | 'dashed' | 'dotted';
/**
* 元素阴影
*
* h: 水平偏移量
*
* v: 垂直偏移量
*
* blur: 模糊程度
*
* color: 阴影颜色
*/
export interface PPTElementShadow {
h: number;
v: number;
blur: number;
color: string;
}
/**
* 元素边框
*
* style?: 边框样式(实线或虚线)
*
* width?: 边框宽度
*
* color?: 边框颜色
*/
export interface PPTElementOutline {
style?: LineStyleType;
width?: number;
color?: string;
}
export type ElementLinkType = 'web' | 'slide';
/**
* 元素超链接
*
* type: 链接类型(网页、幻灯片页面)
*
* target: 目标地址(网页链接、幻灯片页面ID)
*/
export interface PPTElementLink {
type: ElementLinkType;
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;
}
export type TextType =
| 'title'
| 'subtitle'
| 'content'
| 'item'
| 'itemTitle'
| 'notes'
| 'header'
| 'footer'
| 'partNumber'
| 'itemNumber';
/**
* 文本元素
*
* type: 元素类型(text)
*
* content: 文本内容(HTML字符串)
*
* defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
*
* defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
*
* outline?: 边框
*
* fill?: 填充色
*
* lineHeight?: 行高(倍),默认1.5
*
* wordSpace?: 字间距,默认0
*
* opacity?: 不透明度,默认1
*
* shadow?: 阴影
*
* paragraphSpace?: 段间距,默认 5px
*
* vertical?: 竖向文本
*
* textType?: 文本类型
*/
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;
textType?: TextType;
}
/**
* 图片翻转、形状翻转
*
* 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'
| 'sepia'
| 'invert';
export interface ImageElementFilters {
blur?: string;
brightness?: string;
contrast?: string;
grayscale?: string;
saturate?: string;
'hue-rotate'?: string;
sepia?: string;
invert?: string;
opacity?: string;
}
export type ImageClipDataRange = [[number, number], [number, number]];
/**
* 图片裁剪
*
* range: 裁剪范围,例如:[[10, 10], [90, 90]] 表示裁取原图从左上角 10%, 10% 到 90%, 90% 的范围
*
* shape: 裁剪形状,见 configs/image-clip.ts CLIPPATHS
*/
export interface ImageElementClip {
range: ImageClipDataRange;
shape: string;
}
export type ImageType = 'pageFigure' | 'itemFigure' | 'background';
/**
* 图片元素
*
* type: 元素类型(image)
*
* fixedRatio: 固定图片宽高比例
*
* src: 图片地址
*
* outline?: 边框
*
* filters?: 图片滤镜
*
* clip?: 裁剪信息
*
* flipH?: 水平翻转
*
* flipV?: 垂直翻转
*
* shadow?: 阴影
*
* radius?: 圆角半径
*
* colorMask?: 颜色蒙版
*
* imageType?: 图片类型
*/
export interface PPTImageElement extends PPTBaseElement {
type: 'image';
fixedRatio: boolean;
src: string;
outline?: PPTElementOutline;
filters?: ImageElementFilters;
clip?: ImageElementClip;
flipH?: boolean;
flipV?: boolean;
shadow?: PPTElementShadow;
radius?: number;
colorMask?: string;
imageType?: ImageType;
}
export type ShapeTextAlign = 'top' | 'middle' | 'bottom';
/**
* 形状内文本
*
* content: 文本内容(HTML字符串)
*
* defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
*
* defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
*
* align: 文本对齐方向(垂直方向)
*
* lineHeight?: 行高(倍),默认1.5
*
* wordSpace?: 字间距,默认0
*
* paragraphSpace?: 段间距,默认 5px
*
* type: 文本类型
*/
export interface ShapeText {
content: string;
defaultFontName: string;
defaultColor: string;
align: ShapeTextAlign;
lineHeight?: number;
wordSpace?: number;
paragraphSpace?: number;
type?: TextType;
}
/**
* 形状元素
*
* type: 元素类型(shape)
*
* viewBox: SVG的viewBox属性,例如 [1000, 1000] 表示 '0 0 1000 1000'
*
* path: 形状路径,SVG path 的 d 属性
*
* fixedRatio: 固定形状宽高比例
*
* fill: 填充,不存在渐变时生效
*
* gradient?: 渐变,该属性存在时将优先作为填充
*
* pattern?: 图案,该属性存在时将优先作为填充
*
* outline?: 边框
*
* opacity?: 不透明度
*
* flipH?: 水平翻转
*
* flipV?: 垂直翻转
*
* shadow?: 阴影
*
* special?: 特殊形状(标记一些难以解析的形状,例如路径使用了 L Q C A 以外的类型,该类形状在导出后将变为图片的形式)
*
* text?: 形状内文本
*
* pathFormula?: 形状路径计算公式
* 一般情况下,形状的大小变化时仅由宽高基于 viewBox 的缩放比例来调整形状,而 viewBox 本身和 path 不会变化,
* 但也有一些形状希望能更精确的控制一些关键点的位置,此时就需要提供路径计算公式,通过在缩放时更新 viewBox 并重新计算 path 来重新绘制形状
*
* keypoints?: 关键点位置百分比
*/
export interface PPTShapeElement extends PPTBaseElement {
type: 'shape';
viewBox: [number, number];
path: string;
fixedRatio: boolean;
fill: string;
gradient?: Gradient;
pattern?: string;
outline?: PPTElementOutline;
opacity?: number;
flipH?: boolean;
flipV?: boolean;
shadow?: PPTElementShadow;
special?: boolean;
text?: ShapeText;
pathFormula?: ShapePathFormulasKeys;
keypoints?: number[];
}
export type LinePoint = '' | 'arrow' | 'dot';
/**
* 线条元素
*
* type: 元素类型(line)
*
* start: 起点位置([x, y])
*
* end: 终点位置([x, y])
*
* style: 线条样式(实线、虚线、点线)
*
* color: 线条颜色
*
* points: 端点样式([起点样式, 终点样式],可选:无、箭头、圆点)
*
* shadow?: 阴影
*
* broken?: 折线控制点位置([x, y])
*
* broken2?: 双折线控制点位置([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: LineStyleType;
color: string;
points: [LinePoint, LinePoint];
shadow?: PPTElementShadow;
broken?: [number, number];
broken2?: [number, number];
curve?: [number, number];
cubic?: [[number, number], [number, number]];
}
export type ChartType = 'bar' | 'column' | 'line' | 'pie' | 'ring' | 'area' | 'radar' | 'scatter';
export interface ChartOptions {
lineSmooth?: boolean;
stack?: boolean;
}
export interface ChartData {
labels: string[];
legends: string[];
series: number[][];
}
/**
* 图表元素
*
* type: 元素类型(chart)
*
* fill?: 填充色
*
* chartType: 图表基础类型(bar/line/pie),所有图表类型都是由这三种基本类型衍生而来
*
* data: 图表数据
*
* options: 扩展选项
*
* outline?: 边框
*
* themeColors: 主题色
*
* textColor?: 坐标和文字颜色
*
* lineColor?: 网格颜色
*/
export interface PPTChartElement extends PPTBaseElement {
type: 'chart';
fill?: string;
chartType: ChartType;
data: ChartData;
options?: ChartOptions;
outline?: PPTElementOutline;
themeColors: string[];
textColor?: string;
lineColor?: string;
}
export type TextAlign = 'left' | 'center' | 'right' | 'justify';
/**
* 表格单元格样式
*
* 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?: TextAlign;
}
/**
* 表格单元格
*
* 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: 列宽数组,如[0.3, 0.5, 0.2]表示三列宽度分别占总宽度的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代码
*
* html: KaTeX渲染的HTML字符串(新版公式使用)
*
* path: svg path(旧版SVG渲染,向后兼容,可选)
*
* color: 颜色(旧版SVG渲染,向后兼容,可选)
*
* strokeWidth: 路径宽度(旧版SVG渲染,向后兼容,可选)
*
* viewBox: SVG的viewBox属性(旧版SVG渲染,向后兼容,可选)
*
* fixedRatio: 固定形状宽高比例(可选)
*
* align: 公式水平对齐方式(left/center/right,默认center)
*/
export interface PPTLatexElement extends PPTBaseElement {
type: 'latex';
latex: string;
html?: string;
path?: string;
color?: string;
strokeWidth?: number;
viewBox?: [number, number];
fixedRatio?: boolean;
align?: 'left' | 'center' | 'right';
}
/**
* 视频元素
*
* type: 元素类型(video)
*
* src: 视频地址
*
* autoplay: 自动播放
*
* poster: 预览封面
*
* ext: 视频后缀,当资源链接缺少后缀时用该字段确认资源类型
*/
export interface PPTVideoElement extends PPTBaseElement {
type: 'video';
src: string;
autoplay: boolean;
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;
}
/**
* Code line
*
* id: stable line ID (e.g. "L1", "L2"), auto-generated by the system
*
* content: line content (no trailing newline)
*/
export interface CodeLine {
id: string;
content: string;
}
/**
* Code element
*
* type: element type (code)
*
* language: programming language identifier (e.g. 'python', 'javascript', 'typescript')
*
* lines: code content stored as lines, each with a stable ID
*
* fileName?: optional file name title (e.g. "main.py")
*
* showLineNumbers?: whether to show line numbers, default true
*
* fontSize?: font size in pixels, default 14
*/
export interface PPTCodeElement extends PPTBaseElement {
type: 'code';
language: string;
lines: CodeLine[];
fileName?: string;
showLineNumbers?: boolean;
fontSize?: number;
}
export type PPTElement =
| PPTTextElement
| PPTImageElement
| PPTShapeElement
| PPTLineElement
| PPTChartElement
| PPTTableElement
| PPTLatexElement
| PPTVideoElement
| PPTAudioElement
| PPTCodeElement;
export type AnimationType = 'in' | 'out' | 'attention';
export type AnimationTrigger = 'click' | 'meantime' | 'auto';
/**
* 元素动画
*
* id: 动画id
*
* elId: 元素ID
*
* effect: 动画效果
*
* type: 动画类型(入场、退场、强调)
*
* duration: 动画持续时间
*
* trigger: 动画触发方式(click - 单击时、meantime - 与上一动画同时、auto - 上一动画之后)
*/
export interface PPTAnimation {
id: string;
elId: string;
effect: string;
type: AnimationType;
duration: number;
trigger: AnimationTrigger;
}
export type SlideBackgroundType = 'solid' | 'image' | 'gradient';
export type SlideBackgroundImageSize = 'cover' | 'contain' | 'repeat';
export interface SlideBackgroundImage {
src: string;
size: SlideBackgroundImageSize;
}
/**
* 幻灯片背景
*
* type: 背景类型(纯色、图片、渐变)
*
* color?: 背景颜色(纯色)
*
* image?: 图片背景
*
* gradientType?: 渐变背景
*/
export interface SlideBackground {
type: SlideBackgroundType;
color?: string;
image?: SlideBackgroundImage;
gradient?: Gradient;
}
export type TurningMode =
| 'no'
| 'fade'
| 'slideX'
| 'slideY'
| 'random'
| 'slideX3D'
| 'slideY3D'
| 'rotate'
| 'scaleY'
| 'scaleX'
| 'scale'
| 'scaleReverse';
export interface SectionTag {
id: string;
title?: string;
}
export type SlideType = 'cover' | 'contents' | 'transition' | 'content' | 'end';
/**
* 幻灯片页面
*
* id: 页面ID
*
* viewportSize: 视口大小
*
* viewportRatio: 视口宽高比
*
* theme: 幻灯片主题
*
* elements: 元素集合
*
* background?: 页面背景
*
* animations?: 元素动画集合
*
* turningMode?: 翻页方式
*
* sectionTag?: 章节标签
*
* type?: 页面类型
*/
export interface Slide {
id: string;
viewportSize: number;
viewportRatio: number;
theme: SlideTheme;
elements: PPTElement[];
background?: SlideBackground;
animations?: PPTAnimation[];
turningMode?: TurningMode;
sectionTag?: SectionTag;
type?: SlideType;
}
/**
* 幻灯片主题
*
* backgroundColor: 页面背景颜色
*
* themeColor: 主题色,用于默认创建的形状颜色等
*
* fontColor: 字体颜色
*
* fontName: 字体
*/
export interface SlideTheme {
backgroundColor: string;
themeColors: string[];
fontColor: string;
fontName: string;
outline?: PPTElementOutline;
shadow?: PPTElementShadow;
}
export interface SlideTemplate {
name: string;
id: string;
cover: string;
origin?: string;
}
/**
* @deprecated SlideData is deprecated, use Slide instead
*/
export interface SlideData {
id: string;
viewportSize: number;
viewportRatio: number;
theme: {
themeColors: string[];
fontColor: string;
fontName: string;
backgroundColor: string;
};
elements: PPTElement[];
background?: SlideBackground;
animations?: unknown[];
}