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

【PPTist】网格线、对齐线、标尺

前言:本篇文章介绍辅助我们摆放元素位置的几个功能

一、网格线功能

网格线主要是用来辅助我们对齐元素的,右键可以选择使用哪种网格线,以及关闭和打开
在这里插入图片描述
显示效果就是图中的这种效果。但是强迫症有点难受,它底部没对齐啊啊啊
在这里插入图片描述
不行,我要把它改成对齐的!
猜测目前的网格线设置的是固定值。
然后咱们先全局搜索一下“网格线”,发现了这里的定义
src/store/main.ts

gridLineSize: number  // 网格线尺寸(0表示不显示网格线)

网格线这个组件是 src/views/Editor/Canvas/GridLines.vue,其中就两个方法,一个计算网格线颜色的,避免网格线颜色和底色太接近看不清;另一个是计算网格路径的。网格线使用过 path 标签渲染出来的,我们来看一下网格路径的计算方法

const { canvasScale, gridLineSize } = storeToRefs(useMainStore())
// 网格路径
const path = computed(() => {const maxX = VIEWPORT_SIZEconst maxY = VIEWPORT_SIZE * viewportRatio.valuelet p = ''for (let i = 0; i <= Math.floor(maxY / gridLineSize.value); i++) {p += `M0 ${i * gridLineSize.value} L${maxX} ${i * gridLineSize.value} `}for (let i = 0; i <= Math.floor(maxX / gridLineSize.value); i++) {p += `M${i * gridLineSize.value} 0 L${i * gridLineSize.value} ${maxY} `}return p
})

以及页面中的这个网格线组件:
在这里插入图片描述
可以看到里面的线条数据,只有一个不是整数,所以 562.5 应该就是最后一行的纵坐标,不过最后一行应该也是50的倍数,所以应该是下边框上还有一条线
话说好像不能让底部对齐,因为网格得是正方形,好吧,那我还是忍忍吧。
然后还有一个相关的组件 src/views/Editor/Canvas/index.vue,里面有右键菜单。可以看到,设置网格线尺寸的方法是 mainStore.setGridLineSize(50)
这个方法在 src/store/main.ts

setGridLineSize(size: number) {this.gridLineSize = size
},

二、对齐线

对齐线就是这个
在这里插入图片描述

对齐线的定义在这里 src/views/Editor/Canvas/AlignmentLine.vue
控制对齐线的显示的属性有四个:
type: 'vertical' | 'horizontal' 控制方向
lefttop 控制位置
sizeStyle ,如果是竖向就有 height 值,如果是横向就有 width 值表示长度。

然后我们来看一下这个组件的父组件在哪里,以及是怎么从父组件获取 props
是在 src/views/Editor/Canvas/index.vue 文件中
其中的 .viewport-wrapper 是覆盖整个编辑区域的框框
在这里插入图片描述
其中的对齐线是通过 v-for 渲染的数组

<AlignmentLine v-for="(line, index) in alignmentLines" :key="index" :type="line.type" :axis="line.axis" :length="line.length":canvasScale="canvasScale"
/>

数据 alignmentLines 的修改依赖于两个方法

const { dragElement } = useDragElement(elementList, alignmentLines, canvasScale)
const { scaleElement, scaleMultiElement } = useScaleElement(elementList, alignmentLines, canvasScale)

看方法名就是拖拽和缩放元素的时候会更新
这个写法比较少见,没有通过一个方法返回 alignmentLines 更新后的值,而是在方法里面直接修改了 alignmentLines
然后我们会发现代码的组织性真的很好,这些钩子函数在另外的文件中维护,并且方法名很明确。

总而言之言而总之,这个方法好复杂,各种计算的。
简单看一下数据。
在这里插入图片描述
还有多条的情况
在这里插入图片描述

三、标尺

标尺就是这个
在这里插入图片描述
主要跟缩放行为有关,中间顶部 500 的位置和左侧 300 的位置是固定的。

在这里插入图片描述

还有如果选中一个元素的话,标尺的对应坐标会高亮
在这里插入图片描述

它的父组件跟上面的对齐线的父组件是同一个
src/views/Editor/Canvas/index.vue

<Ruler :viewportStyles="viewportStyles" :elementList="elementList" v-if="showRuler" />

showRuler 通过右键菜单控制标尺的开关。

const { dragViewport, viewportStyles } = useViewportSize(canvasRef)
const elementList = ref<PPTElement[]>([])
const setLocalElementList = () => {elementList.value = currentSlide.value ? JSON.parse(JSON.stringify(currentSlide.value.elements)) : []
}
watchEffect(setLocalElementList)
// 开关标尺
const toggleRuler = () => {mainStore.setRulerState(!showRuler.value)
}

标尺组件在这里 src/views/Editor/Canvas/Ruler.vue
根元素下有两个元素,一个是 .h,表示顶部的标尺; 一个是 .v,表示左侧的标尺
先看下动态添加的类名是啥意思:class="{ 'hide': markerSize < 36, 'omit': markerSize < 72 }"

