用JavaScript创建的尖贝塞尔曲线

时间:2018-11-01 18:11:55

标签: javascript svg

我第一次玩香草JavaScript和SVG。 现在,我无法自己解决问题。

这个想法是在点的y轴上移动点。 x轴由已经存在的点(红色圆圈)给出。

我现在计算一个以光标的x值为中心的等腰三角形。三角形随鼠标一起移动。 现在,将计算给定点(红色圆圈)与三角形的交点。 在此相交点被设置。通过这些点,我绘制了贝塞尔曲线。

三角形背后的想法是,当红点分开时,我不想创建非常“陡峭”的曲线。所以我可以“散开” /稍微弄平曲线。至少就是这个主意。

到目前为止,基本原理还算不错,但是发生了一件奇怪的事情:在两个点(用蓝色标记)中,曲线看起来像模拟的三角形-但中间的所有点都创建了完美的贝塞尔曲线。

我不知道发生了什么。 非常感谢您的输入-请对我的(可能是)错误的代码表示友好-我是初学者。 ;)

谢谢!

CodePen:https://codepen.io/clmsvie/pen/Edqzpp?editors=1111

var n = 0;

c1x = 50;
d = 350;

var gap = 100;

var dotsX = [];
var dotsXY = [];

// Kreise zeichnen
var svg = document.querySelector("svg");

for (var i = 0; i <= 8; i++) {
  var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
  circle.setAttributeNS(null, "class", "blub c" + i);
  circle.setAttributeNS(null, "cx", c1x);
  circle.setAttributeNS(null, "cy", d);
  circle.setAttributeNS(null, "r", 15);
  svg.appendChild(circle);
  dotsX.push(c1x); // Werte der Punkte ins Array schreiben
  dotsXY.push(c1x);
  c1x += gap;
}

// Dreieck zeichnen, entlang der virtuellen x Achse
var $tri = document.querySelectorAll(".triangle");

ta = 100; // Strecke = Höhe
tc = 250; // Strecke = Distanz x-Achse
tB = 350; // Punkt = X Punkt der Maus

ax = tB - tc; // A
ay = d;
bx = tB; // B
by = d;
cx = tB; //C
cy = d - ta;

// Maus Koordinaten feststellen

function mouseMove(e) {
  x = typeof e.pageX != "undefined" ? e.pageX : e.touches[0].pageX;
  y = typeof e.pageY != "undefined" ? e.pageY : e.touches[0].pageY;

  //console.log("x = " + x + " y = " + y);

  // Punkt entlang b Achse eines Rechtwinkligen Dreiecks verschieben

  tB = x;

  ax = x - tc; // A
  ay = d;
  bx = x; // B
  by = d;
  cx = x; //C
  cy = d - ta;

  setDots();
}

"mousemove touchmove".split(" ").forEach(function(e) {
  document.addEventListener(e, mouseMove, true);
});

function setDots() {
  // ### Rote Kreise auf Dreieck setzen

  // 2. Brechne neue Höhe der Punkte (auf Dreieck)

  var dotsXY = dotsX.map(function(dotX) {
    tA = tB - tc;
    disDotInTri = dotX < tB ? dotX - tA : tB + tc - dotX;
    dotY = d - disDotInTri * ta / tc;
    dotY = dotY <= d ? dotY : d; // Nicht negativ werden
    return [dotX, dotY.toFixed(2)];
  });

  //console.log("Y-Werte: " + dotsXY);

  var path =
    "M0," +
    d +
    " C" +
    dotsXY
      .map(function(dot) {
        return dot[0] + "," + dot[1];
      })
      .join(" ");

  console.log(path);
  console.log(dotsXY[0] + " - " + dotsXY[2] + " - " + dotsXY[4]);

  // Kontrollpunkte

  var paras = document.getElementsByClassName("kontrolle");

  while (paras[0]) {
    paras[0].parentNode.removeChild(paras[0]);
  }

  for (var i = 0; i < dotsXY.length; i++) {
    var circleKontrolle = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "circle"
    );
    circleKontrolle.setAttributeNS(null, "class", "blub kontrolle");
    circleKontrolle.setAttributeNS(null, "cx", dotsXY[i][0]);
    circleKontrolle.setAttributeNS(null, "cy", dotsXY[i][1]);
    circleKontrolle.setAttributeNS(null, "r", 5);
    svg.appendChild(circleKontrolle);
  }

  document.querySelector("path").setAttribute("d", path);
}
svg {
  width: 100%;
  height: 400px;
  background-color:#d1ff88;
}

path {
  stroke: black;
  stroke-width: 10px;
  stroke-linecap: round;
  fill: none;
}

.blub {
  stroke: black;
  stroke-width: 3px;
  fill: red;
}

#bezier-path {
  stroke: red;
    fill: none;
    stroke-width: 1.2;
}

.c2, .c5 {
  fill: blue;
}
<svg class="test">
  <path xmlns="http://www.w3.org/2000/svg" stroke="red" fill="none" id="bezier-path" stroke-width="1.2" d="M0,350 C50,333.20 150,293.20 250,253.20 350,286.80 450,326.80 550,350.00 650,350.00 750,350.00 850,350.00"/>
</svg>

0 个答案:

没有答案