slides.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. export const enum ShapePathFormulasKeys {
  2. ROUND_RECT = 'roundRect',
  3. ROUND_RECT_DIAGONAL = 'roundRectDiagonal',
  4. ROUND_RECT_SINGLE = 'roundRectSingle',
  5. ROUND_RECT_SAMESIDE = 'roundRectSameSide',
  6. CUT_RECT_DIAGONAL = 'cutRectDiagonal',
  7. CUT_RECT_SINGLE = 'cutRectSingle',
  8. CUT_RECT_SAMESIDE = 'cutRectSameSide',
  9. CUT_ROUND_RECT = 'cutRoundRect',
  10. MESSAGE = 'message',
  11. ROUND_MESSAGE = 'roundMessage',
  12. L = 'L',
  13. RING_RECT = 'ringRect',
  14. PLUS = 'plus',
  15. TRIANGLE = 'triangle',
  16. PARALLELOGRAM_LEFT = 'parallelogramLeft',
  17. PARALLELOGRAM_RIGHT = 'parallelogramRight',
  18. TRAPEZOID = 'trapezoid',
  19. BULLET = 'bullet',
  20. INDICATOR = 'indicator',
  21. }
  22. export const enum ElementTypes {
  23. TEXT = 'text',
  24. IMAGE = 'image',
  25. SHAPE = 'shape',
  26. LINE = 'line',
  27. CHART = 'chart',
  28. TABLE = 'table',
  29. LATEX = 'latex',
  30. VIDEO = 'video',
  31. AUDIO = 'audio',
  32. FRAME = 'frame',
  33. }
  34. /**
  35. * 渐变
  36. *
  37. * type: 渐变类型(径向、线性)
  38. *
  39. * colors: 渐变颜色列表(pos: 百分比位置;color: 颜色)
  40. *
  41. * rotate: 渐变角度(线性渐变)
  42. */
  43. export type GradientType = 'linear' | 'radial'
  44. export type GradientColor = {
  45. pos: number
  46. color: string
  47. }
  48. export interface Gradient {
  49. type: GradientType
  50. colors: GradientColor[]
  51. rotate: number
  52. }
  53. export type LineStyleType = 'solid' | 'dashed' | 'dotted'
  54. /**
  55. * 元素阴影
  56. *
  57. * h: 水平偏移量
  58. *
  59. * v: 垂直偏移量
  60. *
  61. * blur: 模糊程度
  62. *
  63. * color: 阴影颜色
  64. */
  65. export interface PPTElementShadow {
  66. h: number
  67. v: number
  68. blur: number
  69. color: string
  70. }
  71. /**
  72. * 元素边框
  73. *
  74. * style?: 边框样式(实线或虚线)
  75. *
  76. * width?: 边框宽度
  77. *
  78. * color?: 边框颜色
  79. */
  80. export interface PPTElementOutline {
  81. style?: LineStyleType
  82. width?: number
  83. color?: string
  84. }
  85. export type ElementLinkType = 'web' | 'slide'
  86. /**
  87. * 元素超链接
  88. *
  89. * type: 链接类型(网页、幻灯片页面)
  90. *
  91. * target: 目标地址(网页链接、幻灯片页面ID)
  92. */
  93. export interface PPTElementLink {
  94. type: ElementLinkType
  95. target: string
  96. }
  97. /**
  98. * 元素通用属性
  99. *
  100. * id: 元素ID
  101. *
  102. * left: 元素水平方向位置(距离画布左侧)
  103. *
  104. * top: 元素垂直方向位置(距离画布顶部)
  105. *
  106. * lock?: 锁定元素
  107. *
  108. * groupId?: 组合ID(拥有相同组合ID的元素即为同一组合元素成员)
  109. *
  110. * width: 元素宽度
  111. *
  112. * height: 元素高度
  113. *
  114. * rotate: 旋转角度
  115. *
  116. * link?: 超链接
  117. *
  118. * name?: 元素名
  119. */
  120. interface PPTBaseElement {
  121. id: string
  122. left: number
  123. top: number
  124. lock?: boolean
  125. groupId?: string
  126. width: number
  127. height: number
  128. rotate: number
  129. link?: PPTElementLink
  130. name?: string
  131. }
  132. export type TextType = 'title' | 'subtitle' | 'content' | 'item' | 'itemTitle' | 'notes' | 'header' | 'footer' | 'partNumber' | 'itemNumber'
  133. /**
  134. * 文本元素
  135. *
  136. * type: 元素类型(text)
  137. *
  138. * content: 文本内容(HTML字符串)
  139. *
  140. * defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
  141. *
  142. * defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
  143. *
  144. * outline?: 边框
  145. *
  146. * fill?: 填充色
  147. *
  148. * lineHeight?: 行高(倍),默认1.5
  149. *
  150. * wordSpace?: 字间距,默认0
  151. *
  152. * opacity?: 不透明度,默认1
  153. *
  154. * shadow?: 阴影
  155. *
  156. * paragraphSpace?: 段间距,默认 5px
  157. *
  158. * vertical?: 竖向文本
  159. *
  160. * textType?: 文本类型
  161. */
  162. export interface PPTTextElement extends PPTBaseElement {
  163. type: 'text'
  164. content: string
  165. defaultFontName: string
  166. defaultColor: string
  167. outline?: PPTElementOutline
  168. fill?: string
  169. lineHeight?: number
  170. wordSpace?: number
  171. opacity?: number
  172. shadow?: PPTElementShadow
  173. paragraphSpace?: number
  174. vertical?: boolean
  175. textType?: TextType
  176. style?: string,
  177. align?: string
  178. }
  179. /**
  180. * 图片翻转、形状翻转
  181. *
  182. * flipH?: 水平翻转
  183. *
  184. * flipV?: 垂直翻转
  185. */
  186. export interface ImageOrShapeFlip {
  187. flipH?: boolean
  188. flipV?: boolean
  189. }
  190. /**
  191. * 图片滤镜
  192. *
  193. * https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
  194. *
  195. * 'blur'?: 模糊,默认0(px)
  196. *
  197. * 'brightness'?: 亮度,默认100(%)
  198. *
  199. * 'contrast'?: 对比度,默认100(%)
  200. *
  201. * 'grayscale'?: 灰度,默认0(%)
  202. *
  203. * 'saturate'?: 饱和度,默认100(%)
  204. *
  205. * 'hue-rotate'?: 色相旋转,默认0(deg)
  206. *
  207. * 'opacity'?: 不透明度,默认100(%)
  208. */
  209. export type ImageElementFilterKeys = 'blur' | 'brightness' | 'contrast' | 'grayscale' | 'saturate' | 'hue-rotate' | 'opacity' | 'sepia' | 'invert'
  210. export interface ImageElementFilters {
  211. 'blur'?: string
  212. 'brightness'?: string
  213. 'contrast'?: string
  214. 'grayscale'?: string
  215. 'saturate'?: string
  216. 'hue-rotate'?: string
  217. 'sepia'?: string
  218. 'invert'?: string
  219. 'opacity'?: string
  220. }
  221. export type ImageClipDataRange = [[number, number], [number, number]]
  222. /**
  223. * 图片裁剪
  224. *
  225. * range: 裁剪范围,例如:[[10, 10], [90, 90]] 表示裁取原图从左上角 10%, 10% 到 90%, 90% 的范围
  226. *
  227. * shape: 裁剪形状,见 configs/imageClip.ts CLIPPATHS
  228. */
  229. export interface ImageElementClip {
  230. range: ImageClipDataRange
  231. shape: string
  232. }
  233. export type ImageType = 'pageFigure' | 'itemFigure' | 'background'
  234. /**
  235. * 图片元素
  236. *
  237. * type: 元素类型(image)
  238. *
  239. * fixedRatio: 固定图片宽高比例
  240. *
  241. * src: 图片地址
  242. *
  243. * outline?: 边框
  244. *
  245. * filters?: 图片滤镜
  246. *
  247. * clip?: 裁剪信息
  248. *
  249. * flipH?: 水平翻转
  250. *
  251. * flipV?: 垂直翻转
  252. *
  253. * shadow?: 阴影
  254. *
  255. * radius?: 圆角半径
  256. *
  257. * colorMask?: 颜色蒙版
  258. *
  259. * imageType?: 图片类型
  260. */
  261. export interface PPTImageElement extends PPTBaseElement {
  262. type: 'image'
  263. fixedRatio: boolean
  264. src: string
  265. outline?: PPTElementOutline
  266. filters?: ImageElementFilters
  267. clip?: ImageElementClip
  268. flipH?: boolean
  269. flipV?: boolean
  270. shadow?: PPTElementShadow
  271. radius?: number
  272. colorMask?: string
  273. imageType?: ImageType
  274. }
  275. export type ShapeTextAlign = 'top' | 'middle' | 'bottom'
  276. /**
  277. * 形状内文本
  278. *
  279. * content: 文本内容(HTML字符串)
  280. *
  281. * defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
  282. *
  283. * defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
  284. *
  285. * align: 文本对齐方向(垂直方向)
  286. *
  287. * type: 文本类型
  288. */
  289. export interface ShapeText {
  290. content: string
  291. defaultFontName: string
  292. defaultColor: string
  293. align: ShapeTextAlign
  294. type?: TextType
  295. style?: string
  296. }
  297. /**
  298. * 形状元素
  299. *
  300. * type: 元素类型(shape)
  301. *
  302. * viewBox: SVG的viewBox属性,例如 [1000, 1000] 表示 '0 0 1000 1000'
  303. *
  304. * path: 形状路径,SVG path 的 d 属性
  305. *
  306. * fixedRatio: 固定形状宽高比例
  307. *
  308. * fill: 填充,不存在渐变时生效
  309. *
  310. * gradient?: 渐变,该属性存在时将优先作为填充
  311. *
  312. * pattern?: 图案,该属性存在时将优先作为填充
  313. *
  314. * outline?: 边框
  315. *
  316. * opacity?: 不透明度
  317. *
  318. * flipH?: 水平翻转
  319. *
  320. * flipV?: 垂直翻转
  321. *
  322. * shadow?: 阴影
  323. *
  324. * special?: 特殊形状(标记一些难以解析的形状,例如路径使用了 L Q C A 以外的类型,该类形状在导出后将变为图片的形式)
  325. *
  326. * text?: 形状内文本
  327. *
  328. * pathFormula?: 形状路径计算公式
  329. * 一般情况下,形状的大小变化时仅由宽高基于 viewBox 的缩放比例来调整形状,而 viewBox 本身和 path 不会变化,
  330. * 但也有一些形状希望能更精确的控制一些关键点的位置,此时就需要提供路径计算公式,通过在缩放时更新 viewBox 并重新计算 path 来重新绘制形状
  331. *
  332. * keypoints?: 关键点位置百分比
  333. */
  334. export interface PPTShapeElement extends PPTBaseElement {
  335. type: 'shape'
  336. viewBox: [number, number]
  337. path: string
  338. fixedRatio: boolean
  339. fill: string
  340. gradient?: Gradient
  341. pattern?: string
  342. outline?: PPTElementOutline
  343. opacity?: number
  344. flipH?: boolean
  345. flipV?: boolean
  346. shadow?: PPTElementShadow
  347. special?: boolean
  348. text?: ShapeText
  349. pathFormula?: ShapePathFormulasKeys
  350. keypoints?: number[],
  351. pathBBox?: object
  352. }
  353. export type LinePoint = '' | 'arrow' | 'dot'
  354. /**
  355. * 线条元素
  356. *
  357. * type: 元素类型(line)
  358. *
  359. * start: 起点位置([x, y])
  360. *
  361. * end: 终点位置([x, y])
  362. *
  363. * style: 线条样式(实线、虚线、点线)
  364. *
  365. * color: 线条颜色
  366. *
  367. * points: 端点样式([起点样式, 终点样式],可选:无、箭头、圆点)
  368. *
  369. * shadow?: 阴影
  370. *
  371. * broken?: 折线控制点位置([x, y])
  372. *
  373. * broken2?: 双折线控制点位置([x, y])
  374. *
  375. * curve?: 二次曲线控制点位置([x, y])
  376. *
  377. * cubic?: 三次曲线控制点位置([[x1, y1], [x2, y2]])
  378. */
  379. export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'> {
  380. type: 'line'
  381. start: [number, number]
  382. end: [number, number]
  383. style: LineStyleType
  384. color: string
  385. points: [LinePoint, LinePoint]
  386. shadow?: PPTElementShadow
  387. broken?: [number, number]
  388. broken2?: [number, number]
  389. curve?: [number, number]
  390. cubic?: [[number, number], [number, number]]
  391. }
  392. export type ChartType = 'bar' | 'column' | 'line' | 'pie' | 'ring' | 'area' | 'radar' | 'scatter'
  393. export interface ChartOptions {
  394. lineSmooth?: boolean
  395. stack?: boolean
  396. }
  397. export interface ChartData {
  398. labels: string[]
  399. legends: string[]
  400. series: number[][]
  401. }
  402. /**
  403. * 图表元素
  404. *
  405. * type: 元素类型(chart)
  406. *
  407. * fill?: 填充色
  408. *
  409. * chartType: 图表基础类型(bar/line/pie),所有图表类型都是由这三种基本类型衍生而来
  410. *
  411. * data: 图表数据
  412. *
  413. * options: 扩展选项
  414. *
  415. * outline?: 边框
  416. *
  417. * themeColors: 主题色
  418. *
  419. * textColor?: 坐标和文字颜色
  420. *
  421. * lineColor?: 网格颜色
  422. */
  423. export interface PPTChartElement extends PPTBaseElement {
  424. type: 'chart'
  425. fill?: string
  426. chartType: ChartType
  427. data: ChartData
  428. options?: ChartOptions
  429. outline?: PPTElementOutline
  430. themeColors: string[]
  431. textColor?: string
  432. lineColor?: string
  433. }
  434. export type TextAlign = 'left' | 'center' | 'right' | 'justify'
  435. /**
  436. * 表格单元格样式
  437. *
  438. * bold?: 加粗
  439. *
  440. * em?: 斜体
  441. *
  442. * underline?: 下划线
  443. *
  444. * strikethrough?: 删除线
  445. *
  446. * color?: 字体颜色
  447. *
  448. * backcolor?: 填充色
  449. *
  450. * fontsize?: 字体大小
  451. *
  452. * fontname?: 字体
  453. *
  454. * align?: 对齐方式
  455. */
  456. export interface TableCellStyle {
  457. bold?: boolean
  458. em?: boolean
  459. underline?: boolean
  460. strikethrough?: boolean
  461. color?: string
  462. backcolor?: string
  463. fontsize?: string
  464. fontname?: string
  465. align?: TextAlign
  466. }
  467. /**
  468. * 表格单元格
  469. *
  470. * id: 单元格ID
  471. *
  472. * colspan: 合并列数
  473. *
  474. * rowspan: 合并行数
  475. *
  476. * text: 文字内容
  477. *
  478. * style?: 单元格样式
  479. */
  480. export interface TableCell {
  481. id: string
  482. colspan: number
  483. rowspan: number
  484. text: string
  485. style?: TableCellStyle
  486. }
  487. /**
  488. * 表格主题
  489. *
  490. * color: 主题色
  491. *
  492. * rowHeader: 标题行
  493. *
  494. * rowFooter: 汇总行
  495. *
  496. * colHeader: 第一列
  497. *
  498. * colFooter: 最后一列
  499. */
  500. export interface TableTheme {
  501. color: string
  502. rowHeader: boolean
  503. rowFooter: boolean
  504. colHeader: boolean
  505. colFooter: boolean
  506. }
  507. /**
  508. * 表格元素
  509. *
  510. * type: 元素类型(table)
  511. *
  512. * outline: 边框
  513. *
  514. * theme?: 主题
  515. *
  516. * colWidths: 列宽数组,如[30, 50, 20]表示三列宽度分别为30%, 50%, 20%
  517. *
  518. * cellMinHeight: 单元格最小高度
  519. *
  520. * data: 表格数据
  521. */
  522. export interface PPTTableElement extends PPTBaseElement {
  523. type: 'table'
  524. outline: PPTElementOutline
  525. theme?: TableTheme
  526. colWidths: number[]
  527. cellMinHeight: number
  528. data: TableCell[][]
  529. }
  530. /**
  531. * LaTeX元素(公式)
  532. *
  533. * type: 元素类型(latex)
  534. *
  535. * latex: latex代码
  536. *
  537. * path: svg path
  538. *
  539. * color: 颜色
  540. *
  541. * strokeWidth: 路径宽度
  542. *
  543. * viewBox: SVG的viewBox属性
  544. *
  545. * fixedRatio: 固定形状宽高比例
  546. */
  547. export interface PPTLatexElement extends PPTBaseElement {
  548. type: 'latex'
  549. latex: string
  550. path: string
  551. color: string
  552. strokeWidth: number
  553. viewBox: [number, number]
  554. fixedRatio: boolean
  555. }
  556. /**
  557. * 视频元素
  558. *
  559. * type: 元素类型(video)
  560. *
  561. * src: 视频地址
  562. *
  563. * autoplay: 自动播放
  564. *
  565. * poster: 预览封面
  566. *
  567. * ext: 视频后缀,当资源链接缺少后缀时用该字段确认资源类型
  568. */
  569. export interface PPTVideoElement extends PPTBaseElement {
  570. type: 'video'
  571. src: string
  572. autoplay: boolean
  573. poster?: string
  574. ext?: string
  575. }
  576. /**
  577. * 音频元素
  578. *
  579. * type: 元素类型(audio)
  580. *
  581. * fixedRatio: 固定图标宽高比例
  582. *
  583. * color: 图标颜色
  584. *
  585. * loop: 循环播放
  586. *
  587. * autoplay: 自动播放
  588. *
  589. * src: 音频地址
  590. *
  591. * ext: 音频后缀,当资源链接缺少后缀时用该字段确认资源类型
  592. */
  593. export interface PPTAudioElement extends PPTBaseElement {
  594. type: 'audio'
  595. fixedRatio: boolean
  596. color: string
  597. loop: boolean
  598. autoplay: boolean
  599. src: string
  600. ext?: string
  601. }
  602. /**
  603. * 网页元素
  604. *
  605. * url: 网页链接地址
  606. */
  607. export interface PPTFrameElement extends PPTBaseElement {
  608. type: 'frame'
  609. url: string
  610. isHTML?: boolean,
  611. toolType?: number,
  612. isDone?: boolean,
  613. }
  614. export type PPTElement = PPTTextElement | PPTImageElement | PPTShapeElement | PPTLineElement | PPTChartElement | PPTTableElement | PPTLatexElement | PPTVideoElement | PPTAudioElement | PPTFrameElement
  615. export type AnimationType = 'in' | 'out' | 'attention'
  616. export type AnimationTrigger = 'click' | 'meantime' | 'auto'
  617. /**
  618. * 元素动画
  619. *
  620. * id: 动画id
  621. *
  622. * elId: 元素ID
  623. *
  624. * effect: 动画效果
  625. *
  626. * type: 动画类型(入场、退场、强调)
  627. *
  628. * duration: 动画持续时间
  629. *
  630. * trigger: 动画触发方式(click - 单击时、meantime - 与上一动画同时、auto - 上一动画之后)
  631. */
  632. export interface PPTAnimation {
  633. id: string
  634. elId: string
  635. effect: string
  636. type: AnimationType
  637. duration: number
  638. trigger: AnimationTrigger
  639. }
  640. export type SlideBackgroundType = 'solid' | 'image' | 'gradient'
  641. export type SlideBackgroundImageSize = 'cover' | 'contain' | 'repeat'
  642. export interface SlideBackgroundImage {
  643. src: string
  644. size: SlideBackgroundImageSize,
  645. }
  646. /**
  647. * 幻灯片背景
  648. *
  649. * type: 背景类型(纯色、图片、渐变)
  650. *
  651. * color?: 背景颜色(纯色)
  652. *
  653. * image?: 图片背景
  654. *
  655. * gradientType?: 渐变背景
  656. */
  657. export interface SlideBackground {
  658. type: SlideBackgroundType
  659. color?: string
  660. image?: SlideBackgroundImage
  661. gradient?: Gradient
  662. }
  663. export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY' | 'random' | 'slideX3D' | 'slideY3D' | 'rotate' | 'scaleY' | 'scaleX' | 'scale' | 'scaleReverse'
  664. export interface NoteReply {
  665. id: string
  666. content: string
  667. time: number
  668. user: string
  669. }
  670. export interface Note {
  671. id: string
  672. content: string
  673. time: number
  674. user: string
  675. elId?: string
  676. replies?: NoteReply[]
  677. }
  678. export interface SectionTag {
  679. id: string
  680. title?: string
  681. }
  682. export type SlideType = 'cover' | 'contents' | 'transition' | 'content' | 'end'
  683. /**
  684. * 幻灯片页面
  685. *
  686. * id: 页面ID
  687. *
  688. * elements: 元素集合
  689. *
  690. * notes?: 批注
  691. *
  692. * remark?: 备注
  693. *
  694. * background?: 页面背景
  695. *
  696. * animations?: 元素动画集合
  697. *
  698. * turningMode?: 翻页方式
  699. *
  700. * slideType?: 页面类型
  701. */
  702. export interface Slide {
  703. id: string
  704. elements: PPTElement[]
  705. notes?: Note[]
  706. remark?: string
  707. background?: SlideBackground
  708. animations?: PPTAnimation[]
  709. turningMode?: TurningMode
  710. sectionTag?: SectionTag
  711. type?: SlideType
  712. }
  713. /**
  714. * 幻灯片主题
  715. *
  716. * backgroundColor: 页面背景颜色
  717. *
  718. * themeColor: 主题色,用于默认创建的形状颜色等
  719. *
  720. * fontColor: 字体颜色
  721. *
  722. * fontName: 字体
  723. */
  724. export interface SlideTheme {
  725. backgroundColor: string
  726. themeColors: string[]
  727. fontColor: string
  728. fontName: string
  729. outline: PPTElementOutline
  730. shadow: PPTElementShadow
  731. }
  732. export interface SlideTemplate {
  733. name: string
  734. id: string
  735. cover: string
  736. }