当前位置: 首页 > article >正文

【PPTist】画布状态管理

一、简介

在 PPTist 项目中,画布是指幻灯片编辑区域的主要工作区,具体包括:

  • 基础尺寸
  • 主要功能:显示和编辑幻灯片、元素拖拽和缩放等、网格线和标尺对齐、元素的选择和多选
  • 相关状态:缩放比例、画布能否被拖拽、网格线尺寸等
  • 主要操作:缩放、平移、显示网格线标尺等
  • 组成部分:背景层、内容层、工具层
  • 画布的特点:
    响应式:自适应窗口大小、保持宽高比例、支持缩放适配
    交互性:支持拖拽移动、支持元素选择、支持快捷键操作
    辅助功能:网格对齐、标尺显示、智能参考线

二、基础属性

画布的定义在src/store/main.ts文件,看一下接口定义,包含各个部分的编辑状态、选中状态等等

// 主状态接口定义
export interface MainState {
  activeElementIdList: string[]      // 被选中的元素ID集合
  handleElementId: string            // 正在操作的元素ID(如调整大小、旋转等)
  activeGroupElementId: string       // 组合元素中被选中的子元素ID
  hiddenElementIdList: string[]      // 被隐藏的元素ID集合

  canvasPercentage: number          // 画布可视区域百分比
  canvasScale: number               // 画布缩放比例(基于宽度1000px)
  canvasDragged: boolean            // 画布是否被拖拽移动

  thumbnailsFocus: boolean          // 左侧导航缩略图区域是否聚焦
  editorAreaFocus: boolean          // 编辑区域是否聚焦
  disableHotkeys: boolean           // 是否禁用快捷键

  gridLineSize: number              // 网格线尺寸(0表示不显示网格线)
  showRuler: boolean                // 是否显示标尺

  creatingElement: CreatingElement | null   // 正在创建的元素信息
  creatingCustomShape: boolean              // 是否正在绘制自定义形状

  availableFonts: typeof SYS_FONTS         // 当前环境可用的字体列表
  toolbarState: ToolbarStates              // 右侧工具栏状态

  clipingImageElementId: string            // 当前正在裁剪的图片ID
  isScaling: boolean                       // 是否正在进行元素缩放

  richTextAttrs: TextAttrs                 // 富文本编辑器属性
  selectedTableCells: string[]             // 选中的表格单元格

  selectedSlidesIndex: number[]            // 当前选中的页面索引集合
  dialogForExport: DialogForExportTypes    // 导出对话框类型

  databaseId: string                       // 当前应用的indexedDB数据库ID 随机数

  textFormatPainter: TextFormatPainter | null    // 文字格式刷
  shapeFormatPainter: ShapeFormatPainter | null  // 形状格式刷

  showSelectPanel: boolean                 // 是否显示选择面板
  showSearchPanel: boolean                 // 是否显示查找替换面板
  showNotesPanel: boolean                  // 是否显示批注面板
}

三、计算属性

// 计算属性
getters: {
  // 获取当前选中的元素列表
  activeElementList(state) {
    const slidesStore = useSlidesStore()
    const currentSlide = slidesStore.currentSlide
    if (!currentSlide || !currentSlide.elements) return []
    return currentSlide.elements.filter(element => state.activeElementIdList.includes(element.id))
  },

  // 获取当前操作的元素
  handleElement(state) {
    const slidesStore = useSlidesStore()
    const currentSlide = slidesStore.currentSlide
    if (!currentSlide || !currentSlide.elements) return null
    return currentSlide.elements.find(element => state.handleElementId === element.id) || null
  },
},

四、方法

action 的定义还挺多的,但是里面的实现都比较简单,都是设置状态的值。大家肯定看一眼就明白啦

五、使用

画布状态都在哪里使用,这是一个关键的问题,以后我们在开发新功能的时候,需要知道什么时候要调用这里面的方法。
我们以 setCanvasPercentage 方法为例,这个方法是用来改变画布的缩放的百分比的,在 src/hooks/useScaleCanvas.ts 中使用

