【PPTist】批注、选择窗格

news2025/1/10 13:22:46

前言:本篇文章研究批注和选择窗格两个小功能

一、批注

批注功能就是介个小图标
在这里插入图片描述
点击可以为当前页的幻灯片添加批注,还能删除之前的批注
在这里插入图片描述
如果我们增加了登录功能,还可以在批注上显示当前的用户名和头像,不过现在是写死的。
左侧幻灯片缩略图的左上角会显示当前幻灯片的批注的数量
在这里插入图片描述
首先我们来换一个个性的头像吧!
看下头像现在是一个icon
在这里插入图片描述

这段HTML在 src/views/Editor/NotesPanel.vue 文件中
首先创建一个文件目录 src/assets/images/avatars,然后把中意的头像放进去,然后把模版中的icon改成我们的头像就好啦
不过我们也可以写的更智能一点,通过用户名动态渲染

<img :src="getImageUrl(note.user)">
const getImageUrl = (user: string) => {
  return new URL(`../../assets/images/avatars/${user}.png`, import.meta.url).href
}

图片的名字和用户名保持一致就可以了

在这里插入图片描述

最爱的小乔~~~
在这里插入图片描述

这里的批注就是一个列表,添加批注就向批注列表中增加一个数据,然后还需要通过 slidesStore.updateSlide() 方法,更新当前幻灯片的批注

const createNote = () => {
  if (!content.value) {
    if (textAreaRef.value) textAreaRef.value.focus()
    return
  }

  const newNote: Note = {
    id: nanoid(),
    content: content.value,
    time: new Date().getTime(),
    user: '小乔',
  }
  if (handleElementId.value) newNote.elId = handleElementId.value

  const newNotes = [
    ...notes.value,
    newNote,
  ]
  slidesStore.updateSlide({ notes: newNotes })

  content.value = ''
}

还有一个可以给别人的批注回复的功能
在这里插入图片描述
回复是 note.replie 属性,添加回复也跟上面的添加批注的逻辑差不多,没啥复杂的
有一点,这里没有调用 addHistorySnapshot() ,说明批注相关的操作是不能回退的
在这里插入图片描述

二、选择窗格

在这里插入图片描述
可以控制幻灯片的几个部分的显示和隐藏。
我们在全局搜索 “选择窗格” 就可以发现,点击这个按钮的时候,会触发的方法是
src/views/Editor/CanvasTool/index.vue

// 打开选择面板
const toggleSelectPanel = () => {
  mainStore.setSelectPanelState(!showSelectPanel.value)
}

修改公共的数据中的属性 showSelectPanel
src/store/main.ts

setSelectPanelState(show: boolean) {
  this.showSelectPanel = show
},

然后全局搜索这个属性,会在下面这个模版中发现它的踪迹
src/views/Editor/index.vue

<SelectPanel v-if="showSelectPanel" />

组件是 src/views/Editor/SelectPanel.vue
组件的根元素是 MoveablePanel 组件,通过它的名字我们也可以看出,这个组件是可移动的。而且既然这个自定义组件的标签中能放东西,肯定是使用插槽实现的。src/components/MoveablePanel.vue
然后我们还是看选择窗格组件,里面的功能

1、全部显示全部隐藏

是在 src/hooks/useHideElement.ts 中的 showAllElementshideAllElements

const showAllElements = () => {
  const currentSlideElIdList = currentSlide.value.elements.map(item => item.id)
  const needHiddenElementIdList = hiddenElementIdList.value.filter(item => !currentSlideElIdList.includes(item))
  mainStore.setHiddenElementIdList(needHiddenElementIdList)
}
const hideAllElements = () => {
  const currentSlideElIdList = currentSlide.value.elements.map(item => item.id)
  mainStore.setHiddenElementIdList([...hiddenElementIdList.value, ...currentSlideElIdList])
  if (activeElementIdList.value.length) mainStore.setActiveElementIdList([])
}

隐藏元素主要是通过修改 hiddenElementIdList
src/views/Editor/Canvas/index.vue 中,元素会通过 hiddenElementIdList 判断是否展示

v-show="!hiddenElementIdList.includes(element.id)"
2、点击菜单项

点击下面的列表中的菜单项的时候,幻灯片中的对应的元素会被选中
在这里插入图片描述
执行的是这个方法,好像之前见过来着,这是个公共的方法
src/hooks/useSelectElement.ts