const markerSize = computed(() => {return props.viewportStyles.width * canvasScale.value / 10
})

就是缩放值小于72的时候,中间的这个小齿齿会隐藏
在这里插入图片描述
缩放值小于 36 的时候,数字会隐藏
在这里插入图片描述
其中的高亮是这个元素

<div class="range" v-if="elementListRange":style="{left: elementListRange.minX * canvasScale + 'px',width: (elementListRange.maxX - elementListRange.minX) * canvasScale + 'px',}"
></div>
const { canvasScale, activeElementIdList } = storeToRefs(useMainStore())
watchEffect(() => {const els = props.elementList.filter(el => activeElementIdList.value.includes(el.id))if (!els.length) return elementListRange.value = nullelementListRange.value = getElementListRange(els)
})

activeElementIdList 是公用的数据,通过 src/store/main.ts 中的下面的方法修改

// 设置选中元素列表
setActiveElementIdList(activeElementIdList: string[]) {if (activeElementIdList.length === 1) this.handleElementId = activeElementIdList[0]else this.handleElementId = ''this.activeElementIdList = activeElementIdList
},

然后各种地方都可能会用到,包括组合元素、鼠标选中、切换页面(清空)等等。

计算元素的范围 getElementListRange 也是一个公用的方法,在这个文件中 src/utils/element.ts,大致就是找选中的元素的所有的位置,取最边缘的位置,作为包含所有的选中元素的范围。

相关文章:

【PPTist】网格线、对齐线、标尺

前言&#xff1a;本篇文章介绍辅助我们摆放元素位置的几个功能 一、网格线功能 网格线主要是用来辅助我们对齐元素的&#xff0c;右键可以选择使用哪种网格线&#xff0c;以及关闭和打开 显示效果就是图中的这种效果。但是强迫症有点难受&#xff0c;它底部没对齐啊啊啊 不…...

Leetcode3218. 切蛋糕的最小总开销 I

题目描述&#xff1a; 有一个 m x n 大小的矩形蛋糕&#xff0c;需要切成 1 x 1 的小块。 给你整数 m &#xff0c;n 和两个数组&#xff1a; horizontalCut 的大小为 m - 1 &#xff0c;其中 horizontalCut[i] 表示沿着水平线 i 切蛋糕的开销。verticalCut 的大小为 n - 1 …...

ECCV-2024 | 指令不够用、大模型来生成!BEVInstructor:基于BEV感知和大模型的视觉语言导航指令生成

作者&#xff1a;Sheng Fan, Rui Liu, Wenguan Wang, and Yi Yang 单位&#xff1a;浙江大学 原文链接&#xff1a;Navigation Instruction Generation with BEV Perception and Large Language Models &#xff08;https://link.springer.com/chapter/10.1007/978-3-031-726…...

【UE5.3.2 】引擎中安装RiderLink插件

Rider会提示你安装这个插件选择在引擎中安装 Running AutomationTool... Using bundled DotNet SDK version: 6.0.302 Starting AutomationTool... Parsing command line: BuildPlugin -Unversioned -Plugin=C:\Users\zhangbin\AppData\Local\...

【HarmonyOS 5.0】第十二篇-ArkUI公共属性(一)

一、公共样式类属性 ArkUI框架提供的基础组件直接或者间接的继承自 CommonMethod &#xff0c; CommonMethod 中定义的属性样式属于公共样式。下面就来学习这些样式 1.1.尺寸设置 宽高设置 设置组件的宽高&#xff0c;缺省时使用组件自身内容的宽高&#xff0c;比如充满父布…...

京准电钟解读,NTP网络授时服务器如何提升DCS系统效率

京准电钟解读&#xff0c;NTP网络授时服务器如何提升DCS系统效率 京准电钟解读&#xff0c;NTP网络授时服务器如何提升DCS系统效率 NTP 网络授时服务器为防火墙内的网络设备、终端、服务器提供准确、可靠和安全的高精度卫星时间参考&#xff0c;可为它支持数万台支持标准的网…...

4.银河麒麟V10(ARM) 离线安装 MySQL

1. 系统版本 [rootga-sit-cssjgj-db-01u ~]# nkvers ############## Kylin Linux Version ################# Release: Kylin Linux Advanced Server release V10 (Lance)Kernel: 4.19.90-52.39.v2207.ky10.aarch64Build: Kylin Linux Advanced Server release V10 (SP3) /(La…...

Redis四种模式在Spring Boot框架下的配置

1. 单机模式 application.properties 配置&#xff1a; spring.redis.host127.0.0.1 spring.redis.port6379 spring.redis.passwordyourpasswordspring.redis.host: 该配置指定 Redis 服务器的主机地址。在单机模式下&#xff0c;通常是本地 Redis 实例&#xff08;127.0.0.1…...

Golang的性能监控指标

