ham*_*son 18 javascript svg bin-packing d3.js
试图找出最好的方法,将装箱后的已知宽度的svg图像打包/分布在水平行中,如果容器的宽度太紧,可以将它们堆叠在一起。
容器的高度应最佳地自动调整,并且重力应为垂直中心点。创建了一些图像来说明所需的解决方案。
有没有解决这个问题的JS库,也许是d3?感觉上像是一个装箱问题,但也许在顺序和重力方面增加了一些复杂性。对画布解决方案不感兴趣。
如果容器足够宽

太紧,堆叠一些元素

更紧密地堆叠所有

对于基于D3的纯SVG解决方案,我的建议是使用带有碰撞检测的力仿真。D3力模拟(d3.forceCollide)中的碰撞检测是圆形的,即以元素的半径为参数。因此,由于您具有正方形/矩形元素,因此我使用了发现的这种矩形碰撞检测。
这个想法是根据数据和可用宽度使用模拟来设置x和y位置,并根据元素的大小进行碰撞。然后,在调整大小事件中,以新的宽度再次运行模拟。
请记住,与您会发现的大多数D3力导向图相反,我们不想显示整个仿真过程,而只显示最终位置。因此,您将设置仿真并立即停止仿真:
const simulation = d3.forceSimulation(data)
//etc...
.stop();
Run Code Online (Sandbox Code Playgroud)
然后,您执行以下操作:
simulation.tick(n);
Run Code Online (Sandbox Code Playgroud)
或者,在调整大小处理程序中,将其重新加热:
simulation.alpha(1).tick(n);
Run Code Online (Sandbox Code Playgroud)
n您想要的迭代次数在哪里。越多越好,但越慢...
这是一个非常粗糙的示例,移动右侧的蓝色手柄以挤压矩形:
const simulation = d3.forceSimulation(data)
//etc...
.stop();
Run Code Online (Sandbox Code Playgroud)
simulation.tick(n);
Run Code Online (Sandbox Code Playgroud)
simulation.alpha(1).tick(n);
Run Code Online (Sandbox Code Playgroud)
正如我所说,这是一个非常粗糙的代码,仅作为示例。您可以调整强度并改进其他零件,以满足您的需求。
您尝试实现的是砌体布局。通常在不知道元素的高度和数量时使用。真实的砖石布局即使使用可变宽度的元素也可以使用。
这是一个JSFIDDLE示例(调整大小以查看元素如何打包)。
很多代码都需要一些JS,仍然不会是真正的砖石,为每列将具有相同的宽度(在这里,或点击这里)。尽管您实际上可以通过使用多列布局以及媒体查询在纯CSS(无js)中实现此结果。但是,因为这仅在所有元素都具有相同的宽度时才适用,而且似乎不是您的情况,所以我建议您从下面的列表中选择一个:
https://isotope.metafizzy.co/layout-modes/masonry.html
支持很多功能:
https://codepen.io/jh3y/pen/mPgyqw this one is pure css, but is
trickier to use
这是第一个行动的:
我可能已经忘记了一些,如果是的话,请在评论部分提出建议,如果确实是一个砖石结构(支持可变宽度),根据OP的要求,我会将其添加到列表中。
| 归档时间: |
|
| 查看次数: |
471 次 |
| 最近记录: |