slides.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  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. }
  177. /**
  178. * 图片翻转、形状翻转
  179. *
  180. * flipH?: 水平翻转
  181. *
  182. * flipV?: 垂直翻转
  183. */
  184. export interface ImageOrShapeFlip {
  185. flipH?: boolean
  186. flipV?: boolean
  187. }
  188. /**
  189. * 图片滤镜
  190. *
  191. * https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
  192. *
  193. * 'blur'?: 模糊,默认0(px)
  194. *
  195. * 'brightness'?: 亮度,默认100(%)
  196. *
  197. * 'contrast'?: 对比度,默认100(%)
  198. *
  199. * 'grayscale'?: 灰度,默认0(%)
  200. *
  201. * 'saturate'?: 饱和度,默认100(%)
  202. *
  203. * 'hue-rotate'?: 色相旋转,默认0(deg)
  204. *
  205. * 'opacity'?: 不透明度,默认100(%)
  206. */
  207. export type ImageElementFilterKeys = 'blur' | 'brightness' | 'contrast' | 'grayscale' | 'saturate' | 'hue-rotate' | 'opacity' | 'sepia' | 'invert'
  208. export interface ImageElementFilters {
  209. 'blur'?: string
  210. 'brightness'?: string
  211. 'contrast'?: string
  212. 'grayscale'?: string
  213. 'saturate'?: string
  214. 'hue-rotate'?: string
  215. 'sepia'?: string
  216. 'invert'?: string
  217. 'opacity'?: string
  218. }
  219. export type ImageClipDataRange = [[number, number], [number, number]]
  220. /**
  221. * 图片裁剪
  222. *
  223. * range: 裁剪范围,例如:[[10, 10], [90, 90]] 表示裁取原图从左上角 10%, 10% 到 90%, 90% 的范围
  224. *
  225. * shape: 裁剪形状,见 configs/imageClip.ts CLIPPATHS
  226. */
  227. export interface ImageElementClip {
  228. range: ImageClipDataRange
  229. shape: string
  230. }
  231. export type ImageType = 'pageFigure' | 'itemFigure' | 'background'
  232. /**
  233. * 图片元素
  234. *
  235. * type: 元素类型(image)
  236. *
  237. * fixedRatio: 固定图片宽高比例
  238. *
  239. * src: 图片地址
  240. *
  241. * outline?: 边框
  242. *
  243. * filters?: 图片滤镜
  244. *
  245. * clip?: 裁剪信息
  246. *
  247. * flipH?: 水平翻转
  248. *
  249. * flipV?: 垂直翻转
  250. *
  251. * shadow?: 阴影
  252. *
  253. * radius?: 圆角半径
  254. *
  255. * colorMask?: 颜色蒙版
  256. *
  257. * imageType?: 图片类型
  258. */
  259. export interface PPTImageElement extends PPTBaseElement {
  260. type: 'image'
  261. fixedRatio: boolean
  262. src: string
  263. outline?: PPTElementOutline
  264. filters?: ImageElementFilters
  265. clip?: ImageElementClip
  266. flipH?: boolean
  267. flipV?: boolean
  268. shadow?: PPTElementShadow
  269. radius?: number
  270. colorMask?: string
  271. imageType?: ImageType
  272. }
  273. export type ShapeTextAlign = 'top' | 'middle' | 'bottom'
  274. /**
  275. * 形状内文本
  276. *
  277. * content: 文本内容(HTML字符串)
  278. *
  279. * defaultFontName: 默认字体(会被文本内容中的HTML内联样式覆盖)
  280. *
  281. * defaultColor: 默认颜色(会被文本内容中的HTML内联样式覆盖)
  282. *
  283. * align: 文本对齐方向(垂直方向)
  284. *
  285. * type: 文本类型
  286. */
  287. export interface ShapeText {
  288. content: string
  289. defaultFontName: string
  290. defaultColor: string
  291. align: ShapeTextAlign
  292. type?: TextType
  293. style?: string
  294. }
  295. /**
  296. * 形状元素
  297. *
  298. * type: 元素类型(shape)
  299. *
  300. * viewBox: SVG的viewBox属性,例如 [1000, 1000] 表示 '0 0 1000 1000'
  301. *
  302. * path: 形状路径,SVG path 的 d 属性
  303. *
  304. * fixedRatio: 固定形状宽高比例
  305. *
  306. * fill: 填充,不存在渐变时生效
  307. *
  308. * gradient?: 渐变,该属性存在时将优先作为填充
  309. *
  310. * pattern?: 图案,该属性存在时将优先作为填充
  311. *
  312. * outline?: 边框
  313. *
  314. * opacity?: 不透明度
  315. *
  316. * flipH?: 水平翻转
  317. *
  318. * flipV?: 垂直翻转
  319. *
  320. * shadow?: 阴影
  321. *
  322. * special?: 特殊形状(标记一些难以解析的形状,例如路径使用了 L Q C A 以外的类型,该类形状在导出后将变为图片的形式)
  323. *
  324. * text?: 形状内文本
  325. *
  326. * pathFormula?: 形状路径计算公式
  327. * 一般情况下,形状的大小变化时仅由宽高基于 viewBox 的缩放比例来调整形状,而 viewBox 本身和 path 不会变化,
  328. * 但也有一些形状希望能更精确的控制一些关键点的位置,此时就需要提供路径计算公式,通过在缩放时更新 viewBox 并重新计算 path 来重新绘制形状
  329. *
  330. * keypoints?: 关键点位置百分比
  331. */
  332. export interface PPTShapeElement extends PPTBaseElement {
  333. type: 'shape'
  334. viewBox: [number, number]
  335. path: string
  336. fixedRatio: boolean
  337. fill: string
  338. gradient?: Gradient
  339. pattern?: string
  340. outline?: PPTElementOutline
  341. opacity?: number
  342. flipH?: boolean
  343. flipV?: boolean
  344. shadow?: PPTElementShadow
  345. special?: boolean
  346. text?: ShapeText
  347. pathFormula?: ShapePathFormulasKeys
  348. keypoints?: number[]
  349. }
  350. export type LinePoint = '' | 'arrow' | 'dot'
  351. /**
  352. * 线条元素
  353. *
  354. * type: 元素类型(line)
  355. *
  356. * start: 起点位置([x, y])
  357. *
  358. * end: 终点位置([x, y])
  359. *
  360. * style: 线条样式(实线、虚线、点线)
  361. *
  362. * color: 线条颜色
  363. *
  364. * points: 端点样式([起点样式, 终点样式],可选:无、箭头、圆点)
  365. *
  366. * shadow?: 阴影
  367. *
  368. * broken?: 折线控制点位置([x, y])
  369. *
  370. * broken2?: 双折线控制点位置([x, y])
  371. *
  372. * curve?: 二次曲线控制点位置([x, y])
  373. *
  374. * cubic?: 三次曲线控制点位置([[x1, y1], [x2, y2]])
  375. */
  376. export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'> {
  377. type: 'line'
  378. start: [number, number]
  379. end: [number, number]
  380. style: LineStyleType
  381. color: string
  382. points: [LinePoint, LinePoint]
  383. shadow?: PPTElementShadow
  384. broken?: [number, number]
  385. broken2?: [number, number]
  386. curve?: [number, number]
  387. cubic?: [[number, number], [number, number]]
  388. }
  389. export type ChartType = 'bar' | 'column' | 'line' | 'pie' | 'ring' | 'area' | 'radar' | 'scatter'
  390. export interface ChartOptions {
  391. lineSmooth?: boolean
  392. stack?: boolean
  393. }
  394. export interface ChartData {
  395. labels: string[]
  396. legends: string[]
  397. series: number[][]
  398. }
  399. /**
  400. * 图表元素
  401. *
  402. * type: 元素类型(chart)
  403. *
  404. * fill?: 填充色
  405. *
  406. * chartType: 图表基础类型(bar/line/pie),所有图表类型都是由这三种基本类型衍生而来
  407. *
  408. * data: 图表数据
  409. *
  410. * options: 扩展选项
  411. *
  412. * outline?: 边框
  413. *
  414. * themeColors: 主题色
  415. *
  416. * textColor?: 坐标和文字颜色
  417. *
  418. * lineColor?: 网格颜色
  419. */
  420. export interface PPTChartElement extends PPTBaseElement {
  421. type: 'chart'
  422. fill?: string
  423. chartType: ChartType
  424. data: ChartData
  425. options?: ChartOptions
  426. outline?: PPTElementOutline
  427. themeColors: string[]
  428. textColor?: string
  429. lineColor?: string
  430. }
  431. export type TextAlign = 'left' | 'center' | 'right' | 'justify'
  432. /**
  433. * 表格单元格样式
  434. *
  435. * bold?: 加粗
  436. *
  437. * em?: 斜体
  438. *
  439. * underline?: 下划线
  440. *
  441. * strikethrough?: 删除线
  442. *
  443. * color?: 字体颜色
  444. *
  445. * backcolor?: 填充色
  446. *
  447. * fontsize?: 字体大小
  448. *
  449. * fontname?: 字体
  450. *
  451. * align?: 对齐方式
  452. */
  453. export interface TableCellStyle {
  454. bold?: boolean
  455. em?: boolean
  456. underline?: boolean
  457. strikethrough?: boolean
  458. color?: string
  459. backcolor?: string
  460. fontsize?: string
  461. fontname?: string
  462. align?: TextAlign
  463. }
  464. /**
  465. * 表格单元格
  466. *
  467. * id: 单元格ID
  468. *
  469. * colspan: 合并列数
  470. *
  471. * rowspan: 合并行数
  472. *
  473. * text: 文字内容
  474. *
  475. * style?: 单元格样式
  476. */
  477. export interface TableCell {
  478. id: string
  479. colspan: number
  480. rowspan: number
  481. text: string
  482. style?: TableCellStyle
  483. }
  484. /**
  485. * 表格主题
  486. *
  487. * color: 主题色
  488. *
  489. * rowHeader: 标题行
  490. *
  491. * rowFooter: 汇总行
  492. *
  493. * colHeader: 第一列
  494. *
  495. * colFooter: 最后一列
  496. */
  497. export interface TableTheme {
  498. color: string
  499. rowHeader: boolean
  500. rowFooter: boolean
  501. colHeader: boolean
  502. colFooter: boolean
  503. }
  504. /**
  505. * 表格元素
  506. *
  507. * type: 元素类型(table)
  508. *
  509. * outline: 边框
  510. *
  511. * theme?: 主题
  512. *
  513. * colWidths: 列宽数组,如[30, 50, 20]表示三列宽度分别为30%, 50%, 20%
  514. *
  515. * cellMinHeight: 单元格最小高度
  516. *
  517. * data: 表格数据
  518. */
  519. export interface PPTTableElement extends PPTBaseElement {
  520. type: 'table'
  521. outline: PPTElementOutline
  522. theme?: TableTheme
  523. colWidths: number[]
  524. cellMinHeight: number
  525. data: TableCell[][]
  526. }
  527. /**
  528. * LaTeX元素(公式)
  529. *
  530. * type: 元素类型(latex)
  531. *
  532. * latex: latex代码
  533. *
  534. * path: svg path
  535. *
  536. * color: 颜色
  537. *
  538. * strokeWidth: 路径宽度
  539. *
  540. * viewBox: SVG的viewBox属性
  541. *
  542. * fixedRatio: 固定形状宽高比例
  543. */
  544. export interface PPTLatexElement extends PPTBaseElement {
  545. type: 'latex'
  546. latex: string
  547. path: string
  548. color: string
  549. strokeWidth: number
  550. viewBox: [number, number]
  551. fixedRatio: boolean
  552. }
  553. /**
  554. * 视频元素
  555. *
  556. * type: 元素类型(video)
  557. *
  558. * src: 视频地址
  559. *
  560. * autoplay: 自动播放
  561. *
  562. * poster: 预览封面
  563. *
  564. * ext: 视频后缀,当资源链接缺少后缀时用该字段确认资源类型
  565. */
  566. export interface PPTVideoElement extends PPTBaseElement {
  567. type: 'video'
  568. src: string
  569. autoplay: boolean
  570. poster?: string
  571. ext?: string
  572. }
  573. /**
  574. * 音频元素
  575. *
  576. * type: 元素类型(audio)
  577. *
  578. * fixedRatio: 固定图标宽高比例
  579. *
  580. * color: 图标颜色
  581. *
  582. * loop: 循环播放
  583. *
  584. * autoplay: 自动播放
  585. *
  586. * src: 音频地址
  587. *
  588. * ext: 音频后缀,当资源链接缺少后缀时用该字段确认资源类型
  589. */
  590. export interface PPTAudioElement extends PPTBaseElement {
  591. type: 'audio'
  592. fixedRatio: boolean
  593. color: string
  594. loop: boolean
  595. autoplay: boolean
  596. src: string
  597. ext?: string
  598. }
  599. /**
  600. * 网页元素
  601. *
  602. * url: 网页链接地址
  603. */
  604. export interface PPTFrameElement extends PPTBaseElement {
  605. type: 'frame'
  606. url: string
  607. isHTML?: boolean,
  608. toolType?: number
  609. }
  610. export type PPTElement = PPTTextElement | PPTImageElement | PPTShapeElement | PPTLineElement | PPTChartElement | PPTTableElement | PPTLatexElement | PPTVideoElement | PPTAudioElement | PPTFrameElement
  611. export type AnimationType = 'in' | 'out' | 'attention'
  612. export type AnimationTrigger = 'click' | 'meantime' | 'auto'
  613. /**
  614. * 元素动画
  615. *
  616. * id: 动画id
  617. *
  618. * elId: 元素ID
  619. *
  620. * effect: 动画效果
  621. *
  622. * type: 动画类型(入场、退场、强调)
  623. *
  624. * duration: 动画持续时间
  625. *
  626. * trigger: 动画触发方式(click - 单击时、meantime - 与上一动画同时、auto - 上一动画之后)
  627. */
  628. export interface PPTAnimation {
  629. id: string
  630. elId: string
  631. effect: string
  632. type: AnimationType
  633. duration: number
  634. trigger: AnimationTrigger
  635. }
  636. export type SlideBackgroundType = 'solid' | 'image' | 'gradient'
  637. export type SlideBackgroundImageSize = 'cover' | 'contain' | 'repeat'
  638. export interface SlideBackgroundImage {
  639. src: string
  640. size: SlideBackgroundImageSize,
  641. }
  642. /**
  643. * 幻灯片背景
  644. *
  645. * type: 背景类型(纯色、图片、渐变)
  646. *
  647. * color?: 背景颜色(纯色)
  648. *
  649. * image?: 图片背景
  650. *
  651. * gradientType?: 渐变背景
  652. */
  653. export interface SlideBackground {
  654. type: SlideBackgroundType
  655. color?: string
  656. image?: SlideBackgroundImage
  657. gradient?: Gradient
  658. }
  659. export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY' | 'random' | 'slideX3D' | 'slideY3D' | 'rotate' | 'scaleY' | 'scaleX' | 'scale' | 'scaleReverse'
  660. export interface NoteReply {
  661. id: string
  662. content: string
  663. time: number
  664. user: string
  665. }
  666. export interface Note {
  667. id: string
  668. content: string
  669. time: number
  670. user: string
  671. elId?: string
  672. replies?: NoteReply[]
  673. }
  674. export interface SectionTag {
  675. id: string
  676. title?: string
  677. }
  678. export type SlideType = 'cover' | 'contents' | 'transition' | 'content' | 'end'
  679. /**
  680. * 幻灯片页面
  681. *
  682. * id: 页面ID
  683. *
  684. * elements: 元素集合
  685. *
  686. * notes?: 批注
  687. *
  688. * remark?: 备注
  689. *
  690. * background?: 页面背景
  691. *
  692. * animations?: 元素动画集合
  693. *
  694. * turningMode?: 翻页方式
  695. *
  696. * slideType?: 页面类型
  697. */
  698. export interface Slide {
  699. id: string
  700. elements: PPTElement[]
  701. notes?: Note[]
  702. remark?: string
  703. background?: SlideBackground
  704. animations?: PPTAnimation[]
  705. turningMode?: TurningMode
  706. sectionTag?: SectionTag
  707. type?: SlideType
  708. }
  709. /**
  710. * 幻灯片主题
  711. *
  712. * backgroundColor: 页面背景颜色
  713. *
  714. * themeColor: 主题色,用于默认创建的形状颜色等
  715. *
  716. * fontColor: 字体颜色
  717. *
  718. * fontName: 字体
  719. */
  720. export interface SlideTheme {
  721. backgroundColor: string
  722. themeColors: string[]
  723. fontColor: string
  724. fontName: string
  725. outline: PPTElementOutline
  726. shadow: PPTElementShadow
  727. }
  728. export interface SlideTemplate {
  729. name: string
  730. id: string
  731. cover: string
  732. }