js拖拽多个元素,选中多个元素后,水平分布功能?
现在已经实现了其他的对齐功能,就水平分布和垂直分布还未实现。搞了一天了,请教下大家应该怎么做呢?
能提供一下算法思路吗?有点不理解这里的算法是怎么实现的,好纠结。
中部是一个可自由拖拽的画布,选中多个的时候通过left计算每个元素的定位,其他对齐方式都已实现。
setPostion({ setPostion, postion }) {
let activeData = [];
// 获取当前选中得元素得数据
this.contain.nav.forEach(n => {
const status = this.contain.active.includes(n.index);
if (status) activeData.push(n);
});
// 在选中元素中获取各个最大最小数据
const { w, h, l, t, r } = await this.findMaxMinWH(activeData);
const minLeftWidth = activeData.find(n => n.left == l.min).component
.width;
const maxLeftWidth = activeData.find(n => n.left == l.max).component
.width;
const minTopHeight = activeData.find(n => n.top == t.min).component
.height;
// 去除最小left和最大left值得元素
let otherActive = activeData.filter(
n => n.left != l.min && n.left != l.max
);
// 循环选中,通过设置left和top定位对齐元素
activeData.forEach(n => {
let data = this.deepClone(n);
const width = data.component.width;
const height = data.component.height;
if (postion === "right") {
if (data.left + width !== r.max) data[setPostion] = r.max - width;
} else if (postion === "left") {
data.left = l.min;
} else if (postion === "center") {
data[setPostion] =
width < w.max ? (w.max - width) / 2 + l.min : l.min;
} else if (postion === "top") {
data.top = t.min;
} else if (postion === "bottom") {
if (data.top + height !== h.max && h.max - height != 0)
data[setPostion] = h.max - height;
else if (h.max - height == 0) data[setPostion] = h.max;
} else if (postion === "middle") {
data[setPostion] =
height < h.max ? (h.max - height) / 2 + t.min : t.min;
} else if (postion === "horizontal") {
// 排除最大和最小left值的元素,保持不动,去设置其他元素的left位置
if (n.left !== l.min && n.left !== l.max) {
// 找到当前最小left的元素的宽度
const m = l.min + minLeftWidth;
if (otherActive.length == 1) {
data[setPostion] = (l.max - m - width) / 2 + m;
} else {
const targetWidth = l.max - l.min + maxLeftWidth; //盒子宽度
const num = activeData.length;
const totalWidth = activeData.reduce(
(sum, item) => sum + item.component.width,
0
);
const gap = Math.floor((targetWidth - totalWidth) / (num - 1)); //盒子之间缝隙,
activeData.reduce(
(sum, item) => sum + item.component.width + gap,
0
);
data[setPostion] = data.left + gap;
console.log(activeData, gap, "activeData");
}
}
} else if (postion === "vertical") {
if (n.top !== t.min && n.top !== t.max) {
// 找到当前最小left的元素的宽度
const m = t.min + minTopHeight;
if (otherActive.length == 1) {
data[setPostion] = (t.max - m - height) / 2 + m;
} else {
// let h = (l.max + minLeftWidth - l.min) / 2;
// console.log(h, "hhhhhhhhhhhhhhhhhh");
// let offsetLeft = data.left - h - width;
// data[setPostion] = data.left + offsetLeft;
}
}
}
const idx = this.contain.nav.findIndex(e => e.index === n.index);
// 源数据操作
this.contain.nav.splice(idx, 1);
this.$nextTick(_ => {
this.contain.nav.push(data);
this.$forceUpdate();
});
});
},
实现ppt里面这样得效果
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要求均分还是自动溢出换行?
统计所有的
left
和left + width
。Math.min(...lefs)
最左端Math.max(...righs)
最右端然后就是区域内分成几份的问题了,如果这个时候直接使用的话,是居左。那么我们根据当前的idx移动一下中心。
也可以统计 width 的和。然后减去空间,再平分。然后再原有的基础上偏移也可以。
试试 flex布局