效果概述
实现了以下特性:
- 鼠标悬停时展开图标
- 光标移动时图标弹性缩放
- 相邻图标间距自动适应
- 平滑过渡动画
注:如果你想先看效果或完整代码可以去codesandbox codesandbox.io/p/sandbox/b...
使用了我自己写的框架 belling js(在npm上找belling就可以了),是一个高性能的极简mvvm框架。如果你是用vue或react,把state转换成createSignal, h函数转换成jsx就可以了。
核心实现原理
1. 布局架构
使用绝对定位的弹性容器:
javascript
ForIn("div", apps, (i, v) => {
// 生成每个dock图标
}).style({
position: "relative",
width: () => apps.v.length * (w + gap) + gap + 'px',
height: w + 'px'
})
2. 动态响应体系
基于响应式状态管理:
javascript
const x = state(0); // 鼠标X坐标
const hover = state(false); // 悬停状态
3. 鼠标交互
通过事件监听更新状态:
javascript
.on({
mouseenter() { hover.v = true },
mouseleave() { hover.v = false },
mousemove(e) {
x.v = e.clientX - ele.dom.offsetLeft;
}
})
灵魂所在:缩放函数解析
核心算法
javascript
function scale(x) {
return x > 0 ?
scaleRatio * Math.log(x + 1) + x :
-(scaleRatio * Math.log(-x + 1) - x);
}
实现原理
这个函数实现了非对称弹性缩放效果:
scaleRatio: 缩放强度系数(示例值为2)
函数特点:
分界处理:偶函数沿鼠标两侧对称 对数基底:使用log2实现初始变化率大,即鼠标位置放大 叠加:位移 + 对数缩放分量
- 中心点附近变化剧烈
- 边缘区域变化平缓
动态尺寸计算
结合缩放函数实现弹性布局:
javascript
Copy
scss
function size() {
const l = i.v * (w + gap); // 原始左坐标
const r = l + w; // 原始右坐标
// 计算缩放后的实际宽度
return scale(r - x.v) - scale(l - x.v) + "px";
}
效果优化
添加一点CSS过渡动画:
css
transition: all 0.1s
扩展建议
调节scaleRatio控制缩放幅度 修改对数基底改变衰减曲线 实现图标内容缩放