SVG动画演示贝塞尔曲线(1-4阶)绘制过程

贝塞尔曲线是我们大陆的叫法,英文名是Bézier Curve,港澳台称为貝茲曲線,新加坡马来西亚称为贝济埃曲线。

先看一下效果图: 点击这里查看动画效果


维基百科中的贝塞尔曲线条目中的几个GIF动画很漂亮,顺路贴上来。


核心Javscript代码:

var w = 250,
    h = 300,
    t = .5,
    delta = .01,
    padding = 10,
    points = [{x: 10, y: 250}, {x: 0, y: 0}, {x: 100, y: 0}, {x: 200, y: 250}, {x: 225, y: 125}],
    bezier = {},
    line = d3.svg.line().x(x).y(y),
    n = 4,
    orders = d3.range(2, n + 2);

var vis = d3.select("body").selectAll("svg")
    .data(orders)
  .enter().append("svg:svg")
    .attr("width", w + 2 * padding)
    .attr("height", h + 2 * padding)
  .append("svg:g")
    .attr("transform", "translate(" + padding + "," + padding + ")");

update();

vis.selectAll("circle.control")
    .data(function(d) { return points.slice(0, d) })
  .enter().append("svg:circle")
    .attr("class", "control")
    .attr("r", 7)
    .attr("cx", x)
    .attr("cy", y)
    .call(d3.behavior.drag()
      .on("dragstart", function(d) {
        this.__origin__ = [d.x, d.y];
      })
      .on("drag", function(d) {
        d.x = Math.min(w, Math.max(0, this.__origin__[0] += d3.event.dx));
        d.y = Math.min(h, Math.max(0, this.__origin__[1] += d3.event.dy));
        bezier = {};
        update();
        vis.selectAll("circle.control")
          .attr("cx", x)
          .attr("cy", y);
      })
      .on("dragend", function() {
        delete this.__origin__;
      }));

vis.append("svg:text")
  .attr("class", "t")
  .attr("x", w / 2)
  .attr("y", h)
  .attr("text-anchor", "middle");

vis.selectAll("text.controltext")
    .data(function(d) { return points.slice(0, d); })
  .enter().append("svg:text")
    .attr("class", "controltext")
    .attr("dx", "10px")
    .attr("dy", ".4em")
    .text(function(d, i) { return "P" + i });

var last = 0;
d3.timer(function(elapsed) {
  t = (t + (elapsed - last) / 5000) % 1;
  last = elapsed;
  update();
});

function update() {
  var interpolation = vis.selectAll("g")
      .data(function(d) { return getLevels(d, t); });
  interpolation.enter().append("svg:g")
      .style("fill", colour)
      .style("stroke", colour);

  var circle = interpolation.selectAll("circle")
      .data(Object);
  circle.enter().append("svg:circle")
      .attr("r", 4);
  circle
      .attr("cx", x)
      .attr("cy", y);

  var path = interpolation.selectAll("path")
      .data(function(d) { return [d]; });
  path.enter().append("svg:path")
      .attr("class", "line")
      .attr("d", line);
  path.attr("d", line);

  var curve = vis.selectAll("path.curve")
      .data(getCurve);
  curve.enter().append("svg:path")
      .attr("class", "curve");
  curve.attr("d", line);

  vis.selectAll("text.controltext")
      .attr("x", x)
      .attr("y", y);
  vis.selectAll("text.t")
      .text("t=" + t.toFixed(2));
}

function interpolate(d, p) {
  if (arguments.length < 2) p = t;
  var r = [];
  for (var i=1; i<d.length; i++) {
    var d0 = d[i-1], d1 = d[i];
    r.push({x: d0.x + (d1.x - d0.x) * p, y: d0.y + (d1.y - d0.y) * p});
  }
  return r;
}

function getLevels(d, t_) {
  if (arguments.length < 2) t_ = t;
  var x = [points.slice(0, d)];
  for (var i=1; i<d; i++) {
    x.push(interpolate(x[x.length-1], t_));
  }
  return x;
}

function getCurve(d) {
  var curve = bezier[d];
  if (!curve) {
    curve = bezier[d] = [];
    for (var t_=0; t_<=1; t_+=delta) {
      var x = getLevels(d, t_);
      curve.push(x[x.length-1][0]);
    }
  }
  return [curve.slice(0, t / delta + 1)];
}

function x(d) { return d.x; }
function y(d) { return d.y; }
function colour(d, i) {
  return d.length > 1 ? ["#ccc", "yellow", "blue", "green"][i] : "red";
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SVG 是一种用于创建矢量图形的语言,其中包含了一些绘制基本图形的元素(如线段、矩形、圆形等),也支持使用贝塞尔曲线绘制更复杂的图形。下面我将介绍如何在 SVG 中使用贝塞尔曲线贝塞尔曲线是一种数学曲线,其形状由一组控制点决定。在 SVG 中,我们可以使用 path 元素来绘制贝塞尔曲线。path 元素的 d 属性表示路径,其中包含了一系列子命令,每个子命令代表了一条线段或一条曲线。 下面是一个简单的贝塞尔曲线的示例: ```html <svg width="100" height="100"> <path d="M 20 80 Q 50 20, 80 80" stroke="black" fill="none"/> </svg> ``` 这个示例绘制了一条起点为 (20, 80),结束点为 (80, 80) 的曲线,并且控制点为 (50, 20)。其中,M 表示移动到指定点,Q 表示绘制二次贝塞尔曲线,stroke 表示线条颜色,fill 表示填充颜色。 如果你想要绘制更复杂的曲线,可以使用更多的子命令,比如 C 表示绘制三次贝塞尔曲线。下面是一个绘制心形的示例: ```html <svg width="100" height="100"> <path d="M 50 10 C 60 10, 70 20, 70 30 C 70 50, 50 70, 30 90 C 10 70, 10 50, 30 30 C 40 20, 50 10, 50 10" stroke="red" fill="none"/> </svg> ``` 这个示例绘制了一个心形,其中 C 表示绘制三次贝塞尔曲线,stroke 表示线条颜色,fill 表示填充颜色。 希望这个简单的教程能够帮助你开始使用 SVG 绘制贝塞尔曲线。如果你需要更深入的学习,可以参考 SVG 的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值