<title>draggable quadratic bezier curve</title>
<svg id="figure1" width="300" height="300">
<path d="M70 250 20 110 250 50" stroke="black" fill="none" id="controlPath"/>
<path d="M70 250Q20 110 250 50" stroke="green" fill="none" id="curve"/>
<circle cx="70" cy="250" r="8" id="p1" class="control-point draggable"/>
<circle cx="20" cy="110" r="8" id="p2" class="control-point draggable"/>
<circle cx="250" cy="50" r="8" id="p3" class="control-point draggable"/>
var controlPath = document.getElementById('controlPath');
var curve = document.getElementById('curve');
var p1 = document.getElementById('p1');
var p2 = document.getElementById('p2');
var p3 = document.getElementById('p3');
var svg = document.getElementById('figure1');
svg.addEventListener('mousemove', onMouseMove);
svg.addEventListener('mouseup', onMouseUp);
var elements = [p1, p2, p3];
for (i = 0; i < elements.length; i++) {
elements[i].addEventListener('mousedown', onMouseDown);
var mouseOffsetX, mouseOffsetY;
function getClientPointInSVG(ev) {
p = svg.createSVGPoint();
m = dragElem.getScreenCTM();
return p.matrixTransform(m.inverse());
function onMouseDown(ev) {
p = getClientPointInSVG(ev);
mouseOffsetX = p.x - dragElem.getAttribute('cx');
mouseOffsetY = p.y - dragElem.getAttribute('cy');
function onMouseMove(ev) {
p = getClientPointInSVG(ev);
dragElem.setAttribute('cx', p.x - mouseOffsetX);
dragElem.setAttribute('cy', p.y - mouseOffsetY);
controlPath.setAttribute('d',
'M' + p1.getAttribute('cx') + ' ' + p1.getAttribute('cy') +
' ' + p2.getAttribute('cx') + ' ' + p2.getAttribute('cy') +
' ' + p3.getAttribute('cx') + ' ' + p3.getAttribute('cy'));
'M' + p1.getAttribute('cx') + ' ' + p1.getAttribute('cy') +
'Q' + p2.getAttribute('cx') + ' ' + p2.getAttribute('cy') +
' ' + p3.getAttribute('cx') + ' ' + p3.getAttribute('cy'));