如何实现类Mac Dock的弹性缩放动画

效果概述

实现了以下特性:

  • 鼠标悬停时展开图标
  • 光标移动时图标弹性缩放
  • 相邻图标间距自动适应
  • 平滑过渡动画

注:如果你想先看效果或完整代码可以去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控制缩放幅度 修改对数基底改变衰减曲线 实现图标内容缩放

相关推荐
Highcharts.js3 小时前
如何下载使用Highcharts Grid 开发web可编辑表格
前端·人工智能·grid 表格·web 表格·在线编辑表格·highcharts表格安装·表格开发工具
用户62960593247054 小时前
从“浏览器根本区分不了”到真正实现:刷新不退出,关闭标签页自动退出,前端判断浏览器关闭和刷新
前端
qetfw4 小时前
MWU:Vue 3 + FastAPI 的 MaaFramework 跨平台 WebUI 源码
前端·vue.js·python·fastapi·开源项目·效率工具
mfxcyh4 小时前
Vue3+Ant Design Vue 实现手动异步文件上传(含大小校验、弹窗上传)
前端·javascript·vue.js
wordbaby4 小时前
Web端热敏标签打印完整解决方案(QZ Tray + 译维A42)
前端
swipe4 小时前
03|Axios 请求进了后端之后:Controller、Request、Response 是怎么接住它的?
前端·后端·全栈
meilindehuzi_a4 小时前
Vue3进阶基础:指令修饰符、v-model表单绑定、动态样式、计算属性与侦听器实战
前端·javascript·vue.js
csdn2015_4 小时前
vue 前端运行命令
前端·javascript·vue.js
swipe4 小时前
02|从 `pnpm dev` 到 Spring Boot 启动:后端服务到底怎么跑起来?
前端·后端·全栈
swipe5 小时前
01|前端人第一次打开 Spring Boot 项目,应该先看哪里?
前端·后端·全栈