diff --git a/.eslintignore b/.eslintignore
index 6804aa2019b8..b8daf1c6063d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,6 +1,7 @@
# We can probably lint these later but not important at this point
src/renderers/art
src/__mocks__/vendor
+packages/react-art/lib
# But not in docs/_js/examples/*
docs/_js/*.js
docs/js/
diff --git a/fixtures/art/VectorWidget.js b/fixtures/art/VectorWidget.js
index 9c20ed3de269..6b317aaa01f6 100644
--- a/fixtures/art/VectorWidget.js
+++ b/fixtures/art/VectorWidget.js
@@ -8,6 +8,7 @@
*/
'use strict';
+var Circle = require('react-art/lib/Circle.art');
var React = require('react');
var ReactART = require('react-art');
var Group = ReactART.Group;
@@ -93,7 +94,9 @@ class VectorWidget extends React.Component {
-
+
+
+
+ *
+ */
+
+var PropTypes = require('prop-types');
+var React = require('react');
+var ReactART = require('..');
+
+var createReactClass = require('create-react-class');
+
+var Path = ReactART.Path;
+var Shape = ReactART.Shape;
+
+/**
+ * Circle is a React component for drawing circles. Like other ReactART
+ * components, it must be used in a .
+ */
+var Circle = createReactClass({
+ displayName: 'Circle',
+
+ propTypes: {
+ radius: PropTypes.number.isRequired
+ },
+
+ render: function render() {
+ var radius = this.props.radius;
+
+ var path = Path().moveTo(0, -radius).arc(0, radius * 2, radius).arc(0, radius * -2, radius).close();
+ return React.createElement(Shape, _extends({}, this.props, { d: path }));
+ }
+});
+
+module.exports = Circle;
diff --git a/packages/react-art/lib/Rectangle.art.js b/packages/react-art/lib/Rectangle.art.js
new file mode 100644
index 000000000000..c82e4c51eed8
--- /dev/null
+++ b/packages/react-art/lib/Rectangle.art.js
@@ -0,0 +1,138 @@
+'use strict';
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+/**
+ * Copyright (c) 2013-present Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @providesModule Rectangle.art
+ * @typechecks
+ *
+ * Example usage:
+ *
+ *
+ * Additional optional properties:
+ * (Number) radius
+ * (Number) radiusTopLeft
+ * (Number) radiusTopRight
+ * (Number) radiusBottomLeft
+ * (Number) radiusBottomRight
+ *
+ */
+
+var PropTypes = require('prop-types');
+var React = require('react');
+var ReactART = require('..');
+
+var createReactClass = require('create-react-class');
+
+var Shape = ReactART.Shape;
+var Path = ReactART.Path;
+
+/**
+ * Rectangle is a React component for drawing rectangles. Like other ReactART
+ * components, it must be used in a .
+ */
+var Rectangle = createReactClass({
+ displayName: 'Rectangle',
+
+ propTypes: {
+ width: PropTypes.number.isRequired,
+ height: PropTypes.number.isRequired,
+ radius: PropTypes.number,
+ radiusTopLeft: PropTypes.number,
+ radiusTopRight: PropTypes.number,
+ radiusBottomRight: PropTypes.number,
+ radiusBottomLeft: PropTypes.number
+ },
+
+ render: function render() {
+ var width = this.props.width;
+ var height = this.props.height;
+ var radius = this.props.radius ? this.props.radius : 0;
+
+ // if unspecified, radius(Top|Bottom)(Left|Right) defaults to the radius
+ // property
+ var tl = this.props.radiusTopLeft ? this.props.radiusTopLeft : radius;
+ var tr = this.props.radiusTopRight ? this.props.radiusTopRight : radius;
+ var br = this.props.radiusBottomRight ? this.props.radiusBottomRight : radius;
+ var bl = this.props.radiusBottomLeft ? this.props.radiusBottomLeft : radius;
+
+ var path = Path();
+
+ // for negative width/height, offset the rectangle in the negative x/y
+ // direction. for negative radius, just default to 0.
+ if (width < 0) {
+ path.move(width, 0);
+ width = -width;
+ }
+ if (height < 0) {
+ path.move(0, height);
+ height = -height;
+ }
+ if (tl < 0) {
+ tl = 0;
+ }
+ if (tr < 0) {
+ tr = 0;
+ }
+ if (br < 0) {
+ br = 0;
+ }
+ if (bl < 0) {
+ bl = 0;
+ }
+
+ // disable border radius if it doesn't fit within the specified
+ // width/height
+ if (tl + tr > width) {
+ tl = 0;tr = 0;
+ }
+ if (bl + br > width) {
+ bl = 0;br = 0;
+ }
+ if (tl + bl > height) {
+ tl = 0;bl = 0;
+ }
+ if (tr + br > height) {
+ tr = 0;br = 0;
+ }
+
+ path.move(0, tl);
+
+ if (tl > 0) {
+ path.arc(tl, -tl);
+ }
+ path.line(width - (tr + tl), 0);
+
+ if (tr > 0) {
+ path.arc(tr, tr);
+ }
+ path.line(0, height - (tr + br));
+
+ if (br > 0) {
+ path.arc(-br, br);
+ }
+ path.line(-width + (br + bl), 0);
+
+ if (bl > 0) {
+ path.arc(-bl, -bl);
+ }
+ path.line(0, -height + (bl + tl));
+
+ return React.createElement(Shape, _extends({}, this.props, { d: path }));
+ }
+
+});
+
+module.exports = Rectangle;
diff --git a/packages/react-art/lib/Wedge.art.js b/packages/react-art/lib/Wedge.art.js
new file mode 100644
index 000000000000..d1179d37a7bb
--- /dev/null
+++ b/packages/react-art/lib/Wedge.art.js
@@ -0,0 +1,188 @@
+'use strict';
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+/**
+ * Copyright (c) 2013-present Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @providesModule Wedge.art
+ * @typechecks
+ *
+ * Example usage:
+ *
+ *
+ * Additional optional property:
+ * (Int) innerRadius
+ *
+ */
+
+var PropTypes = require('prop-types');
+var React = require('react');
+var ReactART = require('..');
+
+var createReactClass = require('create-react-class');
+
+var Shape = ReactART.Shape;
+var Path = ReactART.Path;
+
+/**
+ * Wedge is a React component for drawing circles, wedges and arcs. Like other
+ * ReactART components, it must be used in a .
+ */
+var Wedge = createReactClass({
+ displayName: 'Wedge',
+
+
+ propTypes: {
+ outerRadius: PropTypes.number.isRequired,
+ startAngle: PropTypes.number.isRequired,
+ endAngle: PropTypes.number.isRequired,
+ innerRadius: PropTypes.number
+ },
+
+ circleRadians: Math.PI * 2,
+
+ radiansPerDegree: Math.PI / 180,
+
+ /**
+ * _degreesToRadians(degrees)
+ *
+ * Helper function to convert degrees to radians
+ *
+ * @param {number} degrees
+ * @return {number}
+ */
+ _degreesToRadians: function _degreesToRadians(degrees) {
+ if (degrees !== 0 && degrees % 360 === 0) {
+ // 360, 720, etc.
+ return this.circleRadians;
+ } else {
+ return degrees * this.radiansPerDegree % this.circleRadians;
+ }
+ },
+
+ /**
+ * _createCirclePath(or, ir)
+ *
+ * Creates the ReactART Path for a complete circle.
+ *
+ * @param {number} or The outer radius of the circle
+ * @param {number} ir The inner radius, greater than zero for a ring
+ * @return {object}
+ */
+ _createCirclePath: function _createCirclePath(or, ir) {
+ var path = Path();
+
+ path.move(0, or).arc(or * 2, 0, or).arc(-or * 2, 0, or);
+
+ if (ir) {
+ path.move(or - ir, 0).counterArc(ir * 2, 0, ir).counterArc(-ir * 2, 0, ir);
+ }
+
+ path.close();
+
+ return path;
+ },
+
+ /**
+ * _createArcPath(sa, ea, ca, or, ir)
+ *
+ * Creates the ReactART Path for an arc or wedge.
+ *
+ * @param {number} startAngle The starting degrees relative to 12 o'clock
+ * @param {number} endAngle The ending degrees relative to 12 o'clock
+ * @param {number} or The outer radius in pixels
+ * @param {number} ir The inner radius in pixels, greater than zero for an arc
+ * @return {object}
+ */
+ _createArcPath: function _createArcPath(startAngle, endAngle, or, ir) {
+ var path = Path();
+
+ // angles in radians
+ var sa = this._degreesToRadians(startAngle);
+ var ea = this._degreesToRadians(endAngle);
+
+ // central arc angle in radians
+ var ca = sa > ea ? this.circleRadians - sa + ea : ea - sa;
+
+ // cached sine and cosine values
+ var ss = Math.sin(sa);
+ var es = Math.sin(ea);
+ var sc = Math.cos(sa);
+ var ec = Math.cos(ea);
+
+ // cached differences
+ var ds = es - ss;
+ var dc = ec - sc;
+ var dr = ir - or;
+
+ // if the angle is over pi radians (180 degrees)
+ // we will need to let the drawing method know.
+ var large = ca > Math.PI;
+
+ // TODO (sema) Please improve theses comments to make the math
+ // more understandable.
+ //
+ // Formula for a point on a circle at a specific angle with a center
+ // at (0, 0):
+ // x = radius * Math.sin(radians)
+ // y = radius * Math.cos(radians)
+ //
+ // For our starting point, we offset the formula using the outer
+ // radius because our origin is at (top, left).
+ // In typical web layout fashion, we are drawing in quadrant IV
+ // (a.k.a. Southeast) where x is positive and y is negative.
+ //
+ // The arguments for path.arc and path.counterArc used below are:
+ // (endX, endY, radiusX, radiusY, largeAngle)
+
+ path.move(or + or * ss, or - or * sc) // move to starting point
+ .arc(or * ds, or * -dc, or, or, large) // outer arc
+ .line(dr * es, dr * -ec); // width of arc or wedge
+
+ if (ir) {
+ path.counterArc(ir * -ds, ir * dc, ir, ir, large); // inner arc
+ }
+
+ return path;
+ },
+
+ render: function render() {
+ // angles are provided in degrees
+ var startAngle = this.props.startAngle;
+ var endAngle = this.props.endAngle;
+ if (startAngle - endAngle === 0) {
+ return;
+ }
+
+ // radii are provided in pixels
+ var innerRadius = this.props.innerRadius || 0;
+ var outerRadius = this.props.outerRadius;
+
+ // sorted radii
+ var ir = Math.min(innerRadius, outerRadius);
+ var or = Math.max(innerRadius, outerRadius);
+
+ var path;
+ if (endAngle >= startAngle + 360) {
+ path = this._createCirclePath(or, ir);
+ } else {
+ path = this._createArcPath(startAngle, endAngle, or, ir);
+ }
+
+ return React.createElement(Shape, _extends({}, this.props, { d: path }));
+ }
+
+});
+
+module.exports = Wedge;
diff --git a/packages/react-art/package.json b/packages/react-art/package.json
index 27b990809585..2fba92140710 100644
--- a/packages/react-art/package.json
+++ b/packages/react-art/package.json
@@ -18,9 +18,11 @@
},
"homepage": "https://facebook.github.io/react/",
"dependencies": {
+ "create-react-class": "^15.6.0",
"fbjs": "^0.8.9",
"loose-envify": "^1.1.0",
- "object-assign": "^4.1.0"
+ "object-assign": "^4.1.0",
+ "prop-types": "^15.5.6"
},
"peerDependencies": {
"react": "^16.0.0-beta.5"