如何以抛物线形式排列一个列表,曲线排列
一、需求
做页面的时候遇到一个需求,需要将一个列表以曲线的形式排列展示。
列表内容:
const statisticLabels: Array<{
name: string,
icon: string,
path: string,
type: string,
dataName: string
}> = [
{name: '云盒报警', icon: 'Bell', path: '/alarm/alarm-history-box', type: 'danger', dataName: 'box_alarm_total'},
{name: '设备报警', icon: 'Bell', path: '/alarm/alarm-history-device', type: 'danger', dataName: 'device_alarm_total'},
{name: '总驱动', icon: 'Coin', path: '/driver/driver-list', type: 'warning', dataName: 'driver_total'},
{name: '总设备', icon: 'Refrigerator', path: '/iot/device-list', type: 'primary', dataName: 'device_total'},
{name: '总云盒', icon: 'MessageBox', path: '/iot/box-list', type: 'success', dataName: 'box_total'},
{name: '总项目', icon: 'FolderOpened', path: '/iot/project', type: 'primary', dataName: 'project_total'},
{name: '总工单', icon: 'Tickets', path: '/ticket/order-list', type: 'info', dataName: 'ticket_total'},
{name: '未处理工单', icon: 'Tickets', path: '/ticket/order-list', type: 'info', dataName: 'ticket_created'},
]
二、一个不太好看的实现方式
列表只需要一个变量来控制它往左边的偏移量:margin-left
只需要用一个方法来获取每个列表项的 margin-left
,这个方法:输入列表项的 index
, 输出这个列表项应该的 margin-left
偏移量
function getMarginLeftOfIndex(index: number): number{
let lineTotal = statisticLabels.length
const maxMarginLeft = 500
return Math.abs(index - lineTotal/2) * maxMarginLeft / lineTotal
}
如果列表项等距离的错开,会成下面这样:
三、以抛物线形式排列这个列表
能看出上面这个等量偏移的方式并不太好看,好看的曲线就只能是抛物线的形式。
这里就需要用一下以前初中学的抛物线方程:
x² = y
只不过现在这个展示的是普通抛物线旋转 90度 的样子。
所以我们需要转换一下坐标:
黑色的序号是列表的 Index, 需要转换成方程中的坐标值,然后用抛物线的方程算出对应位置的偏移量。
// index 位置距离中心点的距离
Math.abs(Math.abs(index - lineTotal/2))
实现的方程是这样的:
function getMarginLeftOfIndex(index: number): number{
let lineTotal = statisticLabels.length
const maxMarginLeft = 500
return Math.abs(index - lineTotal/2) * maxMarginLeft / lineTotal
}
四、最终结果
根据需要调整方法中的 maxMarginLeft
来调整列表整体的偏移量