图形编辑器开发:属性显示与格式转换

大家好,我是前端西瓜哥。

今天简单讲讲图形编辑器的显示属性值时,会遇到的格式转换问题。

编辑器 github 地址:

github.com/F-star/suik...

线上体验:

blog.fstars.wang/app/suika/

单位转换

图形编辑器中的数据,通过 UI 层进行展示时,可能不会直接将数据源的原始值展示出来,而是会额外进行单位的转换,变成另一种格式

这里以简单而常见的弧度为例。

图形的旋转在数据源中,会用弧度(radian)表示。因为弧度更适合进行数学计算,且很多 API 比如 Math.sin(x) 都需要你提供弧度。

但在面向用户的 UI 层,我们通常会提供角度(degree),因为日常生活中人们更常使用,它更直观。

但数据中我们还是要保存弧度的。

转换算法

我们需要明确的点是:

  1. 数据源要用唯一格式,这样可以确保运算逻辑的一致性。比如旋转不建议即可以保存弧度,也可以保存角度。另外,尽量选择精度高的。

  2. 如果有显示另一种格式的需求,你需要实现源格式转其他格式算法。比如弧度转角度显示到用户界面上;

  3. 如果有修改其他格式然后修改源数据的需求,你需要实现其他格式转源数据的算法

ts 复制代码
/**
 * 弧度转角度
 */
export function radian2Degree(radian: number) {
  return (radian * 180) / Math.PI;
}

/**
 * 角度转弧度
 */
export function degree2Radian(degree: number) {
  return (degree * Math.PI) / 180;
}

需要注意,格式的转换通常会丢失一些精度的

这里弧度和角度的转换就是一个例子。

圆周率是一个无限不循环小数,计算的时候,会对其丢掉一些精度再参与计算,最后的结果自然也丢失了精度。

这里给一下 UI 层实现思路,以 React 组件为例,核心实现大致如下:

js 复制代码
const [radian, setRadian] = useState(0);

useEffect(() => {
  rect.onRotationChange((val) => {
    // 从编辑器内核同步过来的状态
    setRadian(val);
  })
});

<NumberInput
  label="旋转"
  value={remainDecimal(radian2Degree(radian))}
  onBlur={(e) => {
    const degree =  e.target.value;
    const radian = normalizeRadian(degree2Radian(degree));
    rect.setRotation(radian);
  }}
/>

题外话,UI 层会直接更新编辑器中的状态,成功更新后通过事件订阅通知回 UI 层,同步状态。

图形编辑器开发:模块间如何通信?

弧度还是比较简单的场景。

像是复杂一点的属性,比如颜色值,通常要实现一个比较完善的拾色器,要支持多种格式,如RGBA、HSL、CMYK 等等,要实现的方法就更复杂也更多。

降低显示精度

UI 层不会显示全精度,意义不大。

比如 x 坐标的真实值是 52.24621202458749,但用户是不希望看到这么长的值的,他只是想知道这个点大概在什么位置。

所以我们最好做一个四舍五入,比如保留有限的有效位显示为 52.25。

需要注意的是,修改属性值时不用做降低精度再转为源格式,我们的数据源精度越高越好。

只在显示时做降低精度。

检验和补正

因为涉及到用户修改属性值,所以我们需要对用户的输入值进行处理,尝试得到一个合法值去修改属性。

简单的做法是 严格校验,比如对于数字类型,出现非数字字符,就直接认为非法值。

稍微好一点的是从字符串中提取符合格式的部分

更人性化的是猜测用户想干嘛,做补全。比如对于 hex 格式的颜色值,用户只输入一个 3,我们给他补全为 33333。

这里有一个例子,是关于用户输入的 hex 颜色值的检验和修复,可以看我的这篇文章:

图形编辑器开发:颜色 hex 标准化

最后

画一张图总结一下。

展示层可能和数据源的格式不同,显示时要做格式转换,然后降低精度,比如对于数字通常保留 1 到 5 个小数位就够了。

修改非源格式要做校验和补正,然后转回数据源格式保存起来。保存成功后再把新值传递到 UI 层。

我是前端西瓜哥,欢迎关注我,学习更多图形编辑器知识。


相关阅读,

几何算法:矩形碰撞和包含检测算法

在容器内显示图片的五种方案:contain、cover、fill、none、scale-down

计算机图形学:变换矩阵

求向量的角度

相关推荐
twins352039 分钟前
解决Vue应用中遇到路由刷新后出现 404 错误
前端·javascript·vue.js
qiyi.sky1 小时前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~1 小时前
分析JS Crash(进程崩溃)
java·前端·javascript
安冬的码畜日常1 小时前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n02 小时前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。2 小时前
案例-任务清单
前端·javascript·css
zqx_73 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己3 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称4 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色4 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript