<pre id="code">code</pre>

<div id="container" type="image/svg+xml"  class="C"><svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 499" width="500" height="500" preserveAspectRatio="xMidYMid meet">
  <g id="main">
    <circle id="p1" cx="100" cy="250" r="16" />
    <circle id="p2" cx="400" cy="250" r="16" />
    
    <circle id="c1" cx="100" cy="100" r="8" />
    <circle id="c2" cx="400" cy="100" r="8" />
    
    <line id="l1" x1="100" y1="250" x2="100" y2="100" />
    <line id="l2" x1="400" y1="250" x2="400" y2="100" />
  
    <path id="curve" d="M100,250 C100,100 400,100 400,250" />
  </g>
</svg></div>
<div class="credit">developed by <a href="https://twitter.com/craigbuckler">Craig Buckler</a> of <a href="http://optimalworks.net/">OptimalWorks.net</a> for <a href="http://sitepoint.com/">SitePoint.com</a></div>
$color-path: #1E1935
$color-controls: #EF2D56
$color-subtle: #999
$color-box: rgba(221,221,221,0.35)
$color-bg: #fff

*
    box-sizing: border-box
    padding: 0
    margin: 0
 
#container
    width: 100%
    height: 500px
    background: $color-bg
    margin: 0 auto
    text-align: center

#code
    display: block
    width: auto
    font: bold 3vw monospace
    padding: 50px 0 4vw 10vw
    margin: 0
    color: $color-path
    background: $color-box
    
    &::selection
        background: $color-controls
        color: $color-bg

path
    stroke-width: 8
    stroke: $color-path
    stroke-linecap: round
    fill: none

path.fill
    fill: $color-path

circle
    stroke-width: 2
    stroke: $color-controls
    fill: $color-bg

circle:hover
    fill: $color-controls
    cursor: move

line
    stroke-width: 1
    stroke: $color-subtle
    stroke-linecap: round
    stroke-dasharray: 5,3
    
.credit
    position: absolute
    top: 5px
    right: 15px
    font: 11px Helvetica, Arial, sans-serif
    color: $color-subtle
    
a
    color: inherit
View Compiled
/* 
 * SVG curve example
 *
 * By Craig Buckler,    https://twitter.com/craigbuckler
 * of OptimalWorks.net    http://optimalworks.net/
 * for SitePoint.com    http://sitepoint.com/
 * 
 * Refer to:
 * http://www.sitepoint.com/html5-svg-quadratic-curves/
 * http://www.sitepoint.com/html5-svg-cubic-curves/
 *
 * This code can be used without restrictions.
 */

(function() {

  var container, svg, cType, code, point = {}, line = {}, fill = false, drag = null, dPoint, maxX, maxY;

  // define initial points
  function Init() {

    var c = svg.getElementsByTagName("circle");
    for (var i = 0; i < c.length; i++) {
      point[c[i].getAttributeNS(null,"id")] = {
        x: parseInt(c[i].getAttributeNS(null,"cx"),10),
        y: parseInt(c[i].getAttributeNS(null,"cy"),10)
      };
    }
    
    // lines
    line.l1 = svg.getElementById("l1");
    line.l2 = svg.getElementById("l2");
    line.curve = svg.getElementById("curve");
    
    // code
    code = document.getElementById("code");
  
    // event handlers
    svg.onmousedown = svg.onmousemove = svg.onmouseup = Drag;
    svg.ontouchstart = svg.ontouchmove = svg.ontouchend = Drag;
    
    DrawSVG();
  }
  
  
  // draw curve
  function DrawSVG() {
  
    // control line 1
    line.l1.setAttributeNS(null, "x1", point.p1.x);
    line.l1.setAttributeNS(null, "y1", point.p1.y);
    line.l1.setAttributeNS(null, "x2", point.c1.x);
    line.l1.setAttributeNS(null, "y2", point.c1.y);
    
    // control line 2
    var c2 = (point.c2 ? "c2" : "c1");
    line.l2.setAttributeNS(null, "x1", point.p2.x);
    line.l2.setAttributeNS(null, "y1", point.p2.y);
    line.l2.setAttributeNS(null, "x2", point[c2].x);
    line.l2.setAttributeNS(null, "y2", point[c2].y);
    
    // curve
    var d = 
      "M"+point.p1.x+","+point.p1.y+" "+cType+
      point.c1.x+","+point.c1.y+" "+
      (point.c2 ? point.c2.x+","+point.c2.y+" " : "")+
      point.p2.x+","+point.p2.y+
      (fill ? " Z" : "");
    line.curve.setAttributeNS(null, "d", d);
    
    // show code
    if (code) {
      code.textContent = '<path d="'+d+'" />';
    }
  }
  
  
  // drag event handler
  function Drag(e) {
    
    e.stopPropagation();
    var t = e.target, id = t.id, et = e.type, m = MousePos(e);
  
    // toggle fill class
    if (!drag && et == "mousedown" && id == "curve") {
      fill = !fill;
      t.setAttributeNS(null, "class", (fill ? "fill" : ""));
      DrawSVG();
    }
  
    // start drag
    if (!drag && typeof(point[id]) != "undefined" && (et == "mousedown" || et == "touchstart")) {
      drag = t;
      dPoint = m;
    }
    
    // drag
    if (drag && (et == "mousemove" || et == "touchmove")) {
      id = drag.id;
      point[id].x += m.x - dPoint.x;
      point[id].y += m.y - dPoint.y;
      dPoint = m;
      drag.setAttributeNS(null, "cx", point[id].x);
      drag.setAttributeNS(null, "cy", point[id].y);
      DrawSVG();
    }
    
    // stop drag
    if (drag && (et == "mouseup" || et == "touchend")) {
      drag = null;
    }
  
  }

  
  // mouse position
  function MousePos(event) {
    return {
      x: Math.max(0, Math.min(maxX, event.pageX)),
      y: Math.max(0, Math.min(maxY, event.pageY))
    }
  }
  
  
  // start
  document.addEventListener('DOMContentLoaded', function() {
    container = document.getElementById("container");
    if (container) {
      cType = container.className;
      maxX = container.offsetWidth-1;
      maxY = container.offsetHeight-1;
      svg = document.getElementById("svg");
      Init();
    }
  });
  
})();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.