使用说明

  1. 您可以通过拖动红色和橙色控制点来调整贝塞尔曲线
  2. 也可以通过输入框精确设置控制点坐标
  3. 点击"播放动画"按钮查看动画效果
  4. 使用滑块调整动画持续时间
  5. 点击预设按钮快速应用常用的贝塞尔曲线
  6. 点击"复制"按钮将 cubic-bezier 函数复制到剪贴板

三阶贝塞尔曲线 javascript 实现


/**
 * @desc 三阶贝塞尔
 * @param {number} t 当前百分比
 * @param {Array} p1 起点坐标
 * @param {Array} p2 终点坐标
 * @param {Array} cp1 控制点1
 * @param {Array} cp2 控制点2
 */
export function cubicBezier(t, p1, cp1, cp2, p2) {
  const [x1, y1] = p1;
  const [x2, y2] = p2;
  const [cx1, cy1] = cp1;
  const [cx2, cy2] = cp2;
  let x =
      x1 * (1 - t) * (1 - t) * (1 - t) +
      3 * cx1 * t * (1 - t) * (1 - t) +
      3 * cx2 * t * t * (1 - t) +
      x2 * t * t * t;
  let y =
      y1 * (1 - t) * (1 - t) * (1 - t) +
      3 * cy1 * t * (1 - t) * (1 - t) +
      3 * cy2 * t * t * (1 - t) +
      y2 * t * t * t;
  return [x, y];
}

功能说明

这个页面实现了一个完整的 CSS3 cubic-bezier 函数在线调试工具,具有以下功能:

  1. 贝塞尔曲线可视化 :
    • 实现三阶贝塞尔函数绘制贝塞尔曲线
    • 可拖动控制点调整曲线形状
    • 显示网格和坐标轴辅助线
  2. 参数控制 :
    • 通过输入框精确调整 P1(x1, y1) 和 P2(x2, y2) 坐标
    • 实时更新曲线和动画效果
  3. 动画预览 :
    • 显示基于当前贝塞尔曲线的动画效果
    • 可调整动画持续时间
    • 一键播放动画
  4. 实用功能 :
    • 复制 cubic-bezier 函数代码到剪贴板
    • 内置常用预设值(ease, ease-in, ease-out 等)
  5. 响应式设计 :
    • 适配不同屏幕尺寸

完整的一到三阶贝塞尔曲线 javascript 实现

/**
 * @desc 贝塞尔曲线算法,包含了3阶贝塞尔
 */
class Bezier {
    /**
     * @desc 获取点,这里可以设置点的个数
     * @param {number} num 点个数
     * @param {Array} p1 点坐标
     * @param {Array} p2 点坐标
     * @param {Array} p3 点坐标
     * @param {Array} p4 点坐标
     * 如果参数是 num, p1, p2 为一阶贝塞尔
     * 如果参数是 num, p1, c1, p2 为二阶贝塞尔
     * 如果参数是 num, p1, c1, c2, p2 为三阶贝塞尔
     */
    getBezierPoints(num = 100, p1, p2, p3, p4) {
        let func = null;
        const points = [];
        if (!p3 && !p4) {
            func = this.oneBezier;
        } else if (p3 && !p4) {
            func = this.twoBezier;
        } else if (p3 && p4) {
            func = this.threeBezier;
        }
        for (let i = 0; i < num; i++) {
            points.push(func(i / num, p1, p2, p3, p4));
        }
        if (p4) {
            points.push([...p4]);
        } else if (p3) {
            points.push([...p3]);
        }
        return points;
    }

    /**
     * @desc 一阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     */
    oneBezier(t, p1, p2) {
        const [x1, y1] = p1;
        const [x2, y2] = p2;
        let x = x1 + (x2 - x1) * t;
        let y = y1 + (y2 - y1) * t;
        return [x, y];
    }

    /**
     * @desc 二阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     * @param {Array} cp 控制点
     */
    twoBezier(t, p1, cp, p2) {
        const [x1, y1] = p1;
        const [cx, cy] = cp;
        const [x2, y2] = p2;
        let x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2;
        let y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2;
        return [x, y];
    }

    /**
     * @desc 三阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     * @param {Array} cp1 控制点1
     * @param {Array} cp2 控制点2
     */
    threeBezier(t, p1, cp1, cp2, p2) {
        const [x1, y1] = p1;
        const [x2, y2] = p2;
        const [cx1, cy1] = cp1;
        const [cx2, cy2] = cp2;
        let x =
            x1 * (1 - t) * (1 - t) * (1 - t) +
            3 * cx1 * t * (1 - t) * (1 - t) +
            3 * cx2 * t * t * (1 - t) +
            x2 * t * t * t;
        let y =
            y1 * (1 - t) * (1 - t) * (1 - t) +
            3 * cy1 * t * (1 - t) * (1 - t) +
            3 * cy2 * t * t * (1 - t) +
            y2 * t * t * t;
        return [x, y];
    }
}

export default new Bezier();

CubicBezier