/**
 * 缩放画布百分比
 * @param command 缩放命令:放大、缩小
 */
const scaleCanvas = (command: '+' | '-') => {
  let percentage = canvasPercentage.value
  const step = 5
  const max = 200
  const min = 30
  if (command === '+' && percentage <= max) percentage += step
  if (command === '-' && percentage >= min) percentage -= step

  mainStore.setCanvasPercentage(percentage)
}

/**
 * 设置画布缩放比例
 * 但不是直接设置该值,而是通过设置画布可视区域百分比来动态计算
 * @param value 目标画布缩放比例
 */
const setCanvasScalePercentage = (value: number) => {
  const percentage = Math.round(value / canvasScale.value * canvasPercentage.value) / 100
  mainStore.setCanvasPercentage(percentage)
}

/**
 * 重置画布尺寸和位置
 */
const resetCanvas = () => {
  mainStore.setCanvasPercentage(90)
  if (canvasDragged) mainStore.setCanvasDragged(false)
}

设置完了之后呢,canvasPercentage这个属性在哪里使用呢?
是在 src/views/Editor/Canvas/hooks/useViewportSize.ts 这个文件中

  // 可视区域缩放或比例变化时,重置/更新可视区域的位置
  watch(canvasPercentage, setViewportPosition)

监听到这个属性变化之后,会计算出画布的位置,然后执行

  // 画布可视区域位置和大小的样式
const viewportStyles = computed(() => ({
  width: VIEWPORT_SIZE,
  height: VIEWPORT_SIZE * viewportRatio.value,
  left: viewportLeft.value,
  top: viewportTop.value,
}))

viewportStyles 这个属性又在 src/views/Editor/Canvas/index.vue 文件中使用

<div 
  class="viewport-wrapper"
  :style="{
    width: viewportStyles.width * canvasScale + 'px',
    height: viewportStyles.height * canvasScale + 'px',
    left: viewportStyles.left + 'px',
    top: viewportStyles.top + 'px',
  }"
>

viewport-wrapper 这个元素我们看一下是谁,就是这个编辑区域
在这里插入图片描述
可以看出,项目的源码分工还是很细的
如果我们要在编辑区域增加一个新的属性,就需要把属性定义到src/store/main.ts 文件中,然后通过 src/hooks/useXXX.ts 文件进行修改,并且导出模版中需要使用的属性,然后在模版中使用。


http://www.kler.cn/a/440972.html

相关文章:

  • FreeRTOS从入门到精通 第十五章(事件标志组)
  • C#方法(练习)
  • .NET Core缓存
  • 《深度揭秘:TPU张量计算架构如何重塑深度学习运算》
  • 哈希表实现
  • Vue-day2
  • Flink CDC 读取oracle库数据性能优化
  • Qt之修改窗口标题、图标以及自定义标题栏(九)
  • 【Leetcode 每日一题】3291. 形成目标字符串需要的最少字符串数 I
  • 建站经验:服务器同步与数据库备份的终极解决方案
  • Arrys.asList踩坑实录
  • Linux计算时间差
  • 【LeetCode】2381、字母移位 II
  • Three.js相机Camera控件知识梳理
  • 压力测试Jmeter简介
  • Java全栈项目实战:校园论坛社交平台开发
  • Vue3实现双向绑定的基本原理和代码示例解析
  • HAL库与标准库的GPIO配置结构体对比
  • 免费下载 | 2024全球AI网络安全产品洞察报告
  • Python-基于Pygame的小游戏(贪吃蛇)(一)
  • Flink State面试题和参考答案-(下)
  • 数智读书笔记系列003 深度学习革命 从历史到未来
  • C++ ofstream:写操作
  • 如何在服务器上安装 Maven
  • busybox学习——简单介绍
  • 学习记录(13):VR晕动症-VR Motion Sickness