Golang的性能监控指标 一、介绍 是一种高性能的编程语言&#xff0c;因其并发模型和内建的性能监控工具而备受开发者青睐。在实际开发中&#xff0c;我们需要了解一些重要的性能监控指标&#xff0c;以便及时发现和解决性能问题。本文将介绍Golang中常用的性能监控指标&#xf…...

基于GAN和DenseNett组合的调制信号分类网络(源码)

(需要源码请私信或评论) 生成对抗网络(GAN)原理 生成对抗网络(GAN)是一种革命性的深度学习模型,在无监督学习领域取得了显著进展。其核心思想基于 二人零和博弈 ,通过生成模型和判别模型的相互竞争实现高质量的数据合成。GAN由Ian Goodfellow等人于2014年首次提出,随后在图…...

uniapp 项目基础搭建(vue2)

一 .创建项目 创建项目可以通过工具创建&#xff0c;也可以通过脚手架下载 1.通过工具创建 2.通过脚手架下载 安装脚手架 ​​npm install -g vue/cli 下载项目模板 vue create -p dcloudio/uni-preset-vue 项目名称 二. 下载相关依赖 1. 项目默认是没有package.json文件的&…...

中关村科金外呼机器人智能沟通破解营销难题

当今&#xff0c;传统的营销方式在效率、成本控制、客户管理等方面逐渐显现出局限性&#xff0c;难以满足现代企业的需求。如何提升营销效率、降低运营成本、有效管理客户会员&#xff0c;成为企业的难题。中关村科金外呼机器人通过智能化沟通技术&#xff0c;为企业提供了一站…...

【Linux】处理用户输入

一、基本介绍 1、如何传递参数 向shell脚本传递数据的最基本方法就是通过命令行参数。如下&#xff0c;这条命令会向test.sh脚本传递10和20这两个参数。 ./test.sh 10 20 2、如何读取参数 bash shell会将所有的命令行参数都指派给称作位置参数&#xff08;positional parame…...

flask后端开发(1):第一个Flask项目

目录 一、Helloworddebug、host、port的配置 gitcode地址&#xff1a; https://gitcode.com/qq_43920838/flask_project.git 一、Helloword 一般是会创建两个文件夹和app.py app.py from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello…...

Highcharts 饼图:数据可视化利器

Highcharts 饼图&#xff1a;数据可视化利器 引言 在数据可视化的领域中&#xff0c;饼图作为一种经典且直观的图表类型&#xff0c;被广泛应用于各种行业和场景中。Highcharts&#xff0c;作为一个功能强大且易于使用的JavaScript图表库&#xff0c;为我们提供了创建交互式和…...

黑马商城项目—服务注册、服务发现

服务注册 我们把item-service注册到Nacos&#xff0c;步骤如下&#xff1a; 1.引入依赖 在item-service的pom.xml中添加依赖&#xff1a; 2.配置Nacos 在item-service的application.yml中添加nacos地址配置: 3.配置服务实例 为了测试一个服务多个实例的情况&#xff0c;我…...

【ES6复习笔记】Map(14)

概念 Map 是 JavaScript 中的一种数据结构&#xff0c;它允许你存储键值对&#xff0c;并且可以通过键来访问对应的值。在本教程中&#xff0c;我们将学习如何声明、添加、删除、获取和遍历 Map 集合。 ES6 提供了 Map 数据结构。它类似于对象&#xff0c;也是键值对的集合。…...

15-makefile

一、Makefile的概述 1.认识make make 是一个命令&#xff0c;是个可执行程序&#xff0c;用来解析 Makefile 文件的命令&#xff1b;linux 环境下&#xff0c;这个命令存放在 /usr/bin/ 目录下&#xff1b;当用户输入 make 指令时&#xff0c;系统会自动寻找 makefile、Makef…...

yii2 手动添加 phpoffice\phpexcel

1.下载地址&#xff1a;https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 在yii项目的vendor目录下创建一个文件夹命名为phpoffice 把phpexcel目录放到phpoffic文件夹下 查看vendor\phpoffice\phpexcel目录下会看到这些文件 3.到vendor\composer目录下…...

使用 AI 辅助开发一个开源 IP 信息查询工具:一

本文将分享如何借助当下流行的 AI 工具,一步步完成一个开源项目的开发。 写在前面 在写代码时&#xff0c;总是会遇到一些有趣的机缘巧合。前几天&#xff0c;我在翻看自己之前的开源项目时&#xff0c;又看到了 DDNS 相关的讨论。虽然在 2021 年我写过两篇相对详细的教程&am…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...

LeetCode第244题_最短单词距离II

LeetCode第244题&#xff1a;最短单词距离II 问题描述 设计一个类&#xff0c;接收一个单词数组 wordsDict&#xff0c;并实现一个方法&#xff0c;该方法能够计算两个不同单词在该数组中出现位置的最短距离。 你需要实现一个 WordDistance 类: WordDistance(String[] word…...