当前位置:首页 > 科技  > 软件

图形编辑器开发:自定义光标

来源: 责编: 时间:2024-01-08 09:15:11 152观看
导读大家好,我是前端西瓜哥。今天来讲讲如何在图形编辑器中使用自定义光标,并对光标其进行管理。编辑器 github 地址:https://github.com/F-star/suika线上体验:https://blog.fstars.wang/app/suika/自定义光标的意义是什么?光

cxp28资讯网——每日最新资讯28at.com

大家好,我是前端西瓜哥。cxp28资讯网——每日最新资讯28at.com

今天来讲讲如何在图形编辑器中使用自定义光标,并对光标其进行管理。cxp28资讯网——每日最新资讯28at.com

编辑器 github 地址:cxp28资讯网——每日最新资讯28at.com

https://github.com/F-star/suikacxp28资讯网——每日最新资讯28at.com

线上体验:cxp28资讯网——每日最新资讯28at.com

https://blog.fstars.wang/app/suika/cxp28资讯网——每日最新资讯28at.com

自定义光标的意义是什么?

光标(游标)在图形界面交互中是非常基础的一环。cxp28资讯网——每日最新资讯28at.com

它是一个指针,悬浮在屏幕的最上层。除了可以标记出指针的当前位置,同时也会通过它独特的样式,提示用户此时可以执行怎么的操作。cxp28资讯网——每日最新资讯28at.com

比如抓手(grab)光标,是一个展开的手掌,表示可以对目标进行拖拽操作。cxp28资讯网——每日最新资讯28at.com

缩放(xx-resize)光标,是一个有方向的单(双)箭头,表示可以往特定方向移动以改变目标大小。cxp28资讯网——每日最新资讯28at.com

长得像英文字母 I 的文字(text)光标,则提示可以进行文字的操作,细瘦的垂直线是为了更好地点中字符之间的空白区域。cxp28资讯网——每日最新资讯28at.com

点击(pointer)光标,一根手指(食指,不是中指)伸出来是要干嘛,是为了试探,看到按钮就尝试点一下,表示某个区域是可点击的。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

操作系统有丰富的光标样式可以选择,在 Web 网页中可以通过  cursor 样式属性进行设置。cxp28资讯网——每日最新资讯28at.com

对于一般应用来说,通常是够用的。但对于一个成熟的图形编辑器来说,这还远远不够。cxp28资讯网——每日最新资讯28at.com

我们还需要一些 更具体的光标样式来向用户传递信息,比如:cxp28资讯网——每日最新资讯28at.com

  • 旋转光标:表示图形可旋转。cursor 属性中没有旋转光标,勉强可用抓手工具做个平替;
  • 支持任意度数的缩放光标。cursor 属性的缩放光标只有 45 度的正数倍数光标,这精度远远不够。
  • 钢笔工具相关光标:钢笔光标、锚点光标、新增/删除点光标;

等等。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

此外,自定义光标还有一个很重要的作用,就是 实现不同平台的视觉一致性。cxp28资讯网——每日最新资讯28at.com

不同操作系统的 UI 风格是不同的,它们的光标是相当不一致的,会给用户带来不同的体验。cxp28资讯网——每日最新资讯28at.com

(我希望在 Windows 系统看到 MacOS 的光标)cxp28资讯网——每日最新资讯28at.com

如何支持自定义光标

没有光标,我们自己造。cxp28资讯网——每日最新资讯28at.com

好在 cursor 是支持自定义光标的。cxp28资讯网——每日最新资讯28at.com

具体用法如下。cxp28资讯网——每日最新资讯28at.com

.suika-cursor-default {  cursor: url(./cursor-icons/suika-cursor-default.png) 5 5, pointer;}

值依次为:cxp28资讯网——每日最新资讯28at.com

  • url(<url>):自定义光标的图片资源 url,因为不大且不希望额外作为单独资源加载,通常会选择转换为 base64 格式内嵌;
  • x y:使用相对图片左上角的像素位置作为光标位置;
  • <keyword>:如果没有指定自定义光标图片,或者加载光标资源失败,就会使用浏览器支持的光标值,比如  pointer。

我们需要绘制好光标图片,然后导出为 png(背景为透明度),然后定义好 x 和 y,再通过 css 类包裹一下,然后根据需要在 Canvas 上设置对应的 css 样式即可。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

多种旋转角度的旋转和缩放光标

有两种光标比较特殊,它们有特殊的旋转角度的参数。cxp28资讯网——每日最新资讯28at.com

它们就是旋转和缩放光标。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

因为 cursor 这个 css 属性并不支持设置旋转角度,所以我们只能绘制 0 到 359 之间度数共 360 个不同的旋转光标图片。cxp28资讯网——每日最新资讯28at.com

