废话不多说之间看效果图,只要解决了这个效果水滴tabbar就能做出来了
源码地址
一、核心实现步骤分解
布局结构搭建
使用 作为绘制容器
设置 width=600, height=200 基础尺寸
通过 JS 动态计算实际尺寸(适配高清屏)
function initCanvas() {
// 获取设备像素比(解决 Retina 屏模糊问题)
const dpr = window.devicePixelRatio || 1;
// 获取父容器实际显示宽度(CSS像素)
const containerWidth = canvas.parentElement.clientWidth;
// 设置 Canvas 的 CSS 显示尺寸
canvas.style.width = containerWidth + 'px';
canvas.style.height = '200px';
// 设置 Canvas 的实际像素尺寸(物理像素)
canvas.width = containerWidth * dpr;
canvas.height = 200 * dpr;
// 缩放坐标系(关键步骤!保证绘制内容高清)
ctx.scale(dpr, dpr);
}
水滴形状绘制
几何分解:水滴 = 左右对称曲线 + 中间半圆
贝塞尔曲线控制点:通过三段三次贝塞尔曲线连接
动态坐标计算:基于 Canvas 宽度动态定位
// 三段贝塞尔曲线参数配置
const curves = {
left: {
P0: {
x: width - len, y: 0 }, // 左曲线起点
CP1: {
x: width - r1 - r2/2, y: 0 }, // 控制点1(水平左移)
CP2: {
x: width - r1, y: r2/2 }, // 控制点2(垂直下压)
P3: {
x: width - r1, y: r2 } // 连接中间半圆左端点
},
// ... 其他曲线段类似
};
// 路径绘制执行
ctx.beginPath();
ctx.moveTo(0, 0); // 从左上角开始
ctx.lineTo(curves.left.P0.x, curves.left.P0.y); // 绘制左侧直线
// 绘制左半曲线
ctx.bezierCurveTo(
curves.left.CP1.x, curves.left.CP1.y,
curves.left.CP2.x, curves.left.CP2.y