rounded triangle

by Steve Eberhardt

HTML

<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.js"></script>
<script src="https://unpkg.com/[email protected]/dist/fabric.js"></script>

<canvas id="c" width="600" height="400"></canvas>

CSS

canvas {
    border: 1px solid #999;
}

JavaScript

fabric.Roundedtriangle = fabric.util.createClass(fabric.Object, {
  type: 'roundedtriangle',
  width: 100,
  height: 100,
  radius: 0,
  _render: function(ctx) {
    var widthBy2 = this.width / 2,
      heightBy2 = this.height / 2;

    ctx.beginPath();
    this._roundedPoly(ctx, [{
        x: -widthBy2,
        y: heightBy2
      },
      {
        x: 0,
        y: -heightBy2
      },
      {
        x: widthBy2,
        y: heightBy2
      },
    ], this.radius);

    this._renderPaintInOrder(ctx);
  },
  _roundedPoly: function(ctx, points, radiusAll) {
  	/*rounded rectangle solution by Blindman67 - https://stackoverflow.com/a/44856925/7693185*/
    var i, x, y, len, p1, p2, p3, v1, v2, sinA, sinA90, radDirection, drawDirection, angle, halfAngle, cRadius, lenOut, radius;
    // convert 2 points into vector form, polar form, and normalised 
    var asVec = function(p, pp, v) {
      v.x = pp.x - p.x;
      v.y = pp.y - p.y;
      v.len = Math.sqrt(v.x * v.x + v.y * v.y);
      v.nx = v.x / v.len;
      v.ny = v.y / v.len;
      v.ang = Math.atan2(v.ny, v.nx);
    }
    radius = radiusAll;
    v1 = {};
    v2 = {};
    len = points.length;
    p1 = points[len - 1];
    // for each point
    for (i = 0; i < len; i++) {
      p2 = points[(i) % len];
      p3 = points[(i + 1) % len];
      //-----------------------------------------
      // Part 1
      asVec(p2, p1, v1);
      asVec(p2, p3, v2);
      sinA = v1.nx * v2.ny - v1.ny * v2.nx;
      sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny;
      angle = Math.asin(sinA < -1 ? -1 : sinA > 1 ? 1 : sinA);
      //-----------------------------------------
      radDirection = 1;
      drawDirection = false;
      if (sinA90 < 0) {
        if (angle < 0) {
          angle = Math.PI + angle;
        } else {
          angle = Math.PI - angle;
          radDirection = -1;
          drawDirection = true;
        }
      } else {
        if (angle > 0) {
          radDirection = -1;
          drawDirection = true;
        }
    ...