## File: README.md

[](https://www.github.com/pipipi-pikachu/PPTist/stargazers)
[](https://www.github.com/pipipi-pikachu/PPTist/network/members)
[](https://github.com/pipipi-pikachu/PPTist/issues)
[](https://www.github.com/pipipi-pikachu/PPTist/blob/master/LICENSE)
[](https://gitee.com/pptist/PPTist)
[](https://gitcode.com/pipipi-pikachu/PPTist)

[简体中文](README_zh.md) | English


# 🎨 PPTist
**PowerPoint-ist（/'pauəpɔintist/）**, A web-based presentation (slideshow) application. This application replicates most of the commonly used features of Microsoft Office PowerPoint. It supports various essential element types such as text, images, shapes, lines, charts, tables, videos, audio, and formulas. You can edit and present slides directly in a web browser.

**Try it online👉：[https://pipipi-pikachu.github.io/PPTist/](https://pipipi-pikachu.github.io/PPTist/)**

> China Mirrors (Synchronized Regularly): [Gitee](https://gitee.com/pptist/PPTist)、[GitCode](https://gitcode.com/pipipi-pikachu/PPTist)


# ✨ Highlights
1. **Easy Development**: Built with Vue 3.x and TypeScript, it does not rely on UI component libraries, making styling customization easier and functionality extension more convenient.
2. **User Friendly**: It offers context menus everywhere, dozens of shortcut operations, and continuously refined editing details, striving to replicate a desktop application-level experience.
3. **Feature Rich**: Supports most commonly used Office PPT elements and features, supports template-based AIPPT, supports exporting in various formats, and offers basic editing and previewing on mobile devices.
4. **Controllable Code**: Not a temporary product of vibe coding. The code is robust, controllable, easy to maintain, and leaves no technical debt.


# 👀 Front-Row Reminder
1. The target audience for this project is developers with web slide development needs and basic web development experience. The provided link is for demonstration purposes only and does not offer any online services. This project should not be used directly as a tool, nor does it support out-of-the-box use. If you simply need a ready-made service or tool, please consider other products.
2. Here are some summarized [Frequently Asked Questions](/doc/Q&A.md). When raising Issues or submitting PRs for the first time, be sure to read this document in advance.
3. For commercial use, please refer to [商业用途](#-商业用途)


# 🧩 Project Positioning
> The core positioning of this project is a **Web Slide Editing/Presentation Application**. The following are the recommendation levels for common use cases:

- **Low-code Platforms / H5 Editors / Image Editors / Whiteboards** (Recommendation: Not Recommended): We suggest choosing open-source projects that better match those scenarios.
- **AI PPT Generation Tool** (Recommendation: ⭐⭐): This project supports a template-based AIPPT generation approach, and also provides a data structure definition for AI to directly generate page data. See `AI_PPT_SCHEMA.md`. In theory, it supports non-template PPT generation, where AI directly generates PPTist data. Note that the final result of AIPPT depends heavily on model capabilities, prompt design, asset generation/retrieval, and other factors. PPTist is better suited as a foundation for carrying, editing, and further processing structured generation results, rather than an out-of-the-box complete AIPPT commercial solution.
- **PPT File Preview Tool** (Recommendation: ⭐⭐): This project supports importing PPTX files and can cover many common page contents and styles (roughly 85%+ fidelity overall), making it suitable for online preview, lightweight review, and content browsing. However, because the PPTX ecosystem is complex, animations, special charts, deeply nested structures, non-standard elements, and some advanced styles may inevitably have fidelity differences. If your business requires pixel-perfect fidelity, evaluate with your actual sample files.
- **Office PPT Authoring Tool** (Recommendation: ⭐⭐): This project supports many common Office PPT features and can import/export local PPTX files, making it usable as a foundation for online authoring and editing. Note that full Office PPT compatibility involves many details, including complex layouts, animations, charts, themes, and masters. Some details will inevitably be lost during file import/export, so 100% fidelity cannot be guaranteed. If your core goal is to fully replace Microsoft PowerPoint, evaluate and make trade-offs with your actual business documents.
- **Web Slide Editing/Presentation App** (Recommendation: ⭐⭐⭐⭐⭐): This is the most recommended scenario. The core strengths of PPTist are its editing capabilities and editing experience. You can build upon this project to customize or add unique nodes and features according to your needs, without using import/export as the ultimate goal. After all, those customized things do not exist in Office PPT. **Summary: I hope you use PPTist to build a presentation product different from Office PPT, rather than just an editing relay station for Office PPT.**


# 🚀 Installation
> node.js version >= 20

```
npm install

npm run dev
```
Browser access: http://127.0.0.1:5173/


# 📚 Features
### Basic Features
- History (undo, redo)
- Shortcuts
- Right-click menu
- Import: PPTX (overall fidelity ~85%+), JSON, pptist files
- Export: PPTX (overall fidelity ~95%+), JSON, images, PDF (print), pptist files
- Template-based AI PPT generation
### Slide Page Editing
- Add/delete pages
- Copy/paste pages
- Adjust page order
- Create sections
- Background settings (solid color, gradient, image)
- Set canvas size
- Gridlines
- Rulers
- Canvas zoom and move
- Theme settings
- Extract slides style
- Speaker notes (rich text)
- Slide templates
- Transition animations
- Element animations (entrance, exit, emphasis)
- Selection panel (hide elements, layer sorting, element naming)
- Labels for Page and Node Types (usable for template-related features)
- Find/replace
- Annotations
### Slide Element Editing
- Add/delete elements
- Copy/paste elements
- Drag and move elements
- Rotate elements
- Scale elements
- Multiple element selection (marquee, point selection)
- Group multiple elements
- Batch edit multiple elements
- Lock elements
- Magnetic alignment of elements (move and scale)
- Adjust element layer
- Align elements to canvas
- Align elements to other elements
- Evenly distribute multiple elements
- Drag to add text and images
- Paste external images
- Set element coordinates, size, and rotation
- Element hyperlinks (link to webpage, link to other slide pages)
- Element bubble menu (Floating toolbar)
#### Text
- Rich text editing (color, highlight, font, font size, bold, italic, underline, strikethrough, subscript, inline code, quote, hyperlink, alignment, numbering, bullet points, paragraph indent, clear formatting)
- Line height
- Character spacing
- Paragraph spacing
- First line indent
- Fill color
- Border
- Shadow
- Transparency
- Vertical text
- Text box margins
- Auto-fit/fixed height (vertical alignment can be selected when fixed)
- AI Rewrite/Expand/Abbreviate
#### Images
- Crop (custom, shape, aspect ratio)
- Rounding
- Filters
- Tint (mask)
- Flip
- Border
- Shadow
- Replace image
- Reset image
- Set as background
#### Shapes
- Freehand draw any polygon
- Freehand draw any line (unclosed shape simulation)
- Visual path creation method
- Replace shape
- Fill (solid color, gradient, image)
- Border
- Shadow
- Transparency
- Flip
- Shape format painter
- Edit text (supports rich text, similar to text element’s rich text editing)
- Text box margins
- Text vertical alignment
#### Lines
- Straight lines, polylines, curves
- Color
- Width
- Style (solid, dashed, dotted)
- Endpoint style
#### Charts (bar, column, line, area, scatter, pie, donut, radar)
- Chart type conversion
- Data editing
- Background fill
- Theme color
- Coordinate system and axis text color
- Grid color
- Other chart settings
- Border
#### Tables
- Add/delete rows and columns
- Theme settings (theme color, header, total row, first column, last column)
- Merge cells
- Cell styles (fill color, text color, bold, italic, underline, strikethrough, alignment)
- Border
#### Video
- Preview cover settings
- Auto play
#### Audio
- Icon color
- Auto play
- Loop play
#### Formulas
- LaTeX editing
- Color settings
- Formula line thickness settings
### Slide Show
- Brush tools (pen/shape/arrow/highlighter annotation, eraser, blackboard mode)
- Preview all slides
- Bottom thumbnails navigation
- Timer tool
- Laser pointer
- Auto play
- Speaker view
- Audience view
### Mobile
- Basic editing
  - Add/delete/copy/note/undo redo pages
  - Insert text, images, rectangles, circles
  - General element operations: move, scale, rotate, copy, delete, layer adjust, align
  - Element styles: text (bold, italic, underline, strikethrough, font size, color, alignment), fill color
- Basic preview
- Play preview


# 👀 FAQ
Some common problems: [FAQ](/doc/Q&A.md)


# 🎯 Supplement
There is currently no complete development documentation, but the following documents may be of some help to you:
- [Project Directory and Data Structure](/doc/DirectoryAndData.md)
- [Fundamentals of Canvas and Elements](/doc/Canvas.md)
- [How to Customize an Element](/doc/CustomElement.md)
- [About AIPPT](/doc/AIPPT.md)

Here are some auxiliary development tools/repositories:
- Import PPTX file reference: [pptxtojson](https://github.com/pipipi-pikachu/pptxtojson)
- Draw shape: [svgPathCreator](https://github.com/pipipi-pikachu/svgPathCreator)


# 📄 License
[AGPL-3.0 License](https://github.com/pipipi-pikachu/PPTist/blob/master/LICENSE) | Copyright © 2020-PRESENT [pipipi-pikachu](https://github.com/pipipi-pikachu)

# 🧮 Commercial
If you wish to use this project for commercial gain, I hope you will respect open source and strictly adhere to the AGPL-3.0 license, giving back to the open source community. Or contact the author for an independent commercial license.





# 🧮 商业用途
## 商用须知
- 本项目禁止闭源商用，如果你希望将其用于商业项目，请尊重开源，**严格遵循 [AGPL-3.0 协议](https://www.gnu.org/licenses/agpl-3.0.html)**，回馈开源社区；
- 如果你因为任何原因，无法执行 AGPL-3.0 协议，可以选择：
    1. 使用 Apache 2.0 协议版本（最后更新时间为2022年5月，已停止维护，[点此下载](https://github.com/pipipi-pikachu/PPTist/archive/f1a35bb8e045124e37dcafd6acbf40b4531b69aa.zip)）；
    2. 成为项目的重要贡献者（先违反协议后再成为贡献者不适用此项），包括：
        - 你的代码被本项目作为依赖引用，包括：npm安装、文件引用、代码片段引用（引用处会注明）；
        - 你给本项目提交过重要的 PR 或 Issue（由作者主观判断，符合的 PR 或 Issue 会打上`important contribution`标签）；
    3. [邮件联系作者](mailto:pipipi_pikachu@163.com)付费获取独立的商业授权（违反协议后被作者找到的不适用此项）。独立授权价格：
        - 一年：2999元；
        - 永久：5699元（不含税）；
- 请优先考虑执行AGPL-3.0协议，如需付费获取独立的商业授权，请务必在联系作者前阅读以下内容：
    - **独立商业授权表示**：
        - 作者单独出具商业授权协议文件（邮件联系作者获取），双方按流程签署协议；
        - 允许将代码用于商业行为，且不必执行 AGPL-3.0 协议；
        - 授权对象可以是个人或组织（企业），允许授权对象名下的所有产品使用本项目代码；
    - **授权流程**：
        1. 被授权方确认协议内容，若无异议，需提供协议中所需的个人/企业信息；
        2. 由作者补充好协议双方信息后打印签字，并将电子扫描件发给被授权方；
        3. 被授权方收到后，将协议打印盖章，再扫描电子档发回给作者，此时协议开始生效；
        4. 被授权方在协议规定时间内支付费用，并保留好支付凭证，授权结束；
    - **授权不等于出售软件或服务**：
        - 不存在其他“商业版本”、不提供任何API/SDK/在线服务/技术支持/技术咨询/定制开发；
        - 不提供可直接交付的产品，你仍需从本仓库获取代码自行开发；
        - 该软件无法开箱即用，至少也得自行接入后端能力（需要有最基本的web开发经验）；
        - 不保证未来版本的兼容性，不保证代码没有bug；
        - 作者不承担任何因使用本项目代码而导致的直接或间接损失；
        - 务必提前做好调研，判断该软件是否符合需求，包括但不限于功能（是否能满足业务需求）和开发（是否上手当前技术栈/实现方案）；
- 不接受[黑名单/耻辱柱](/doc/Blacklist.md)或存在违反协议行为的对象通过任何形式获取商业授权；
- 作者倡导异步沟通（正式、信息整合度高），**不加私人微信/QQ/手机号等**，有任何授权相关疑问请邮件联系，谢谢理解；
- 提需求/报bug/询问技术方案等非授权相关咨询，请在 [Issues](https://github.com/pipipi-pikachu/PPTist/issues) 中进行。

## AGPL-3.0 协议
协议核心要求用通俗的语言解释如下：
- **开源义务**：如果你用了 AGPL 的代码，无论你或你的下游怎么使用/修改，都必须把你最终的代码全部完整公开出来，并继续以 AGPL 协议开源（强调：必须延续 AGPL 协议，保持开源的传染性，不能更换其他协议）。
- **网络服务也要开源**：即使你只是用 AGPL 的代码做了一个网站或网络服务，别人通过网络用你的服务时，你也需要遵守上一条**开源义务**。
- **保留版权声明**：你不能删掉代码里原来的作者信息和许可证声明，得告诉大家这代码是从哪儿来的。
- **不能加额外限制**：你不能在衍生出来的 AGPL 代码上加一些限制，比如不让别人再分发代码，或者要求别人付费才能使用代码（包括但不限于：要求别人购买授权/服务/产品等）。
- **免责声明**：作者不保证代码没有 bug，也不对使用后果负责。

> 详细协议内容见官方文档：[AGPL-3.0 协议](https://www.gnu.org/licenses/agpl-3.0.html)

---

## File: doc/AIPPT.md

## 模板式AIPPT的基本原理
1. 定义PPT结构（一套PPT中都有什么类型的页面，每种页面都有些什么内容）；
2. 基于以上结构，定义数据格式，该数据将用于AI生成结构化的PPT数据，具体结构见：
    - 示例数据：`public/mocks/AIPPT.json`
    - 结构定义：`src/types/AIPPT.ts`
3. 制作模板，模板中标记好结构类型；
4. AI生成符合第1步定义的PPT结构的数据；
5. 利用AI或其他方案，生成相关的配图（常见途径有：AI文生图、图库搜索匹配）；
6. 将AI生成的数据、配图与模板进行匹配结合，生成最终的PPT。

> 注1：虽然当前线上版本不提供配图演示效果，但是AIPPT的方法是支持此功能的，你只需要自己提供图片源，按照要求的格式将待选图片集合传入AIPPT方法即可。

> 注2：以上仅适用模板式AIPPT，非模板式AIPPT可以直接生成最终目标格式，参考：`AI_PPT_SCHEMA.md`

## AIPPT模板制作流程
1. 打开PPTist；
2. 制作模板页面；
3. 打开左上角菜单[幻灯片类型标注]功能；
4. 为制作好的页面标注页面类型和节点类型；
5. 使用导出功能导出为JSON文件。

> 注意：实际上并不存在专门提供给AIPPT的模板。所谓的AIPPT模板只是把在PPTist中制作的普通页面标注上类型标记而已。这些数据不仅仅用于AI生成PPT，也可以作为普通的页面模板使用。

## 模板标记类型：页面标记和节点标记
#### 封面页
* 标题
* 正文
* 图片（背景图、页面插图）
#### 目录页
* 目录标题（标记类型为：列表项目）
* 图片（背景图、页面插图）
#### 过渡页（章节过渡）
* 标题
* 正文
* 节编号
* 图片（背景图、页面插图）
#### 内容页
* 标题
* 2～4个内容项，包括：
  * 内容项标题（标记类型为：列表项标题）
  * 内容项正文（标记类型为：列表项目）
  * 内容项编号（标记类型为：项目编号）
* 图片（背景图、页面插图、项目插图）
#### 结束页（致谢页）
* 图片（背景图、页面插图）

> 节点标记分为两种 - 文本标记和图片标记：
> - 文本标记可作用于文本节点和带文字的形状节点；
> - 图片标记只作用于图片节点；
> - 你可以自行添加更多类型的标记（如图表）。

## AIPPT模板制作原则
一个用于AIPPT的模板至少包括以下页面（至少13页，但建议30页以上）：
* 1个封面页（建议2个以上）
* 6个目录页：2～6项目录各1个，10项目录的1个（建议各2个）
* 1个过渡页（建议3个以上）
* 4个内容页：2～4项内容各1个，1项内容的1个（建议各2个）
* 1个结束页（建议2个以上）

> 注意：
> 1. 以上页数仅满足当前替换逻辑的最基本要求，如果希望AI生成的PPT具有一定的随机性，需要适当增加每种页面的数量（举个例子，假设模板中存在3个封面页，生成时会从3个中随机选择1个使用）；
> 2. 当前替换逻辑下，目录页可支持1～20个目录项，内容页可支持1～12个内容项，但不需要每种数量的模板都做一遍，因为程序会自动通过模板的拼接/裁减方式来实现特殊的项目数；
> 3. 你可以自行调整替换逻辑，以支持更多情况。

---

## File: doc/Canvas.md

## 画布与元素

#### 编辑器的基本结构
```
└──编辑器
    ├── 顶部菜单栏
    ├── 左侧导航栏
    ├── 右侧导航栏
    ├── 中上部插入/工具栏
    ├── 底部演讲者备注
    └── 画布
         ├── 可视区域
         │    ├── 可编辑元素
         │    └── 鼠标选框
         │
         └── 画布工具
              ├── 参考线
              ├── 标尺
              ├── 元素操作节点层（如拖拽缩放点）
              ├── 吸附对齐线
              └── 可视区域背景
```

#### 画布的基本原理
我们把关注点放在相对复杂的【画布】部分。画布中的每一个元素都由一组数据来描述，例如：
```typescript
interface PPTBaseElement {
  id: string;
  left: number;
  top: number;
  width: number;
  height: number;
}
```
顾名思义，`left` 表示元素距离画布左上角的位置，`width` 表示元素的宽度，以此类推。
重点需要知道的是：可视区域默认以 宽1000像素 、高562.5像素为基础比例。即无论画布和可视区域实际大小是多少，一个 `{ width: 1000px, height: 562.5px, left: 0, top: 0 }` 的元素一定会正好铺满整个可视区域。
具体实现的方法很简单：假设可视区域的实际宽度为 1200px ，计算出此时的缩放比为 1200 / 1000 = 1.2 ，然后将可视区域内的元素全部缩放到 1.2 倍即可。
同理【缩略图】 和 【放映页面】 其实上就是一个实际大小更小或更大的可视区域。
> 注：1000×562.5的宽高是可以通过修改`src/store/slides.ts`中的`viewportSize`来调整的。

#### 画布内的元素
除了上述中的位置和尺寸信息，还可以携带更多的数据，以一个文本元素为例：
```typescript
interface PPTTextElement {
  type: 'text';
  id: string;
  left: number;
  top: number;
  lock?: boolean;
  groupId?: string;
  width: number;
  height: number;
  link?: string;
  content: string;
  rotate: number;
  defaultFontName: string;
  defaultColor: string;
  outline?: PPTElementOutline;
  fill?: string;
  lineHeight?: number;
  wordSpace?: number;
  opacity?: number;
  shadow?: PPTElementShadow;
}
```
你可以定义一个 `rotate` 来表示文本框旋转的角度、定义一个 `opacity` 来表示文本框的透明度 等。在实现时只需要按照你所定义的数据来渲染元素组件即可，而编辑元素的本质就是在修改这些数据。
以上就是一个画布最基本的组成了。

---

## File: doc/CustomElement.md

## 如何自定义一个元素

我们以【网页元素】为例，来梳理下自定义一个元素的过程。
> 完整代码在 https://github.com/pipipi-pikachu/PPTist/tree/document-demo

> 注意：由于版本更新，该文档和仓库中的代码并不是直接复制粘贴就可以使用，这里仅提供思路。

### 编写新元素的结构与配置
首先需要定义这个元素的结构，并添加该元素类型
```typescript 
// types/slides.ts

export const enum ElementTypes {
  TEXT = 'text',
  IMAGE = 'image',
  SHAPE = 'shape',
  LINE = 'line',
  CHART = 'chart',
  TABLE = 'table',
  LATEX = 'latex',
  VIDEO = 'video',
  AUDIO = 'audio',
  FRAME = 'frame', // add
}

// add
export interface PPTFrameElement extends PPTBaseElement {
  type: 'frame'
  id: string;
  left: number;
  top: number;
  width: number;
  height: number;
  url: string; // 网页链接地址
}

// 修改 PPTElement Type
export type PPTElement = PPTTextElement | PPTImageElement | PPTShapeElement | PPTLineElement | PPTChartElement | PPTTableElement | PPTLatexElement | PPTVideoElement | PPTAudioElement | PPTFrameElement
```

在配置文件中添加新元素的中文名，以及最小尺寸：
```typescript
// configs/element

export const ELEMENT_TYPE_ZH = {
  text: '文本',
  image: '图片',
  shape: '形状',
  line: '线条',
  chart: '图表',
  table: '表格',
  video: '视频',
  audio: '音频',
  frame: '网页', // add
}

export const MIN_SIZE = {
  text: 20,
  image: 20,
  shape: 15,
  chart: 200,
  table: 20,
  video: 250,
  audio: 20,
  frame: 200, // add
}
```

### 编写新元素组件
然后开始编写该元素的组件：
```html


<template>
  
    
       handleSelectElement($event)"
        @touchstart="$event => handleSelectElement($event)"
      >
        

        
        
        
        

         handleSelectElement($event, false)"
          @touchstart="$event => handleSelectElement($event, false)"
        >
      
    
  
</template>

<script lang="ts" setup>
import { PropType } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import { PPTFrameElement } from '@/types/slides'
import { ContextmenuItem } from '@/components/Contextmenu/types'

const props = defineProps({
  elementInfo: {
    type: Object as PropType,
    required: true,
  },
  selectElement: {
    type: Function as PropType<(e: MouseEvent | TouchEvent, element: PPTFrameElement, canMove?: boolean) => void>,
    required: true,
  },
  contextmenus: {
    type: Function as PropType<() => ContextmenuItem[] | null>,
  },
})

const { handleElementId } = storeToRefs(useMainStore())

const handleSelectElement = (e: MouseEvent | TouchEvent, canMove = true) => {
  e.stopPropagation()
  props.selectElement(e, props.elementInfo, canMove)
}
</script>

<style lang="scss" scoped>
.editable-element-frame {
  position: absolute;
}
.element-content {
  width: 100%;
  height: 100%;
  cursor: move;
}
.drag-handler {
  position: absolute;

  &.top {
    height: 20px;
    left: 0;
    right: 0;
    top: 0;
  }
  &.bottom {
    height: 20px;
    left: 0;
    right: 0;
    bottom: 0;
  }
  &.left {
    width: 20px;
    top: 0;
    bottom: 0;
    left: 0;
  }
  &.right {
    width: 20px;
    top: 0;
    bottom: 0;
    right: 0;
  }
}
.mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
</style>
```

此外我们需要另一个不带编辑功能的基础版组件，用于缩略图/放映模式下显示：
```html


<template>
  
    
      
        

        
      
    
  
</template>

<script lang="ts" setup>
import { PropType } from 'vue'
import { PPTFrameElement } from '@/types/slides'

const props = defineProps({
  elementInfo: {
    type: Object as PropType,
    required: true,
  },
})
</script>

<style lang="scss" scoped>
.base-element-frame {
  position: absolute;
}
.element-content {
  width: 100%;
  height: 100%;
}
.mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
</style>
```

在这里你可能会发现，这两个组件非常相似，确实如此，对于比较简单的元素组件来说，可编辑版和不可编辑版是高度一致的，不可编辑版可能仅仅是少了一些方法而已。但是对于比较复杂的元素组件，两者的差异就会比较大了（具体可以比较文本元素和图片元素的两版），因此，你可以自行判断是否将二者合并抽象为一个组件，这里不过多展开。

编写完元素组件，我们需要把它用在需要的地方，具体可能包括：

- 缩略图元素组件 `views/components/ThumbnailSlide/ThumbnailElement.vue`
- 放映元素组件 `views/Screen/ScreenElement.vue`
- 可编辑元素组件 `views/Editor/Canvas/EditableElement.vue`
- 移动端可编辑元素组件 `views/Mobile/MobileEditor/MobileEditableElement.vue`

一般来说，前两者使用不可编辑版，后两者使用可编辑版。
这里仅以画布中的可编辑元素组件为例：
```html


<script lang="ts" setup>
 import FrameElement from '@/views/components/element/FrameElement/index.vue'

 const currentElementComponent = computed(() => {
  const elementTypeMap = {
    [ElementTypes.IMAGE]: ImageElement,
    [ElementTypes.TEXT]: TextElement,
    [ElementTypes.SHAPE]: ShapeElement,
    [ElementTypes.LINE]: LineElement,
    [ElementTypes.CHART]: ChartElement,
    [ElementTypes.TABLE]: TableElement,
    [ElementTypes.LATEX]: LatexElement,
    [ElementTypes.VIDEO]: VideoElement,
    [ElementTypes.AUDIO]: AudioElement,
    [ElementTypes.FRAME]: FrameElement, // add
  }
  return elementTypeMap[props.elementInfo.type] || null
})
</script>
```

在画布的可编辑元素中，还需要为元素添加操作节点 `Operate`（一般包括八个缩放点、四条边线、一个旋转点），对于特殊的元素（如线条的操作节点明显与其他不同）你可以自己编写该组件，但是一般情况下可以直接使用已经编写好的通用操作节点：
```html


<script lang="ts" setup>
const currentOperateComponent = computed(() => {
  const elementTypeMap = {
    [ElementTypes.IMAGE]: ImageElementOperate,
    [ElementTypes.TEXT]: TextElementOperate,
    [ElementTypes.SHAPE]: ShapeElementOperate,
    [ElementTypes.LINE]: LineElementOperate,
    [ElementTypes.TABLE]: TableElementOperate,
    [ElementTypes.CHART]: CommonElementOperate,
    [ElementTypes.LATEX]: CommonElementOperate,
    [ElementTypes.VIDEO]: CommonElementOperate,
    [ElementTypes.AUDIO]: CommonElementOperate,
    [ElementTypes.FRAME]: CommonElementOperate, // add
  }
  return elementTypeMap[props.elementInfo.type] || null
})
</script>
```

### 编写右侧元素编辑面板
接下来需要为元素添加一个样式面板。当选中元素时，右侧工具栏会自动聚焦到该面板，你需要在这里添加一些你认为需要的设置项来操作元素本身，只需要记住一点：修改元素实际是修改元素的数据，也就是最开始定义的结构中的各个字段。
另外，修改元素后不要忘了将操作添加到历史记录。
```html


<template>
  
    
      网页链接：
      
      确定
    
  
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'

const slidesStore = useSlidesStore()
const { handleElementId } = storeToRefs(useMainStore())

const { addHistorySnapshot } = useHistorySnapshot()

const url = ref('')

const updateURL = () => {
  if (!handleElementId.value) return
  slidesStore.updateElement({ id: handleElementId.value, props: { url: url.value } })
  addHistorySnapshot()
}
</script>
```
```html
<script lang="ts" setup>
import FrameStylePanel from './FrameStylePanel.vue'
  
const panelMap = {
  [ElementTypes.TEXT]: TextStylePanel,
  [ElementTypes.IMAGE]: ImageStylePanel,
  [ElementTypes.SHAPE]: ShapeStylePanel,
  [ElementTypes.LINE]: LineStylePanel,
  [ElementTypes.CHART]: ChartStylePanel,
  [ElementTypes.TABLE]: TableStylePanel,
  [ElementTypes.LATEX]: LatexStylePanel,
  [ElementTypes.VIDEO]: VideoStylePanel,
  [ElementTypes.AUDIO]: AudioStylePanel,
  [ElementTypes.FRAME]: FrameStylePanel, // add
}
</script>
```

### 创建元素
这是自定义一个新元素的最后一步。首先编写一个创建元素的方法：
```typescript
// src\hooks\useCreateElement.ts

const createFrameElement = (url: string) => {
  createElement({
    type: 'frame',
    id: nanoid(10),
    width: 800,
    height: 480,
    rotate: 0,
    left: (VIEWPORT_SIZE - 800) / 2,
    top: (VIEWPORT_SIZE * viewportRatio.value - 480) / 2,
    url,
  })
}
```
然后在插入工具栏中使用：
```html


<template>
  
    
      
      插入网页
    
  
</template>

<script lang="ts" setup>
const {
  createImageElement,
  createChartElement,
  createTableElement,
  createLatexElement,
  createVideoElement,
  createAudioElement,
  createFrameElement, // add
} = useCreateElement()
</script>
```
点击【插入网页】按钮，你就会看到一个网页元素被添加到画布中了。

### 总结
至此就是自定义一个元素的基本流程了。整个过程比较繁琐，但并不复杂，重点在于元素结构的定义与元素组件的编写，这决定了新元素将具备怎样的能力与外表。而其他的部分仅依葫芦画瓢即可。
除此之外，还有一些非必须的调整：比如你希望导出能够支持新元素，则需要在导出相关的方法中进行扩展；比如你希望主题功能能够应用在新元素上，则需要在主题相关的方法中进行扩展，以此类推。

---

## File: doc/DirectoryAndData.md

## 项目目录与数据结构

### 项目目录结构
```
├── assets                        // 静态资源
│   ├── fonts                     // 在线字体文件
│   └── styles                    // 样式
│       ├── antd.scss             // antd默认样式覆盖
│       ├── font.scss             // 在线字体定义
│       ├── global.scss           // 通用全局样式
│       ├── mixin.scss            // scss全局混入
│       ├── variable.scss         // scss全局变量
│       └── prosemirror.scss      // ProseMirror 富文本默认样式
├── components                    // 与业务逻辑无关的通用组件
├── configs                       // 配置文件，如：画布尺寸、字体、动画配置、快捷键配置、预置形状、预置线条等数据。
├── hooks                         // 供多个组件（模块）使用的 hooks 方法
├── mocks                         // mocks 数据
├── plugins                       // 自定义的 Vue 插件
├── services                      // API方法
├── types                         // 类型定义文件
├── store                         // Pinia store，参考：https://pinia.vuejs.org/
├── utils                         // 通用的工具方法
└── views                         // 业务组件目录，分为 `编辑器` 和 `播放器` 两个部分。
    ├── components                // 公用的业务组件
    ├── Editor                    // 编辑器模块
    ├── Screen                    // 播放器模块
    └── Mobile                    // 移动端模块
```


### 数据
幻灯片的数据主要存放在 `src/store/slides.ts` 中。
> 换句话说，在实际的生产环境中，一般需要将该文件内state中的数据（部分）保存到数据库。

包括：
- `title` 幻灯片标题/文件名
- `slides` 幻灯片页面数据，包括每一页的ID、元素内容、备注、背景、动画、切页方式等信息
- `theme` 幻灯片主题数据，包括背景色、主题色、字体颜色、字体等信息
- `viewportSize` 幻灯片可视区域宽度基数（默认1000，即1000×562.5的画布）
- `viewportRatio` 幻灯片可视区域比例（宽:高），默认16:9
- `templates` 幻灯片模板

具体类型的定义可见：[完整数据类型定义](https://github.com/pipipi-pikachu/PPTist/blob/master/src/types/slides.ts)

---

## File: doc/Q&A.md

## 常见问题

#### Q. 为什么xxx快捷键没有作用？

A. 部分快捷键需要聚焦到指定区域才会生效，例如焦点在左边缩略图列表才能使用操作页面的快捷键，焦点在画布区域才能使用操作元素的快捷键。

#### Q. 为什么粘贴没有作用？

A. 请注意允许浏览器访问系统剪贴板。

#### Q. 为什么浏览器刷新或重新打开后，之前做的PPT没有了？

A. 仓库提供的链接仅供演示，且该项目是纯前端部署的，没有后台，不会保存数据。

#### Q. 如何调整幻灯片页面的顺序？

A. 按住左侧缩略图可进行拖拽调整顺序。

#### Q. 为什么插入图片后会出现操作卡顿的情况？

A. 由于本演示项目不依赖后端，插入本地图片实际引用的是Base64，导致数据体积非常大，在真正的生产环境中应该上传图片后引用图片地址，就不会出现这样的情况了。

#### Q. 为什么应用预置主题后没有效果？

A. 设置预置主题的作用是使新添加的元素和页面应用主题样式，不会对已有的元素和页面生效，您可以使用“应用主题到全部”功能，将当前主题应用到全部页面中。

#### Q. 设置在线字体不生效？

A. 设置在线字体时会下载对应的字体文件，该文件较大，需要等待下载完成后才会应用新的字体。

#### Q. 关于导入导出PPTX文件

A. 作为一个在线幻灯片应用，导出、导入 PPTX 文件是非常重要的功能，但是经过调研发现，该功能实现起来的复杂度远超过了预期。由于个人能力和时间有限，这部分功能只能借助第三方的轮子来完成。

- 导出：目前导出功能主要基于 [PptxGenJS](https://github.com/gitbrent/PptxGenJS/) 完成，能够实现大多数基本元素的导出，但还有非常多的缺陷需要一点点完善。同时需要知晓的是：1、该功能依赖 PptxGenJS，对于该库本身无法实现的部分（如动画），本项目也无能为力；2、导出功能的目标只是【导出样式尽可能一致的元素】，而不是一比一将网页还原到PPT，一些样式差异是必然存在的。

- 导入：导入功能目前暂时没有合适的解决方案，还在调研和观望中。如果有感兴趣或做过相关内容的朋友，欢迎来 issues 中讨论。

> PS. 我做了一个 [pptx转json](https://github.com/pipipi-pikachu/pptx2json) 的实验，如果你急需实现导入PPTX文件功能，可以此为参考自行实现。

同时补充一点，本项目不是 office PPT 的专属在线编辑器，本质上与 office PPT 没有任何关系。【导入/导出 ppt 文件】只是项目的一个[功能]而非[目的]。

#### Q. 视频元素支持哪些格式？

A. 本项目只提供最基础的视频能力，正常状态下可以播放video标签本身支持的格式。

此外，可以额外引入 [hls.js](https://github.com/video-dev/hls.js) 或 [flv.js](https://github.com/Bilibili/flv.js) 来支持对应的格式（.m3u8 .flv），你只需要在项目中引入对应的文件（如cdn）即可，无需其他配置。

#### Q. 关于导入JSON文件

A. 首先，出于安全等原因，个人并不建议将这种功能在前端直接暴露给用户，或者说用户根本就不应该接触到JSON这种格式（甚至导出JSON功能的初衷也只是为了方便开发）。如果真的有相关的需求，请自行在服务端实现，核心在于做好进行数据的校验，前端实现也是一样。

#### Q. 打印 / 导出 PDF 样式与实际有出入

A. 请注意在浏览器弹出的打印窗口调整相关的设置。建议：设置边距为【默认】、取消勾选【页眉和页脚】、勾选【背景图形】。另外，建议在正式环境中采用后端生成PDF的方案效果更佳（如puppeteer）。

#### Q. 为什么移动端不支持 xxx 功能？

A. 首先需要明确的一点，就是移动端无论怎么做，体验上都是必然大不如 PC 端的。因此个人将移动端定位为：简单进行一些临时处理的应急使用。真正的设计/制作幻灯片应在电脑上使用完整的功能。如实在有移动端的特殊需求，可尝试在移动端使用电脑模式打开（当然，体验会更槽糕），或者开发者自己进行二次开发。

#### Q. 关于兼容性？

A. 本项目优先兼容Chrome、Firefox。在Safari下可能存在部分兼容性问题。不兼容IE。

#### Q. 为什么不是NPM包？

A. 大家都知道，对于一般的插件/库而言，一个封装好的npm包能够更方便的接入现有的项目中，但PPTist是特殊的，这是一个完整的程序，而不是作为程序的一部分存在。如果你需要使用PPTist，那么我认为你必然需要在此基础上做很多定制化的开发，包括但不限于：与后台的通信、各种模板和预置素材、新的元素类型、使用其他方案实现现有的某些元素、自己的主题、更换快捷键，等等……而不是仅仅安装一个和现有demo一样的东西就行了（这样虽然方便，但在实际的产品开发中没有任何意义）。正如前面所列举的，需要可配置的东西太多了，如果作为一个插件的存在，很难兼顾得了，或者说这样做的开发量是巨大的，目前个人还承担不起。

因此，使用PPTist开发项目正确的做法是：拉取完整的代码、尝试理解它、基于它改造你自己的东西。社区中也不乏类似的项目，例如 [drawio](https://github.com/jgraph/drawio)

#### Q. 关于 AI PPT

A. 首先需要说明，AIPPT不是PPTist的重点，现在或以后都不是，它只是PPTist众多功能中非常小的一部分而已，并且是比较简单一部分，你可以理解为这只是一个跟风的小功能点，我不想蹭AI的热度，但无奈太多人将AI看得太重要太复杂了，于是我做了这个DEMO（它真的没那么复杂），目前此功能仅作参考，内部实现了最基础的AIPPT生成逻辑，即：模板定制 + AI生成数据与模板结合 + 配图替换。为控制成本暂时只能做到这里，但为了达到生产环节的效果，你还需要做更多，例如更多的模板、更细致的AI工作流程。

注：配图替换仅提供方法，不提供实际演示功能，你需要自己提供图片源接入（如AI文生图、图库搜索匹配等方法）

#### Q. 其他

A. 另外需要强调，PPTist只是一个开源项目而非面向普通用户的产品，主要提供的是技术解决方案，一些产品化的需求/优化还需要开发者自己去实现和完善。

## FAQ
#### Q. Why doesn’t the xxx shortcut work?

A. Some shortcuts only work when the focus is on a specific area. For example, the shortcuts for operating pages only work when the focus is on the thumbnail list on the left, and the shortcuts for operating elements only work when the focus is on the canvas area.

#### Q. Why isn’t pasting working?

A. Please make sure to allow the browser access to the system clipboard.

#### Q. Why do my previous PPT disappear after refreshing or reopening the browser?

A. The links provided by the repository are for demonstration purposes only, and the project is deployed as a pure front-end application without a backend, thus it does not save data.

#### Q. How do I adjust the order of slides?

A. You can drag and drop the thumbnails on the left to adjust the order.

#### Q. Why does the application become unresponsive after inserting images?

A. Since this demo project does not rely on a backend, inserting local images actually references Base64 encoded data, which can result in very large data sizes. In a real production environment, you should upload images and reference their addresses to avoid this issue.

#### Q. Why doesn’t the preset theme take effect after being applied?

A. Applying a preset theme affects new elements and pages added, but will not apply to existing elements and pages. You can use the “Apply Theme to All” feature to apply the current theme to all pages.

#### Q. Why doesn’t setting an online font work?

A. Setting an online font involves downloading the corresponding font file, which can be large and requires time to complete the download before the new font is applied.

#### Q. About Importing and Exporting PPTX Files

A. As an online presentation application, the ability to import and export PPTX files is very important. However, it has been found that the complexity of implementing this feature far exceeds expectations. Due to limited personal capacity and time, this functionality can only be achieved with the help of third-party solutions.

Export: The current export function is mainly based on [PptxGenJS](https://github.com/gitbrent/PptxGenJS/), and it can export most basic elements, but there are still many defects that need to be improved. It’s important to note that: 1) This feature relies on PptxGenJS, and for parts that the library itself cannot implement (such as animations), there’s nothing this project can do; 2) The goal of the export function is to export elements with styles as consistent as possible, not to recreate the web page one-to-one in PPT, and some style differences are inevitable.

Import: The import function currently does not have a suitable solution and is still under investigation. If you are interested or have experience in related areas, please discuss in the issues.

> PS. I made an experimental [pptx to json](https://github.com/pipipi-pikachu/pptx2json) converter. If you urgently need to implement the import PPTX file function, you can use this as a reference for your own implementation.

It should be noted that this project is not an exclusive online editor for Office PPT. It is essentially unrelated to Office PPT. The [import/export of PPT files] is just a [feature] of the project, not its [purpose].

#### Q. Which video formats are supported?

A. This project only provides basic video capabilities and can play formats supported by the video tag in normal conditions.

Additionally, you can introduce [hls.js](https://github.com/video-dev/hls.js) or [flv.js](https://github.com/Bilibili/flv.js) to support corresponding formats (.m3u8 .flv) by simply including the corresponding files (such as CDN) in your project, without any other configuration required.

#### Q. About Importing JSON Files

A. Firstly, due to security reasons, I do not recommend exposing such functionality directly to users on the front end, or users should not even come into contact with formats like JSON in the first place (even the export JSON feature was initially intended only for development convenience). If there is a real need, please implement it on the server side, with a focus on data validation, and the same goes for the front end.

#### Q. Print / Export PDF Styles Are Different from the Actual

A. Please adjust the settings in the print dialog that pops up in the browser. It is recommended to set the margins to [default], uncheck [headers and footers], and check [background graphics]. Furthermore, it is recommended to adopt a backend-generated PDF solution (such as Puppeteer) for a more optimal outcome in a formal environment.

#### Q. Why doesn’t the mobile version support xxx feature?

A. The first thing to clarify is that the mobile experience will inevitably be inferior to the PC experience no matter what. Therefore, the mobile version is positioned for simple, temporary handling in emergency situations. True design and creation of slides should be done on a computer with full functionality. If there is a specific need for the mobile version, you can try opening it in desktop mode on mobile (of course, the experience will be worse), or the developer can do further custom development.

#### Q. About Compatibility?

A. This project prioritizes compatibility with Chrome and Firefox. There may be some compatibility issues under Safari. It is not compatible with IE.

#### Q. Why isn’t it an NPM package?

A. Everyone knows that for general plugins/libraries, a well-packaged NPM package can more easily integrate into existing projects. However, PPTist is special; it is a complete program, not a part of another program. If you need to use PPTist, I believe you will necessarily need to do a lot of custom development based on it, including but not limited to: communication with the backend, various templates and pre-installed materials, new element types, using other solutions to implement certain existing elements, your own themes, changing shortcuts, and so on… It’s not just about installing something that is the same as the existing demo (which may be convenient but has no practical significance in actual product development). As previously mentioned, there are many things that need to be configurable, and it would be difficult to cater to all these needs if it were an NPM plugin. The development effort would be enormous, and currently, I cannot afford it.

Therefore, the correct way to develop a project using PPTist is to pull the complete code, try to understand it, and modify it to suit your own needs. There are also similar projects in the community, such as [drawio](https://github.com/jgraph/drawio).

#### Q. About AI PPT
A. I don't want to ride the wave of AI hype, but it's unavoidable as too many people place too much importance on AI. So, I created this DEMO (it's really not that complicated). Currently, this feature is for reference only, and internally, it implements the most basic AI PPT generation logic, which is: template customization + AI-generated data combined with templates + image replacement. To control costs, we can only go this far for now. However, to achieve the effect of a production environment, you would need to do more, such as creating more templates and refining the AI workflow.

Note: Image replacement only provides the method and does not offer an actual demonstration function. You will need to provide your own image sources (such as AI text-to-image generation, image library search matching, etc.).

#### Q. Other

A. Additionally, it is important to emphasize that PPTist is merely an open-source project, not a product tailored for the average user. It primarily offers technical solutions. Some product-oriented demands and optimizations require developers to implement and refine on their own.

---

## File: README_zh.md

[](https://www.github.com/pipipi-pikachu/PPTist/stargazers)
[](https://www.github.com/pipipi-pikachu/PPTist/network/members)
[](https://github.com/pipipi-pikachu/PPTist/issues)
[](https://www.github.com/pipipi-pikachu/PPTist/blob/master/LICENSE)
[](https://gitee.com/pptist/PPTist)
[](https://gitcode.com/pipipi-pikachu/PPTist)

简体中文 | [English](README.md)


# 🎨 PPTist
**PowerPoint-ist（/'pauəpɔintist/）**，一个基于 Web 的在线演示文稿（幻灯片）应用，还原了大部分 Office PowerPoint 常用功能，支持 文字、图片、形状、线条、图表、表格、视频、音频、公式 几种最常用的元素类型，可以在 Web 浏览器中编辑/演示幻灯片。

**在线体验地址👉：[https://pipipi-pikachu.github.io/PPTist/](https://pipipi-pikachu.github.io/PPTist/)**

> 国内镜像（定期同步）：[Gitee](https://gitee.com/pptist/PPTist)、[GitCode](https://gitcode.com/pipipi-pikachu/PPTist)

# ✨ 项目特色
1. 易开发：基于 Vue3.x + TypeScript 构建，不依赖UI组件库，样式定制更轻松、功能扩展更方便；
2. 易使用：随处可见的右键菜单、数十种快捷操作方式、持续深入打磨编辑细节，力求还原桌面应用级的交互体验；
3. 功能丰富：支持 Office PPT 大部分常用元素和功能，支持模板式AIPPT、支持多种格式导出、支持移动端基础编辑和预览；
4. 代码可控：非 vibe coding 的临时产物，代码稳健、可控、易维护，不留技术债。


# 👀 前排提示
1. 本项目的目标受众是**有Web幻灯片开发需求的开发者，需要有基础的web开发经验**，提供的链接只是一个演示地址，不提供任何在线服务。你不应该直接将本项目作为工具使用，也不支持开箱即用。如果你只是需要一个服务或工具，可以选择更优秀和成熟的产品。
2. 这里总结了一些[常见问题](/doc/Q&A.md)，第一次提 Issues 和 PR 时，务必提前阅读此文档。
3. 商用相关请参阅[商业用途](#-商业用途)


# 🧩项目定位
> 本项目的核心定位是**Web 幻灯片编辑/演示应用**，以下是一些常见使用场景推荐度：

- **低代码平台/H5编辑器/图片编辑器/白板应用**（推荐度：完全不推荐）：建议选择匹配度更高的开源项目。
- **AIPPT生成工具**（推荐度：⭐⭐）：本项目支持模板式 AIPPT 生成思路，也提供了面向 AI 直接生成页面数据的结构定义，参考 [AI_PPT_SCHEMA](/doc/AI_PPT_SCHEMA.md)，理论上支持非模板式 PPT 生成（由 AI 直接生成 PPTist 数据）。需要注意的是，AIPPT 的最终效果很大程度取决于模型能力、提示词设计、素材生成/检索等。PPTist 更适合作为结构化生成结果的承载、编辑和二次加工底座，而不是开箱即用的完整 AIPPT 商业方案。
- **PPT文件预览工具**（推荐度：⭐⭐）：本项目支持导入PPTX文件，并能覆盖较多常见页面内容和样式（综合来看，可达到85%+的还原度），可以用于在线预览、轻量校对、内容浏览等场景。但由于PPTX生态本身较复杂，动画、特殊图表、多层嵌套、非标准元素、部分高级样式等仍不可避免的存在还原差异。如果你的业务对像素级还原要求极高，建议结合实际样例进行评估。
- **Office PPT制作工具**（推荐度：⭐⭐）：本项目支持大量Office PPT常用功能，也支持导入和导出本地PPTX文件，可作为在线制作、编辑的基础方案使用。需要注意的是，Office PPT的完整兼容涉及复杂排版、动画、图表、主题、母版等大量细节，文件导入导出时必然会丢失部分细节，无法做到100%还原。因此，如果你的核心目标是完全替代Office PowerPoint，建议结合实际业务文档进行测试和取舍。
- **Web 幻灯片编辑/演示应用**（推荐度：⭐⭐⭐⭐⭐）：这是最推荐的场景，编辑能力和编辑体验是PPTist最核心的优势，你可以在本项目的基础上，根据自己的需求，定制/新增一些个性化的节点/功能，不以导入导出为最终目的（毕竟这些定制化的东西在Office PPT中是不存在的）。**一句话总结：我更希望你基于PPTist打造一个不同于Office PPT的演示类产品，而不只是做一个Office PPT的编辑中转站。**


# 🚀 项目运行
> node version >= 20

```
npm install

npm run dev
```
浏览器访问：http://127.0.0.1:5173/


# 📚 功能列表
### 基础功能
- 历史记录（撤销、重做）
- 快捷键
- 右键菜单
- 导入：PPTX（综合还原度约85%+）、JSON、特有 pptist 文件
- 导出：PPTX（综合还原度约95%+）、JSON、图片、PDF（打印）、特有 pptist 文件
- 模板式AI生成PPT
### 幻灯片页面编辑
- 页面添加、删除
- 页面顺序调整
- 页面复制粘贴
- 幻灯片分节
- 背景设置（纯色、渐变、图片）
- 设置画布尺寸
- 网格线
- 标尺
- 画布缩放、移动
- 主题设置
- 提取已有幻灯片风格
- 演讲者备注（富文本）
- 幻灯片模板
- 翻页动画
- 元素动画（入场、退场、强调）
- 选择面板（隐藏元素、层级排序、元素命名）
- 页面和节点类型标注（可用于模板相关功能）
- 查找/替换
- 批注
### 幻灯片元素编辑
- 元素添加、删除
- 元素复制粘贴
- 元素拖拽移动
- 元素旋转
- 元素缩放
- 元素多选（框选、点选）
- 多元素组合
- 多元素批量编辑
- 元素锁定
- 元素吸附对齐（移动和缩放）
- 元素层级调整
- 元素对齐到画布
- 元素对齐到其他元素
- 多元素均匀分布
- 拖拽添加图文
- 粘贴外部图片
- 元素坐标、尺寸和旋转角度设置
- 元素超链接（链接到网页、链接到其他幻灯片页面）
- 元素浮动气泡菜单
#### 文字
- 富文本编辑（颜色、高亮、字体、字号、加粗、斜体、下划线、删除线、角标、行内代码、引用、超链接、对齐方式、序号、项目符号、段落缩进、清除格式）
- 行高
- 字间距
- 段间距
- 首行缩进
- 填充色
- 边框
- 阴影
- 透明度
- 竖向文本
- 文本框边距
- 高度自适应/固定（固定时可选垂直对齐方向）
- AI改写/扩写/缩写
#### 图片
- 裁剪（自定义、按形状、按纵横比）
- 圆角
- 滤镜
- 着色（蒙版）
- 翻转
- 边框
- 阴影
- 替换图片
- 重置图片
- 设置为背景图
#### 形状
- 自由绘制任意多边形
- 自由绘制任意线条（未封闭形状模拟）
- 可视化的路径创建方式
- 替换形状
- 填充（纯色、渐变、图片）
- 边框
- 阴影
- 透明度
- 翻转
- 形状格式刷
- 编辑文字（支持富文本，与文字元素的富文本编辑功能近似）
- 文本框边距
- 文本垂直对齐方向
#### 线条
- 直线、基础折线/曲线
- 颜色
- 宽度
- 样式（实线、虚线、点线）
- 端点样式
#### 图表（柱状图、条形图、折线图、面积图、散点图、饼图、环形图、雷达图）
- 图表类型转换
- 数据编辑
- 背景填充
- 主题色
- 坐标轴/坐标文字颜色
- 网格颜色
- 堆积模式、平滑曲线等
#### 表格
- 行、列添加删除
- 主题设置（主题色、表头、汇总行、第一列、最后一列）
- 合并单元格
- 单元格样式（填充色、文字颜色、加粗、斜体、下划线、删除线、对齐方式）
- 边框
#### 视频
- 预览封面设置
- 自动播放
#### 音频
- 图标颜色
- 自动播放
- 循环播放
#### 公式
- LaTeX编辑
- 颜色设置
- 公式线条粗细设置
### 幻灯片放映
- 画笔工具（画笔/形状/箭头/荧光笔标注、橡皮擦除、黑板模式）
- 全部幻灯片预览
- 触底显示缩略图导航
- 计时器工具
- 激光笔
- 自动放映
- 演讲者视图
- 观众视图
### 移动端
- 基础编辑
    - 页面添加、删除、复制、备注、撤销重做
    - 插入文字、图片、矩形、圆形
    - 元素通用操作：移动、缩放、旋转、复制、删除、层级调整、对齐
    - 元素样式：文字（加粗、斜体、下划线、删除线、字号、颜色、对齐方向）、填充色
- 基础预览
- 播放预览


# 🎯 开发
目前没有完整的开发文档，但下面这些文档可能会对你有一些帮助：
- [项目目录与数据结构](/doc/DirectoryAndData.md)
- [画布与元素的基本原理](/doc/Canvas.md)
- [如何自定义一个元素](/doc/CustomElement.md)
- [关于AIPPT](/doc/AIPPT.md)

下面是一些辅助开发的工具/仓库：
- 导入PPTX文件参考：[pptxtojson](https://github.com/pipipi-pikachu/pptxtojson)
- 绘制形状：[svgPathCreator](https://github.com/pipipi-pikachu/svgPathCreator)


# 📄 版权声明/开源协议
[AGPL-3.0 License](/LICENSE) | Copyright © 2020-PRESENT [pipipi-pikachu](https://github.com/pipipi-pikachu)


# 🧮 商业用途
## 商用须知
- 本项目禁止闭源商用，如果你希望将其用于商业项目，请尊重开源，**严格遵循 [AGPL-3.0 协议](https://www.gnu.org/licenses/agpl-3.0.html)**，回馈开源社区；
- 如果你因为任何原因，无法执行 AGPL-3.0 协议，可以选择：
    1. 使用 Apache 2.0 协议版本（最后更新时间为2022年5月，已停止维护，[点此下载](https://github.com/pipipi-pikachu/PPTist/archive/f1a35bb8e045124e37dcafd6acbf40b4531b69aa.zip)）；
    2. 成为项目的重要贡献者（先违反协议后再成为贡献者不适用此项），包括：
        - 你的代码被本项目作为依赖引用，包括：npm安装、文件引用、代码片段引用（引用处会注明）；
        - 你给本项目提交过重要的 PR 或 Issue（由作者主观判断，符合的 PR 或 Issue 会打上`important contribution`标签）；
    3. [邮件联系作者](mailto:pipipi_pikachu@163.com)付费获取独立的商业授权（违反协议后被作者找到的不适用此项）。独立授权价格：
        - 一年：2999元；
        - 永久：5699元（不含税）；
- 请优先考虑执行AGPL-3.0协议，如需付费获取独立的商业授权，请务必在联系作者前阅读以下内容：
    - **独立商业授权表示**：
        - 作者单独出具商业授权协议文件（邮件联系作者获取），双方按流程签署协议；
        - 允许将代码用于商业行为，且不必执行 AGPL-3.0 协议；
        - 授权对象可以是个人或组织（企业），允许授权对象名下的所有产品使用本项目代码；
    - **授权流程**：
        1. 被授权方确认协议内容，若无异议，需提供协议中所需的个人/企业信息；
        2. 由作者补充好协议双方信息后打印签字，并将电子扫描件发给被授权方；
        3. 被授权方收到后，将协议打印盖章，再扫描电子档发回给作者，此时协议开始生效；
        4. 被授权方在协议规定时间内支付费用，并保留好支付凭证，授权结束；
    - **授权不等于出售软件或服务**：
        - 不存在其他“商业版本”、不提供任何API/SDK/在线服务/技术支持/技术咨询/定制开发；
        - 不提供可直接交付的产品，你仍需从本仓库获取代码自行开发；
        - 该软件无法开箱即用，至少也得自行接入后端能力（需要有最基本的web开发经验）；
        - 不保证未来版本的兼容性，不保证代码没有bug；
        - 作者不承担任何因使用本项目代码而导致的直接或间接损失；
        - 务必提前做好调研，判断该软件是否符合需求，包括但不限于功能（是否能满足业务需求）和开发（是否上手当前技术栈/实现方案）；
- 不接受[黑名单/耻辱柱](/doc/Blacklist.md)或存在违反协议行为的对象通过任何形式获取商业授权；
- 作者倡导异步沟通（正式、信息整合度高），**不加私人微信/QQ/手机号等**，有任何授权相关疑问请邮件联系，谢谢理解；
- 提需求/报bug/询问技术方案等非授权相关咨询，请在 [Issues](https://github.com/pipipi-pikachu/PPTist/issues) 中进行。

## AGPL-3.0 协议
协议核心要求用通俗的语言解释如下：
- **开源义务**：如果你用了 AGPL 的代码，无论你或你的下游怎么使用/修改，都必须把你最终的代码全部完整公开出来，并继续以 AGPL 协议开源（强调：必须延续 AGPL 协议，保持开源的传染性，不能更换其他协议）。
- **网络服务也要开源**：即使你只是用 AGPL 的代码做了一个网站或网络服务，别人通过网络用你的服务时，你也需要遵守上一条**开源义务**。
- **保留版权声明**：你不能删掉代码里原来的作者信息和许可证声明，得告诉大家这代码是从哪儿来的。
- **不能加额外限制**：你不能在衍生出来的 AGPL 代码上加一些限制，比如不让别人再分发代码，或者要求别人付费才能使用代码（包括但不限于：要求别人购买授权/服务/产品等）。
- **免责声明**：作者不保证代码没有 bug，也不对使用后果负责。

> 详细协议内容见官方文档：[AGPL-3.0 协议](https://www.gnu.org/licenses/agpl-3.0.html)