Skip to content

Instantly share code, notes, and snippets.

@hongymagic
Created February 25, 2015 04:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hongymagic/4193fb7311e931a2d5c5 to your computer and use it in GitHub Desktop.
Save hongymagic/4193fb7311e931a2d5c5 to your computer and use it in GitHub Desktop.
React.js svg rounded (soft edged) line
var React = require('react/addons');
//
// Shortcut method to describe svg <circle> element.
function circle(cx, cy, r, fill) {
return {
cx: cx,
cy: cy,
r: r,
fill: fill
};
}
//
// Determine if the rounding rule covers the given side.
function covers(rounding, side) {
if (rounding === 'both') {
return true;
}
if (rounding === 'none') {
return false;
}
return rounding === side;
}
//
// Draw a line with rounded edges.
//
// <RoundedLine x1 x2 y1 y2 rounding fill stroke strokeWidth />
//
// rounding attribute determines the rounded edge pattern:
// none, left, right, both
//
var RoundedLine = React.createClass({
propTypes: {
x1: React.PropTypes.number,
y1: React.PropTypes.number,
x2: React.PropTypes.number,
y2: React.PropTypes.number,
fill: React.PropTypes.string,
stroke: React.PropTypes.string,
strokeWidth: React.PropTypes.number,
rounding: React.PropTypes.oneOf([
'none',
'left',
'right',
'both'
])
},
getDefaultProps: function () {
return {
x1: 0, y1: 0,
x2: 100, y1: 100,
fill: 'none',
stroke: '#000', strokeWidth: 5,
rounding: 'both'
};
},
renderCircle: function (side, desc) {
return covers(this.props.rounding, side) ?
<circle {...desc} /> :
null;
},
render: function () {
var p = this.props;
var r = p.strokeWidth / 2;
// Need to recalculate endpoints as circle takes some space on either
// side of the line:
//
// (=================) as opposed to
// ===================
// ^ ^
// extra space if we use raw end points.
if (p.x1 > p.x2) {
p.x1 -= covers(p.rounding, 'right') ? r : 0;
p.x2 += covers(p.rounding, 'left') ? r : 0;
} else if (p.x2 > p.x1) {
p.x1 += covers(p.rounding, 'left') ? r : 0;
p.x2 -= covers(p.rounding, 'right') ? r : 0;
}
// Definitions for two end points (circles) which define rounded edges.
var c1 = circle(p.x1, p.y1, r, p.stroke);
var c2 = circle(p.x2, p.y2, r, p.stroke);
return (
<g className='rounded-line'>
{this.renderCircle('left', c1)}
<line {...p} />
{this.renderCircle('right', c2)}
</g>
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment