Построение кривой Безье на 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);
}
Если у вас возникнут вопросы по этому пример, задайте их в комментарии. Удачной разработки!
Алексей, фильм пока не смотрел, но скрипт попробовал запускать. Получилось, что в FF у события нет свойства srcElement, пришлось еще проверять else if(e.target instanceof SVGCircleElement), а IE11 не понимает новый синтаксис подстановки переменных в строку `M${d.x1} ${d.y1} Q ${d.x2} ${d.y2} ${d.x3} ${d.y3}`, чтобы заработало, пришлось поменять на стандартную конкатенацию.
Но эти детали наверное и не нужны в статье, конкретно и лаконично объясняющей сам принцип.
Спасибо! Да, надо было
var target = e.target || e.srcElement
. В IE не проверял, спешил реализовать идею; сейчас попробовал на десятке — codepen даже содержимое полей с кодом не показывает.>>Но эти детали наверное и не нужны в статье, конкретно и лаконично объясняющей сам принцип.
Эти детали важны для начинающих разработчиков, спасибо за комментарий.