svg-arc-corners
Version:
SVG arc path with rounded corners
118 lines (95 loc) • 4.8 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cornerArc = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var RAD_DEG = Math.PI / 180.0;
var PI2 = 2 * Math.PI;
/**
* @param {Array.<Number>} center
* @param {Number} R
* @param {Number} angle
* @return {Array.<Number>}
*/
var pointOnArc = function pointOnArc(center, R, angle) {
var radians = (angle - 90) * RAD_DEG;
return [center[0] + R * Math.cos(radians), center[1] + R * Math.sin(radians)];
};
/**
* @param {Array.<Number>} center
* @param {Number} R
* @param {Number} width
* @return {String}
*/
var drawCircle = function drawCircle(center, R, width) {
var innerR = R - width;
var _center = _slicedToArray(center, 2);
var x = _center[0];
var y = _center[1];
return ['M', x - R, y, 'A', R, R, 0, 1, 0, x + R, y, 'A', R, R, 0, 1, 0, x - R, y, 'M', x - innerR, y, 'A', innerR, innerR, 0, 1, 0, x + innerR, y, 'A', innerR, innerR, 0, 1, 0, x - innerR, y, 'Z'];
};
/**
* Generates arc path
*
* @param {Array.<Number>} center
* @param {Number} R
* @param {Number} start
* @param {Number} end
* @param {Number} w
* @param {Number} corner Corner radius
* @param {Booelan=} returnPoints - return array for path or string
*
* @return {String|Array.<Number|String>}
*/
var arc = function arc(center, R, start, end, w, corner, returnPoints) {
var points = void 0;
if (Math.abs(end - start) === 360) {
points = drawCircle(center, R, w);
return returnPoints ? points : points.join(' ');
}
var innerR = R - w;
var circumference = Math.abs(end - start);
corner = Math.min(w / 2, corner);
if (360 * (corner / (Math.PI * (R - w))) > Math.abs(start - end)) {
corner = circumference / 360 * innerR * Math.PI;
}
// inner and outer radiuses
var innerR2 = innerR + corner;
var outerRadius = R - corner;
// butts corner points
var oStart = pointOnArc(center, outerRadius, start);
var oEnd = pointOnArc(center, outerRadius, end);
var iStart = pointOnArc(center, innerR2, start);
var iEnd = pointOnArc(center, innerR2, end);
var iSection = 360 * (corner / (PI2 * innerR));
var oSection = 360 * (corner / (PI2 * R));
// arcs endpoints
var iArcStart = pointOnArc(center, innerR, start + iSection);
var iArcEnd = pointOnArc(center, innerR, end - iSection);
var oArcStart = pointOnArc(center, R, start + oSection);
var oArcEnd = pointOnArc(center, R, end - oSection);
var arcSweep1 = circumference > 180 + 2 * oSection ? 1 : 0;
var arcSweep2 = circumference > 180 + 2 * iSection ? 1 : 0;
points = [
// begin path
"M", oStart[0], oStart[1],
// outer start corner
"A", corner, corner, 0, 0, 1, oArcStart[0], oArcStart[1],
// outer main arc
"A", R, R, 0, arcSweep1, 1, oArcEnd[0], oArcEnd[1],
// outer end corner
"A", corner, corner, 0, 0, 1, oEnd[0], oEnd[1],
// end butt
"L", iEnd[0], iEnd[1],
// inner end corner
"A", corner, corner, 0, 0, 1, iArcEnd[0], iArcEnd[1],
// inner arc
"A", innerR, innerR, 0, arcSweep2, 0, iArcStart[0], iArcStart[1],
// inner start corner
"A", corner, corner, 0, 0, 1, iStart[0], iStart[1], "Z" // end path
];
return returnPoints ? points : points.join(' ');
};
module.exports = arc;
module.exports.pointOnArc = pointOnArc;
module.exports.drawCircle = drawCircle;
},{}]},{},[1])(1)
});