大家好,动功我是实现前端西瓜哥。这次来讲解图形编辑器排列(arrange)功能的图形实现。
先看效果。编辑
有四种移动方式:
需要注意保持被移动图形,图形要保持它们原来的编辑相对顺序。
编辑器 github 地址:
https://github.com/F-star/suika
线上体验:
https://blog.fstars.wang/app/suika/
置顶,是将图形放在最顶部的位置。
假设图形树对应的一个数组 graphs,需要被移动的元素集合为 movedGraphSet(Set 类型)。要做的是将这些元素移动到数组末尾。
图形是按照数组的顺序绘制的,后面绘制的会盖住前面的图形,所以是移动到末尾而不是开头。这点需要注意。
我们只需要递归 graphs,不在 movedGraphSet 中的元素搬到新的数组中,在 movedGraphSet 中的元素,放到 tailGraphs 数组中。
const front = (graphs: Graph[], movedGraphSet: Set<Graph>) => {
const newGraphs: Graph[] = [];
const tailGraphs: Graph[] = [];
for (let i = 0; i < graphs.length; i++) {
const graph = graphs[i];
if (movedGraphSet.has(graph)) {
tailGraphs.push(graph);
} else {
newGraphs.push(graph);
}
}
newGraphs.push(...tailGraphs);
return newGraphs;
};
图形树可能会是链表,或者有 group 的概念,实现代码或许不同,但思路是一样的。
置底同理。
这次是从右往左遍历。另外因为要减少数组搬移的操作,我们需要额外将数组做一个倒序。
往数组的头部插入新元素,是要将原来的整个数组往后移动一格的,时间复杂度是 O(n),往末尾加则不需要。
const back = (graphs: Graph[], movedGraphSet: Set<Graph>) => {
const newGraphs: Graph[] = [];
const tailGraphs: Graph[] = [];
for (let i = graphs.length - 1; i >= 0; i--) {
const graph = graphs[i];
if (movedGraphSet.has(graph)) {
tailGraphs.push(graph);
} else {
newGraphs.push(graph);
}
}
newGraphs.push(...tailGraphs);
return newGraphs.reverse(); // 反向
};
将存在于 movedGraphSet 的图形都往后移动一个位置。需要注意多个需要移动的图形如果紧邻,是要将它们作为一个整体放到它们之后的第一个不移动图形的后面的。
比如被操作数组为 [0, 1, 2, 3, 4, 5, 6, 7],指定数组元素为 [1, 2, 6],返回 [0, 3, 1, 2, 4, 5, 7, 6]。
一开始我想的从左往右遍历,用多个指针记录连续需要移动的图形的,然后发现实现上也太复杂了吧。要维护指针,还要判断指针什么时候应该移动什么的。
后面我换了个思路,改为从右往左遍历。如果当前元素是需搬移元素,就和下一个元素交换。
这样,一个不用搬移的元素就能往前挤过被搬运元素的集群。
const forward = (graphs: Graph[], movedGraphs: Set<Graph>) => {
const newGraphs = [...graphs];
for (let i = newGraphs.length - 2; i >= 0; i--) {
if (movedGraphs.has(newGraphs[i])) {
// 交换
[newGraphs[i], newGraphs[i + 1]] = [newGraphs[i + 1], newGraphs[i]];
}
}
return newGraphs;
};
同理。
换个方向。
const backward = (graphs: Graph[], movedGraphs: Set<Graph>) => {责任编辑:姜华 来源: 前端西瓜哥 图形编辑器排列移动功能
const newGraphs = [...graphs];
for (let i = 1; i < newGraphs.length; i++) {
if (movedGraphs.has(newGraphs[i])) {
[newGraphs[i], newGraphs[i - 1]] = [newGraphs[i - 1], newGraphs[i]];
}
}
return newGraphs;
};
(责任编辑:知识)
爆料任天堂新机Switch 2或将涨价 售价399.99美元!
国内首款抑郁症诊断机器人亮相达沃斯夏季论坛展台 采用脑机接口技术
波音公司与美军合作研发极超音速太空飞船,可十天内完成十次飞行任务
寰亚传媒(08075.HK)中期亏损收窄至1916万港元 每股亏损4.58港仙