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;
}
...