缩放光标因为其样式中心对称的原因,倒是不需要这么多,只要绘制 0 到 179 共 180 个图片。cxp28资讯网——每日最新资讯28at.com

然后是 精细度的问题。cxp28资讯网——每日最新资讯28at.com

你这里可以整一些猫腻,比如偷懒,抽走一些度数,只给偶数的度数,比如 2、4,奇数的度数都丢掉,没有 1、3 这些度数。设置光标的时候舍入一下,找最接近的度数。cxp28资讯网——每日最新资讯28at.com

或者你精益求精,你说间隔 1 度未免太大,我们要更精确一点,我们不仅支持整数,我们还要支持 1.5、6.5 这种中间值,我们要用 720 个图片。cxp28资讯网——每日最新资讯28at.com

没问题,都可以上。cxp28资讯网——每日最新资讯28at.com

批量生成方案

但是呢,我们发现,这些光标其实都来自一个源图片,只是旋转了不同的角度,我们手工一个个操作未免太低效了。cxp28资讯网——每日最新资讯28at.com

这时候我们就可以自己写或找一些工具,批量对一张源图形生成旋转多种角度后的图片,然后再写个脚本去自动生成 css 代码,把这些图片引入进去。cxp28资讯网——每日最新资讯28at.com

这是一个方案,figma 是这么做的。cxp28资讯网——每日最新资讯28at.com

感觉还是有亿点麻烦。没事,我们有另一个方案。cxp28资讯网——每日最新资讯28at.com

上面做的是打包前生成大量图片,那我们可不可以在运行时动态生成光标呢?cxp28资讯网——每日最新资讯28at.com

可以的。图片有位图的,也有矢量的啊,我们可以用一种叫做 SVG 的特殊图片格式,它的内容是文本,一种的 xml 文本。cxp28资讯网——每日最新资讯28at.com

我们可以将光标 UI 导出为 SVG,然后在最顶层的元素加上 transform 的旋转变换。cxp28资讯网——每日最新资讯28at.com

可以写一个方法,传入角度和位置信息,动态生成对应的 SVG 字符串,然后转成 DataURL 给 cursor 应用上。cxp28资讯网——每日最新资讯28at.com

大概像这样:cxp28资讯网——每日最新资讯28at.com

const getRotationIconDataUrl = (degree, x = 0, y = 0) => {  return `url("data:image/svg+xml,   ...   <g fill='none' transform='rotate(${degree} ${x} ${y})'   ...  ") ${x} ${y}, pointer`}canvas.style.cursor = getRotationIconDataUrl(114.544);

开源白板工具 tldraw 选择了这个方案。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

你可以给一个精度很高的旋转度数。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

模块设计

代码设计上,我们会设计一个 CursorManager 类进行光标的管理。cxp28资讯网——每日最新资讯28at.com

这个类最重要的作用就是设置光标值。cxp28资讯网——每日最新资讯28at.com

setCursor 方法接收一个光标值,除了支持传统的字符串,也支持 { type: 'rotation'; degree: 45 } 这种形式。cxp28资讯网——每日最新资讯28at.com

它主要做了如下操作:cxp28资讯网——每日最新资讯28at.com

  • 标准化光标值,比如把度数取余到 0~360 内。
  • 比较新旧光标值,相同就跳过。
  • 清空原来设置的光标样式。
  • 根据光标不同,执行各自的逻辑。

下面是核心代码实现。cxp28资讯网——每日最新资讯28at.com

// 支持的光标类型export type ICursor =  | 'default'  | { type: 'resize'; degree: number }  | { type: 'rotation'; degree: number }  | 'grab' | ...}class CursorManager {  private cursor: ICursor;  setCursor(cursor: ICursor) {    // 1. 标准化光标值,比如把度数取余到 0~360 内    cursor = this.normalizeCursor(cursor);    // 2. 比较新旧光标值,相同就跳过    if (isEqual(cursor, this.cursor)) {      return;    }    this.cursor = cursor;        const clsPrefix = 'suika-cursor-';    // 3. 清空原来设置的光标样式    canvasElement.classList.forEach((className) => {      if (className.startsWith(clsPrefix) {        canvasElement.classList.remove(className);      }    });    this.editor.canvasElement.style.cursor = '';        // 4. 根据光标不同,执行各自的逻辑    if (this.customClassCursor.has(cursor)) {      // 这个是注册了 class 的光标      const className = `${clsPrefix}${cursor}`;      this.editor.canvasElement.classList.add(className);    } else if (typeof cursor == 'string') {      // 用浏览器自带的      this.editor.canvasElement.style.cursor = cursor;    } else if (cursor.type === 'resize') {      // 后面都是使用动态 svg 字符串      this.setResizeCursorInCanvas(cursor.degree);    } else if (cursor.type === 'rotation') {      this.setRotationCursorInCanvas(cursor.degree);    }  }}

绘制在画布上的光标

光标还有一种比较少用的方案,也说说吧。cxp28资讯网——每日最新资讯28at.com

就是有些光标是绘制在画布上的。cxp28资讯网——每日最新资讯28at.com

一个经典的例子就是 AutoCAD 的十字光标,这个十字的长度是可以设置的,可以相当长。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

如果你修改操作系统的光标,那这个十字便会突破天际地显示到非绘制区域上。cxp28资讯网——每日最新资讯28at.com

此外,AutoCAD 的光标并不忠实跟随操作系统光标,比如有时候会吸附于某点不动,并基于它的位置显示下拉菜单,此时可以用真正的光标去点选。cxp28资讯网——每日最新资讯28at.com

cxp28资讯网——每日最新资讯28at.com

考虑到性能,建议把光标放到另一个 canvas 上,和图形放一个 canvas 会让画布中没做任何操作的图形频繁重绘。cxp28资讯网——每日最新资讯28at.com

结尾

总结一下。cxp28资讯网——每日最新资讯28at.com

关于图形编辑器的光标,我们有以下方案:cxp28资讯网——每日最新资讯28at.com

  • 使用浏览器本身就提供的一些光标值。优点是成本低,缺点是样式有限,且不同操作系统风格差异大;
  • cursor 支持自定义光标,所以我们可以自己设置自己的一套光标去应用。但其中有一些比较特殊的有各种旋转方向的光标,需要做特别的处理。一种是用工具批量生产光标图片,一种是利用 svg 在运行时动态生成;
  • 最后是在画布上渲染光标的方案,适合一些有特殊需求的图形编辑器。这类图形编辑器的光标往往可以自定义,且可以非常大,或是它们在某些场景下会脱离鼠标的控制,喜欢特立独行,比如突然吸附到某个吸附点上。缺点是实现比较复杂,你可能需要像管理图形一样去管理它。

本文链接:http://www.28at.com/showinfo-26-57869-0.html图形编辑器开发:自定义光标

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 盘一盘这个没资格出现在面试环节的场景题

下一篇: @Configuration注解天天用,你真的了解它吗?

标签:
  • 热门焦点
  • 鸿蒙OS 4.0公测机型公布:甚至连nova6都支持

    鸿蒙OS 4.0公测机型公布:甚至连nova6都支持

    华为全新的HarmonyOS 4.0操作系统将于今天下午正式登场,官方在发布会之前也已经正式给出了可升级的机型产品,这意味着这些机型会率先支持升级享用。这次的HarmonyOS 4.0支持
  • 容量越大越不坏?24万块硬盘故障率报告公布 这些产品零故障

    容量越大越不坏?24万块硬盘故障率报告公布 这些产品零故障

    8月5日消息,云存储服务商Backblaze发布了最新的硬盘故障率报告,年故障率有所上升。Backblaze发布的硬盘季度统计数据,其中包括故障率等重要方面。这些结
  • 得物效率前端微应用推进过程与思考

    得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • 共享单车的故事讲到哪了?

    共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 新电商三兄弟,“抖快红”成团!

    新电商三兄弟,“抖快红”成团!

    来源:价值研究所作 者:Hernanderz 随着内容电商的概念兴起,抖音、快手、小红书组成的&ldquo;新电商三兄弟&rdquo;成为业内一股不可忽视的势力,给阿里、京东、拼多多带去了巨大压
  • 年轻人的“职场羞耻感”,无处不在

    年轻人的“职场羞耻感”,无处不在

    作者:冯晓亭 陶 淘 李 欣 张 琳 马舒叶来源:燃次元&ldquo;人在职场,应该选择什么样的着装?&rdquo;近日,在网络上,一个与着装相关的帖子引发关注,在该帖子里,一位在高级写字楼亚洲金
  • 华为将推出盘古数字人大模型 可帮助用户12小时完成数字人生成

    华为将推出盘古数字人大模型 可帮助用户12小时完成数字人生成

    在今日举行的2023年华为云数字文娱AI创新峰会上,华为云全球Marketing与销售服务总裁石冀琳表示,华为云将在后续推出盘古数字人大模型,可帮助用户12小
  • DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    10月30日,据韩国媒体消息,自今年年初以来一直在上涨的 DRAM 存储器的交易价格仅在本月就下跌了近 10%,此次是全年首次降价,而NAND 闪存本月价格与上月持平。市
  • “买真退假” 这种“羊毛”不能薅

    “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top