Построение кривой Безье на SVG и JavaScript

Построение кривой Безье на SVG и JavaScript

Построение кривой Безье на SVG

Кривая Безье на SVG и JavaScript

Построение кривой Безье на SVG, процесс не сложный, если мы знаем о векторной масштабируемой графике и о кривых Безье 🙂 Эти кривые могут использовать для описания кривых линий на основе нескольких базовых точек. Сам SVG фактически является расширение языка XML; состоит из корневой элемент с одноимённым названием — svg,  и различными фигурами внутри  — прямоугольником, окружностью, отрезком, путём (path) и др.

Построение кривой Безье


Код примера можно посмотреть на Codepen.  Видео-ролик о решении задачи по изменению SVG при помощи JavaScript.

Пример SVG-элемента с сайта Мозиллы:

<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
  <path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>
</svg>

Наш черновой вариант для решения прикладной задачи:

var c1 = document.querySelectorAll("circle")[0],
c2 = document.querySelectorAll("circle")[1],
c3 = document.querySelectorAll("circle")[2],
path = document.querySelectorAll("path")[0],
drag, d = {x1:10,y1:80,x2:95,y2:10,x3:180,y3:80};    

window.addEventListener("mousedown",mdHandler);
function mdHandler(e){
  if(e.srcElement instanceof SVGCircleElement){
    drag = e.srcElement;
    drag.x = e.srcElement.getAttribute("cx");
    drag.y = e.srcElement.getAttribute("cy");
    drag.clientX = e.clientX;
    drag.clientY = e.clientY;
    
    window.addEventListener("mousemove",mmHandler);
    window.addEventListener("mouseup",muHandler);
  }
}

function mmHandler(e){
  drag.setAttribute("cx",e.clientX - (drag.clientX - drag.x));
  drag.setAttribute("cy",e.clientY - (drag.clientY - drag.y));
  switch( drag ){
    case c1:
      d.x1 = drag.getAttribute("cx");
      d.y1 = drag.getAttribute("cy"); break;    
    case c2:
      d.x2 = drag.getAttribute("cx");
      d.y2 = drag.getAttribute("cy"); break;
    case c3:
      d.x3 = drag.getAttribute("cx");
      d.y3 = drag.getAttribute("cy"); break;      
  }
  path.setAttribute("d",`M${d.x1} ${d.y1} Q ${d.x2} ${d.y2} ${d.x3} ${d.y3}`);
  document.getElementById("path").innerHTML = path.getAttribute("d");
}
function muHandler(e){
  window.removeEventListener("mousemove",mmHandler);
  window.removeEventListener("mouseup",muHandler);
} 

Если у вас возникнут вопросы по этому пример, задайте их в комментарии. Удачной разработки!


Об авторе

@altarasov administrator

2 комментария

T-50Дата:2:39 пп - Дек 9, 2016

Алексей, фильм пока не смотрел, но скрипт попробовал запускать. Получилось, что в FF у события нет свойства srcElement, пришлось еще проверять else if(e.target instanceof SVGCircleElement), а IE11 не понимает новый синтаксис подстановки переменных в строку `M${d.x1} ${d.y1} Q ${d.x2} ${d.y2} ${d.x3} ${d.y3}`, чтобы заработало, пришлось поменять на стандартную конкатенацию.
Но эти детали наверное и не нужны в статье, конкретно и лаконично объясняющей сам принцип.

    @altarasovДата:3:07 пп - Дек 9, 2016

    Спасибо! Да, надо было var target = e.target || e.srcElement. В IE не проверял, спешил реализовать идею; сейчас попробовал на десятке — codepen даже содержимое полей с кодом не показывает.

    >>Но эти детали наверное и не нужны в статье, конкретно и лаконично объясняющей сам принцип.
    Эти детали важны для начинающих разработчиков, спасибо за комментарий.

Вы должны быть авторизованы, чтобы оставить комментарий.