import { SGraphItem } from "./SGraphItem"; import { SObject } from "@saga-web/base/lib"; import { SGraphLayoutType } from "./enums/SGraphLayoutType"; /** * 基本选择器 * * @author 郝建龙 */ export class SGraphSelectContainer extends SObject { /** 选择对象list */ private itemList: SGraphItem[] = []; /** 统计选中item的数量 */ get count(): number { return this.itemList.length; } /** * 构造体 * */ constructor() { super(); } // Constructor /** * 添加item到list * * @param item 当前选中的item * */ addItem(item: SGraphItem): void { for (let i = 0; i < this.itemList.length; i++) { if (this.itemList[i] == item) { return; } } item.selected = true; this.itemList.push(item); this.$emit("listChange", this.itemList); } // Function addItem() /** * 清空再添加(事件+复制数组) * * @param item 当前选中的item * */ setItem(item: SGraphItem): void { this.itemList.forEach((t: SGraphItem): void => { t.selected = false; }); this.itemList.length = 0; item.selected = true; this.itemList.push(item); this.$emit("listChange", this.itemList); } // Function setItem() /** * 清空选择对象 * * */ clear(): void { this.itemList.forEach((t: SGraphItem): void => { t.selected = false; }); this.itemList.length = 0; this.$emit("listChange", this.itemList); } // Function clear() /** * 切换选择对象 * * @param item 当前选中的item * */ toggleItem(item: SGraphItem): void { for (let i = 0; i < this.itemList.length; i++) { if (this.itemList[i] == item) { this.itemList[i].selected = false; this.itemList.splice(i, 1); this.$emit("listChange", this.itemList); return; } } // 多选时,父级item需要一致 if (this.itemList.length) { if (item.parent != this.itemList[0].parent) { return; } } item.selected = true; this.itemList.push(item); this.$emit("listChange", this.itemList); } // Function toggleItem() /** * 对齐 * * @param type 对齐方式 * */ layout(type: SGraphLayoutType): void { if (this.itemList.length < 2) { return; } switch (type) { case SGraphLayoutType.Left: this.alignLeft(); break; case SGraphLayoutType.Bottom: this.alignBottom(); break; case SGraphLayoutType.Center: this.alignCenter(); break; case SGraphLayoutType.Horizontal: this.alignHorizontal(); break; case SGraphLayoutType.Middle: this.alignMiddle(); break; case SGraphLayoutType.Right: this.alignRight(); break; case SGraphLayoutType.Top: this.alignTop(); break; case SGraphLayoutType.Vertical: this.alignVertical(); break; default: console.log("对齐类型不存在"); break; } } // Function layout() /** * 左对齐 * * */ private alignLeft(): void { let standardItem = this.itemList[0]; // 计算第一个外接矩阵左上角坐标在场景中的坐标 let p = standardItem.mapToScene( standardItem.boundingRect().x, standardItem.boundingRect().y ); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { // 将p转换为当前item中的坐标 let p1 = curItem.mapFromScene(p.x, p.y); // 根据等式差值相等 newboundx - oldboundx = newposx - oldposx => newposx = newboundx - oldboundx + oldposx curItem.x = p1.x - curItem.boundingRect().x + curItem.x; } } } // Function alignLeft() /** * 顶对齐 * * */ private alignTop(): void { let standardItem = this.itemList[0]; let p = standardItem.mapToScene( standardItem.boundingRect().x, standardItem.boundingRect().y ); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { let p1 = curItem.mapFromScene(p.x, p.y); curItem.y = p1.y - curItem.boundingRect().y + curItem.y; } } } // Function alignTop() /** * 右对齐 * * */ private alignRight(): void { let standardItem = this.itemList[0]; let p = standardItem.mapToScene( standardItem.boundingRect().right, standardItem.boundingRect().bottom ); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { let p1 = curItem.mapFromScene(p.x, p.y); curItem.x = p1.x - curItem.boundingRect().right + curItem.x; } } } // Function alignRight() /** * 底对齐 * * */ private alignBottom(): void { let standardItem = this.itemList[0]; let p = standardItem.mapToScene( standardItem.boundingRect().right, standardItem.boundingRect().bottom ); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { let p1 = curItem.mapFromScene(p.x, p.y); curItem.y = p1.y - curItem.boundingRect().bottom + curItem.y; } } } // Function alignBottom() /** * 水平居中对齐 * * */ private alignCenter(): void { // 第一个选中的item即为基准对象 let standardItem = this.itemList[0]; // 基准对象的中心点 let center = standardItem.boundingRect().center(); // 中心点转换为场景坐标 let p = standardItem.mapToScene(center.x, center.y); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { let p1 = curItem.mapFromScene(p.x, p.y); // 根据等式差值相等 newcenterx - oldcenterx = newposx - oldposx => newposx = newcenterx - oldcenterx + oldposx curItem.x = p1.x - curItem.boundingRect().center().x + curItem.x; } } } // Function alignCenter() /** * 垂直居中对齐 * * */ private alignMiddle(): void { // 第一个选中的item即为基准对象 let standardItem = this.itemList[0]; // 基准对象的中心点 let center = standardItem.boundingRect().center(); // 中心点转换为场景坐标 let p = standardItem.mapToScene(center.x, center.y); for (let i = 1; i < this.itemList.length; i++) { let curItem = this.itemList[i]; if (curItem.moveable) { let p1 = curItem.mapFromScene(p.x, p.y); curItem.y = p1.y - curItem.boundingRect().center().y + curItem.y; } } } // Function alignMiddle() /** * 垂直分布 * * */ private alignVertical(): void { if (this.itemList.length < 3) { return; } for (let i = 0; i < this.itemList.length - 1; i++) { for (let j = 0; j < this.itemList.length - 1 - i; j++) { let curItemCenter = this.itemList[j].boundingRect().center(); let nextItemCenter = this.itemList[j + 1] .boundingRect() .center(); let curCenterY = this.itemList[j].mapToScene( curItemCenter.x, curItemCenter.y ).y; let nextCenterY = this.itemList[j + 1].mapToScene( nextItemCenter.x, nextItemCenter.y ).y; if (curCenterY > nextCenterY) { let temp = this.itemList[j]; this.itemList[j] = this.itemList[j + 1]; this.itemList[j + 1] = temp; } } } let top = this.itemList[0]; let bottom = this.itemList[this.itemList.length - 1]; let topCenter = top.boundingRect().center(); let bottomCenter = bottom.boundingRect().center(); let leftToRight = bottom.mapToScene(bottomCenter.x, bottomCenter.y).y - top.mapToScene(topCenter.x, topCenter.y).y; let average = leftToRight / (this.itemList.length - 1); for (let k = 1; k < this.itemList.length - 1; k++) { let curItem = this.itemList[k]; if (curItem.moveable) { let p1 = top.mapToScene( top.boundingRect().center().x, top.boundingRect().center().y ); let p2 = curItem.mapFromScene(p1.x, p1.y + average * k); curItem.y = p2.y - curItem.boundingRect().center().y + curItem.y; } } } // Function alignVertical() /** * 水平分布 * * */ private alignHorizontal(): void { if (this.itemList.length < 3) { return; } for (let i = 0; i < this.itemList.length - 1; i++) { for (let j = 0; j < this.itemList.length - 1 - i; j++) { let curItemCenter = this.itemList[j].boundingRect().center(); let nextItemCenter = this.itemList[j + 1] .boundingRect() .center(); let curCenterX = this.itemList[j].mapToScene( curItemCenter.x, curItemCenter.y ).x; let nextCenterX = this.itemList[j + 1].mapToScene( nextItemCenter.x, nextItemCenter.y ).x; if (curCenterX > nextCenterX) { let temp = this.itemList[j]; this.itemList[j] = this.itemList[j + 1]; this.itemList[j + 1] = temp; } } } let left = this.itemList[0]; let right = this.itemList[this.itemList.length - 1]; let leftCenter = left.boundingRect().center(); let rightCenter = right.boundingRect().center(); let leftToRight = right.mapToScene(rightCenter.x, rightCenter.y).x - left.mapToScene(leftCenter.x, leftCenter.y).x; let average = leftToRight / (this.itemList.length - 1); for (let k = 1; k < this.itemList.length - 1; k++) { let curItem = this.itemList[k]; if (curItem.moveable) { let p1 = left.mapToScene( left.boundingRect().center().x, left.boundingRect().center().y ); let p2 = curItem.mapFromScene(p1.x + average * k, p1.y); // 根据等式 newposx - oldposx = newcenterx - oldcenterx curItem.x = p2.x - curItem.boundingRect().center().x + curItem.x; } } } // Function alignHorizontal() } // Class SGraphSelectContainer