// 将指定元素设置为被选择状态
const selectElement = (id: string) => {
  if (handleElementId.value === id) return
  if (hiddenElementIdList.value.includes(id)) return
  
  const lockedElements = currentSlide.value.elements.filter(el => el.lock)
  if (lockedElements.some(el => el.id === id)) return

  mainStore.setActiveElementIdList([id])
}

点击菜单项后面的小眼睛切换元素的显示的时候,还是修改 hiddenElementIdList
src/hooks/useHideElement.ts

const toggleHideElement = (id: string) => {
  if (hiddenElementIdList.value.includes(id)) {
    mainStore.setHiddenElementIdList(hiddenElementIdList.value.filter(item => item !== id))
  }
  else mainStore.setHiddenElementIdList([...hiddenElementIdList.value, id])

  if (activeElementIdList.value.includes(id)) mainStore.setActiveElementIdList([])
}

所以元素的显示隐藏相关的功能都是通过修改 hiddenElementIdList 数组实现的。
如果是组合的话,会显示成二级菜单
在这里插入图片描述
另外选中某个元素的时候,右侧的样式也会改变成选中元素的样式
在这里插入图片描述
右侧 Tab 栏组件是 src/views/Editor/Toolbar/index.vue

const { activeElementIdList, handleElement, toolbarState } = storeToRefs(mainStore)

我们看一下 handleElement,会显示填充色、宽高、位置、类型等属性
在这里插入图片描述

修改的时候就修改这个目标元素的属性即可。
handleElementsrc/store/main.ts 中的一个计算属性,实时计算

// 获取当前操作的元素
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
},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2274353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue进阶(贰幺贰)npm run build多环境编译

文章目录 一、前言二、实施三、总结&#xff1a;需要打包区分不同环境四、拓展阅读 一、前言 项目开发阶段&#xff0c;会涉及打包部署到多个环境应用场景&#xff0c;在不同环境中&#xff0c;需要进行项目层面的区分&#xff0c;做不同的操作&#xff0c;可以利用打包的--mo…

Elasticsearch—索引库操作(增删查改)

Elasticsearch中Index就相当于MySQL中的数据库表 Mapping映射就类似表的结构。 因此我们想要向Elasticsearch中存储数据,必须先创建Index和Mapping 1. Mapping映射属性 Mapping是对索引库中文档的约束&#xff0c;常见的Mapping属性包括&#xff1a; type&#xff1a;字段数据类…

“AI智慧组卷系统:让考试变得更简单、更公平!

大家好&#xff0c;我是一名资深的产品经理&#xff0c;今天咱们就来聊聊教育领域的一款黑科技产品——AI智慧组卷系统。在这个信息技术飞速发展的时代&#xff0c;AI技术已经渗透到了我们生活的方方面面&#xff0c;教育行业也不例外。下面我就用大白话给大家介绍一下这个AI智…

单元测试概述入门

引入 什么是测试&#xff1f;测试的阶段划分&#xff1f; 测试方法有哪些&#xff1f; 1.什么是单元测试&#xff1f; 单元测试&#xff1a;就是针对最小的功能单元&#xff08;方法&#xff09;&#xff0c;编写测试代码对其正确性进行测试。 2.为什么要引入单元测试&#x…

三、Angular 路由

一、简介 Angular 的路由服务是一个可选的服务&#xff0c;它用来呈现指定的 URL 所对应的视图。它并不是Angular 核心库的一部分&#xff0c;而是位于 angular/router 包中。像其他 Angular 包一样&#xff0c;路由服务在用户需要时才从此包中导入。 [1]. 创建路由模块 默认…

【MATLAB】绘制投资组合的有效前沿

文章目录 一、数据准备二、有效前沿三、代码3.1 数据批量读取、预处理3.2 绘制可行集3.3 绘制有效前沿3.4 其它-最大夏普率 一、数据准备 准备多个股票的的历史数据&#xff0c;目的就是找到最优的投资组合。 下载几个标普500里面的公式的股票数据吧&#xff0c;下载方法也可…

JuiceFS 2024:开源与商业并进,迈向 AI 原生时代

即将过去的 2024 年&#xff0c;是 JuiceFS 开源版本推出的第 4 年&#xff0c;企业版的第 8 个年头。回顾过去这一年&#xff0c;JuiceFS 社区版依旧保持着快速成长的势头&#xff0c;GitHub 星标突破 11.1K&#xff0c;各项使用指标增长均超过 100%&#xff0c;其中文件系统总…

重生之我在异世界学编程之C语言:枚举联合篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文枚举&#xff08;Enum&#xff0…

6 分布式限流框架

限流的作用 在API对外互联网开放的情况下&#xff0c;是无法控制调用方的行为的。当遇到请求激增或者黑客攻击的情况下&#xff0c;会导致接口占用大量的服务器资源&#xff0c;使得接口响应效率的降低或者超时&#xff0c;更或者导致服务器宕机。 限流是指对应用服务进行限制…

【Linux系列】如何使用 nohup 命令在后台运行脚本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

门禁系统与消防报警的几种联动方式

1、规范中要求的出入口系统与消防联动 1.1《建筑设计防火规范》GB 50016-2018 1.2《民用建筑电气设计规范》JGJ 16-2008  14.4出入口控制系统 3 设置在平安疏散口的出入口限制装置&#xff0c;应与火灾自动报警系统联动;在紧急状况下应自动释放出入口限制系统&…

Express 加 sqlite3 写一个简单博客

例图&#xff1a; 搭建 命令&#xff1a; 前提已装好node.js 开始创建项目结构 npm init -y package.json:{"name": "ex01","version": "1.0.0","main": "index.js","scripts": {"test": &q…

GetMaterialApp组件的功能与用法

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性3. 示例代码4. 内容总结我们在上一章回中介绍了"Get包简介"相关的内容,本章回中将介绍GetMaterialApp组件.闲话休提,让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经介绍过GetMaterialApp组…

LabVIEW之树形控件

一、树形控件基本构成 树形控件这个名称非常形象&#xff0c;其如同树一样&#xff0c;是典型的分层结构。树形控件的属性和方法使用非常灵活&#xff0c;树形控件的内容既可以静态编辑&#xff0c;也可以通过编程来动态填充。静态编辑树形控件适用于内容不变的应用场景&#…

Inno Setup制作安装包,安装给win加环境变量

加 ; 加环境变量&#xff0c;开启&#xff0c;下面一行 ChangesEnvironmentyes 和 ; 加环境变量wbrj变量名&#xff0c;{app}\project\bin变量值&#xff0c;{app}\后接文件名&#xff0c;{app}表示安装路径。下面一行,{olddata};原来的值上拼接 Root: HKLM; Subkey: “SYSTEM\…

张朝阳惊现CES展,为中国品牌 “代言”的同时,或将布局搜狐新战略!

每年年初&#xff0c;科技圈的目光都会聚焦在美国拉斯维加斯&#xff0c;因为这里将上演一场被誉为 “科技春晚” 的年度大戏 ——CES 国际消费电子展。作为全球规模最大、最具影响力的科技展会之一&#xff0c;CES 吸引了来自 160 多个国家的创新者和行业领导者&#xff0c;是…

UDS诊断之0x27服务—结合实例讲解

前言&#xff1a; 本文讲解的是比较深入一点知识&#xff0c;对于一些刚入门的同学&#xff0c;建议直接先看一遍14229规范&#xff0c;然后找一个实际项目练练手&#xff01;然后再来看本文&#xff0c;相信你会对0x27服务有更深的认知&#xff01;&#xff01;&#xff01; …

React Router 向路由组件传state参数浏览器回退历史页面显示效果问题

昨天在看尚硅谷张天禹老师讲的 React教程p90&#xff0c;老师讲到 React路由的 replace模式和push模式&#xff0c;老师的演示效果与自己本地操作不太一样。 老师的效果&#xff1a;点击查看消息1&#xff0c;消息2&#xff0c;消息3 再点回退&#xff0c;可以依次查看到 消息…

静态路由配置与调试——计算机网络实训day1

文章目录 操作前准备一、实验目的二、实验要求三、实验过程1、在R1和R2上配置设备名称。基本配置设备命名 2、在R1和R2上配置接口IP地址&#xff0c;并查看IP地址的配置情况。3、在R1和R2上配置静态路由&#xff0c;并查看路由表。静态路由缺省路由&#xff08;默认路由&#x…

【HeadFirst系列之HeadFirst设计模式】第1天之HeadFirst设计模式开胃菜

HeadFirst设计模式开胃菜 前言 从今日起&#xff0c;陆续分享《HeadFirst设计模式》的读书笔记&#xff0c;希望能够帮助大家更好的理解设计模式&#xff0c;提高自己的编程能力。 今天要分享的是【HeadFirst设计模式开胃菜】&#xff0c;主要介绍了设计模式的基本概念、设计模…