├── .gitignore
├── .babelrc
├── src
├── index.js
├── elements.js
└── utils.js
├── lib
├── index.js
├── utils.js
└── elements.js
├── .eslintrc.json
├── LICENSE
├── package.json
├── images
└── snapshot.svg
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ['es2015', 'stage-2', 'react']
3 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const Raphael = require("raphael");
2 | const Utils = require("./utils");
3 |
4 | const {
5 | Paper,
6 | Set,
7 | Circle,
8 | Ellipse,
9 | Image,
10 | Path,
11 | Print,
12 | Rect,
13 | Text,
14 | Line,
15 | Element
16 | } = require("./elements");
17 |
18 | exports.Raphael = Raphael;
19 | exports.Utils = Utils;
20 | exports.Paper = Paper;
21 | exports.Set = Set;
22 | exports.Element = Element;
23 | exports.Circle = Circle;
24 | exports.Ellipse = Ellipse;
25 | exports.Image = Image;
26 | exports.Path = Path;
27 | exports.Print = Print;
28 | exports.Rect = Rect;
29 | exports.Text = Text;
30 | exports.Line = Line;
31 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var Raphael = require("raphael");
4 | var Utils = require("./utils");
5 |
6 | var _require = require("./elements"),
7 | Paper = _require.Paper,
8 | Set = _require.Set,
9 | Circle = _require.Circle,
10 | Ellipse = _require.Ellipse,
11 | Image = _require.Image,
12 | Path = _require.Path,
13 | Print = _require.Print,
14 | Rect = _require.Rect,
15 | Text = _require.Text,
16 | Line = _require.Line,
17 | Element = _require.Element;
18 |
19 | exports.Raphael = Raphael;
20 | exports.Utils = Utils;
21 | exports.Paper = Paper;
22 | exports.Set = Set;
23 | exports.Element = Element;
24 | exports.Circle = Circle;
25 | exports.Ellipse = Ellipse;
26 | exports.Image = Image;
27 | exports.Path = Path;
28 | exports.Print = Print;
29 | exports.Rect = Rect;
30 | exports.Text = Text;
31 | exports.Line = Line;
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "commonjs": true,
5 | "es6": true
6 | },
7 | "extends": ["airbnb", "eslint:recommended"],
8 | "installedESLint": true,
9 | "parserOptions": {
10 | "ecmaFeatures": {
11 | "experimentalObjectRestSpread": true,
12 | "jsx": true
13 | },
14 | "sourceType": "module"
15 | },
16 | "plugins": [
17 | "react"
18 | ],
19 | "rules": {
20 | "import/no-extraneous-dependencies": 1,
21 | "no-case-declarations": 1,
22 | "react/no-did-mount-set-state": 1,
23 | "react/no-string-refs": 1,
24 | "react/no-find-dom-node": 0,
25 | "react/prop-types": 0,
26 | "react/no-multi-comp": 0,
27 | "react/no-unused-prop-types": 1,
28 | "react/jsx-filename-extension": 0,
29 | "react/forbid-prop-types": 0,
30 | "indent": [
31 | "error",
32 | 4
33 | ],
34 | "linebreak-style": [
35 | "error",
36 | "unix"
37 | ],
38 | "quotes": [
39 | "error",
40 | "double"
41 | ],
42 | "semi": [
43 | "error",
44 | "always"
45 | ]
46 | }
47 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 刘红
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-raphael",
3 | "version": "0.9.0",
4 | "description": "reactify raphael",
5 | "main": "./lib",
6 | "files": [
7 | "lib"
8 | ],
9 | "scripts": {
10 | "test": "test",
11 | "clean": "rm -rf ./lib",
12 | "build": "npm run clean & NODE_ENV=production babel ./src --out-dir ./lib"
13 | },
14 | "devDependencies": {
15 | "babel-cli": "^6.24.1",
16 | "babel-loader": "^7.1.0",
17 | "babel-preset-es2015": "^6.24.1",
18 | "babel-preset-react": "^6.24.1",
19 | "babel-preset-stage-2": "^6.24.1",
20 | "eslint": "^3.13.1",
21 | "eslint-config-airbnb": "^14.0.0",
22 | "eslint-plugin-import": "^2.2.0",
23 | "eslint-plugin-jsx-a11y": "^3.0.2",
24 | "eslint-plugin-react": "^6.9.0",
25 | "prop-types": "^15.5.10",
26 | "raphael": "^2.2.6",
27 | "react": "^15.6.1",
28 | "react-dom": "^15.6.1"
29 | },
30 | "repository": {
31 | "type": "git",
32 | "url": "git+https://github.com/liuhong1happy/react-raphael.git"
33 | },
34 | "keywords": [
35 | "react",
36 | "raphael",
37 | "react-raphael",
38 | "react-component"
39 | ],
40 | "author": "Holly Liu",
41 | "license": "MIT",
42 | "bugs": {
43 | "url": "https://github.com/liuhong1happy/react-raphael/issues"
44 | },
45 | "homepage": "https://github.com/liuhong1happy/react-raphael#readme"
46 | }
47 |
--------------------------------------------------------------------------------
/images/snapshot.svg:
--------------------------------------------------------------------------------
1 | Created with Raphaël 2.2.0 同一个世界 同一个梦想 One World One Dream
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-raphael
2 |
3 | [](https://www.npmjs.com/package/react-raphael)
4 | [](https://www.npmjs.com/package/react-raphael)
5 |
6 | reactify raphael
7 |
8 | ## Install
9 |
10 | # or specify the externals in webpack config
11 | npm install --save raphael
12 | # install react-raphael in your react-raphael project
13 | npm install --save react-raphael
14 |
15 | ## Example
16 |
17 | - [react-raphael-example](https://github.com/liuhong1happy/react-raphael-example)
18 | - [react-raphael-map](https://github.com/liuhong1happy/react-raphael-map)
19 | - [react-raphael-chart](https://github.com/liuhong1happy/react-raphael-chart)
20 | - [react-raphael-workflow](https://github.com/liuhong1happy/react-raphael-workflow)
21 | - [react-raphael-scrawl](https://github.com/liuhong1happy/react-raphael-scrawl)
22 | - [react-raphael-mine-sweeping](https://github.com/liuhong1happy/react-raphael-mine-sweeping)
23 |
24 | ## Quickly Start
25 |
26 | ```js
27 | var React = require('react');
28 | var ReactDOM = require('react-dom');
29 |
30 | const {Raphael,Paper,Set,Circle,Ellipse,Image,Rect,Text,Path,Line} = require('react-raphael');
31 |
32 | class App extends React.Component{
33 | render(){
34 | var data = [
35 | {x:50,y:50,r:40,attr:{"stroke":"#0b8ac9","stroke-width":5},animate:Raphael.animation({cx:60},500,"<>")},
36 | {x:100,y:100,r:40,attr:{"stroke":"#f0c620","stroke-width":5},animate:Raphael.animation({cx:105},500,"<>")},
37 | {x:150,y:50,r:40,attr:{"stroke":"#1a1a1a","stroke-width":5}},
38 | {x:200,y:100,r:40,attr:{"stroke":"#10a54a","stroke-width":5},animate:Raphael.animation({cx:195},500,"<>")},
39 | {x:250,y:50,r:40,attr:{"stroke":"#e11032","stroke-width":5},animate:Raphael.animation({cx:240},500,"<>")}
40 | ]
41 | return (
42 |
43 | {
44 | data.map(function(ele,pos){
45 | return ()
46 | })
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | ")} attr={{"stroke":"#fff"}}/>
56 | ")} attr={{"stroke":"#fff"}}/>
57 |
58 | )
59 | }
60 | }
61 | ```
62 |
63 | ## Snapshot
64 |
65 | 
66 |
67 | ## API
68 |
69 | #### All Element Props
70 |
71 | - Paper
72 | - width `number` width of the canvas.
73 | - height `number` height of the canvas.
74 | - container `object` props of the canvas's container.`default value: { style:{}, className:"" }`
75 | - Element
76 | - attr `object` Sets the attributes of the element.
77 | - animate `object` Creates and starts animation for given element.
78 | - animateWith `object` Acts similar to Element.animate, but ensure that given animation runs in sync with another given element.
79 | - click `function` Adds event handler for click for the element.
80 | - data `object` Adds or retrieves given value asociated with given key.
81 | - dblclick `function` Adds event handler for double click for the element.
82 | - drag `object` Adds event handlers for drag of the element. `object {move,start,end,mcontext,scontext,econtext}`
83 | - glow `function` Return set of elements that create glow-like effect around given element.
84 | - hover `object` Adds event handlers for hover for the element. `object {in,out,icontext,ocontext}`
85 | - hide `boolean` Makes element invisible.
86 | - mousedown `function` Adds event handler for mousedown for the element.
87 | - mousemove `function` Adds event handler for mousemove for the element.
88 | - mouseout `function` Adds event handler for mouseout for the element.
89 | - mouseover `function` Adds event handler for mouseover for the element.
90 | - mouseup `function` Adds event handler for mouseup for the element.
91 | - load `function` Adds event handler for load for the element.
92 | - rotate `object` Adds rotation by given angle around given point to the list of transformations of the element.
93 | - scale `object` Adds scale by given amount relative to given point to the list of transformations of the element.
94 | - stop `boolen` Stops animation for given element.
95 | - toBack `boolean` Moves the element so it is the furthest from the viewer’s eyes, behind other elements.
96 | - toFront `boolean` Moves the element so it is the closest to the viewer’s eyes, on top of other elements.
97 | - touchcancel `function` Adds event handler for touchcancel for the element.
98 | - touchend `function` Adds event handler for touchend for the element.
99 | - touchmove `function` Adds event handler for touchmove for the element.
100 | - touchstart `function` Adds event handler for touchstart for the element.
101 | - transform `string` or `array` Adds transformation to the element which is separate to other attributes, i.e. translation doesn’t change x or y of the rectange. The format of transformation string is similar to the path string syntax:`"t100,100r30,100,100s2,2,100,100r45s1.5"`
102 | - translate `object` Adds translation by given amount to the list of transformations of the element.
103 | - update `function` Adds event handler for update for the element.
104 | - Set `Extends Element & Container Elements`
105 | - Circle `Extends Element & Draws a circle`
106 | - x `number` x coordinate of the centre
107 | - y `number` y coordinate of the centre
108 | - r `number` radius
109 | - Ellipse `Extends Element & Draws a ellipse`
110 | - x `number` x coordinate of the centre
111 | - y `number` y coordinate of the centre
112 | - rx `number` horizontal radius
113 | - ry `number` vertical radius
114 | - Image `Extends Element & Embeds an image into the surface`
115 | - src `string` URI of the source image
116 | - x `number` x coordinate of the centre
117 | - y `number` y coordinate of the centre
118 | - width `number` width of the image
119 | - height `number` height of the image
120 | - Path `Extends Element & Creates a path element by given path data string`
121 | - d `string` path string in SVG format
122 | - Print `Extends Element & Creates set of shapes to represent given font at given position with given size`
123 | - x `number` x position of the text
124 | - y `number` y position of the text
125 | - text `string` text to print
126 | - font-family `string` family of font object
127 | - font-weight `string` weight of font object
128 | - font-style `string` style of font object
129 | - font-stretch `string` stretch of font object
130 | - font-size `number` size of the font, default is 16
131 | - origin `string` could be "baseline" or "middle", default is "middle"
132 | - letter-spacing `number` number in range -1..1, default is 0
133 | - Rect `Extends Element & Draws a circle`
134 | - x `number` x coordinate of the top left corner
135 | - y `number` y coordinate of the top left corner
136 | - width `number` width of the rect
137 | - height `number` height of the rect
138 | - r `number` radius for rounded corners, default is 0
139 | - Text `Extends Element & Draws a text string & If you need line breaks, put “\n” in the string`
140 | - x `number` x coordinate position
141 | - y `number` y coordinate position
142 | - text `string` The text string to draw
143 | - Line `Extends Path & Draws a line`
144 | - x1 `number` x coordinate of the start point
145 | - y1 `number` y coordinate of the start point
146 | - x2 `number` x coordinate of the end point
147 | - y2 `number` y coordinate of the end point
148 |
149 | #### All Element Ref Function
150 |
151 | - Paper
152 | - getPaper `function` paper of the component
153 | - Set
154 | - getSet `function` set of the component
155 | - Element
156 | - getElement `function` element of the component
157 |
158 | #### Raphael & Utils
159 |
160 | - Raphael `you can see ` [http://dmitrybaranovskiy.github.io/raphael/reference.html#Raphael](http://dmitrybaranovskiy.github.io/raphael/reference.html#Raphael)
161 | - Utils
162 | - createPaper `function` create a paper by `Raphael()`
163 | - updatePaper `function` update a paper
164 | - removePaper `function` remove a paper
165 | - create `function` create elements or a set by `paper.xxx`
166 | - createElement `function` call create to create a element
167 | - createSet `function` call create to create a set
168 | - updateElement `function` update elements or a set
169 | - removeSet `function` remove a set from paper
170 | - removeElement `function` remove a element from paper
171 | - papers `array` all paper instance
172 | - elements `array` all elements or set of the only paper instance
173 | - findParentById `function` find parent of element by id
174 |
175 | # Contact
176 |
177 | Email: [liuhong1.happy@163.com](mailto:liuhong1.happy@163.com)
--------------------------------------------------------------------------------
/src/elements.js:
--------------------------------------------------------------------------------
1 | const React = require("react");
2 | const ReactDOM = require("react-dom");
3 | const Utils = require("./utils");
4 |
5 | const PropTypes = require("prop-types");
6 |
7 | class Paper extends React.Component {
8 | constructor(props){
9 | super(props);
10 | this.state = {
11 | loaded: false
12 | };
13 | }
14 | componentDidMount(){
15 | const container = ReactDOM.findDOMNode(this.refs.container);
16 | const paper = Utils.createPaper(container,this.props);
17 | this.paper = paper;
18 | setTimeout(()=>{
19 | this.setState({
20 | loaded: true,
21 | id: paper.id
22 | });
23 | });
24 | }
25 | componentDidUpdate() {
26 | Utils.updatePaper(this.paper, this.props);
27 | }
28 | componentWillUnmount(){
29 | this.paper.remove();
30 | }
31 |
32 | getPaper(){
33 | return this.paper;
34 | }
35 | genElementsContainer(){
36 | if(this.state.loaded){
37 | return (
38 | {this.props.children}
39 |
);
40 | }else{
41 | return (
);
42 | }
43 | }
44 | render(){
45 | const eleContainer = this.genElementsContainer();
46 | const {style,className,...others} = this.props.container;
47 | return (
48 | {eleContainer}
49 |
50 |
);
51 | }
52 | }
53 | Paper.propTypes = {
54 | x: PropTypes.number,
55 | y: PropTypes.number,
56 | width: PropTypes.number,
57 | height: PropTypes.number,
58 | viewbox: PropTypes.string,
59 | container: PropTypes.object
60 | };
61 | Paper.defaultProps = { x:0, y: 0,width: 100, height: 100, container:{ style:{}, className:"" }, viewbox: "" };
62 |
63 | class Set extends React.Component{
64 | constructor(props){
65 | super(props);
66 | this.state = {
67 | loaded: false
68 | };
69 | }
70 | componentDidMount(){
71 | const root = ReactDOM.findDOMNode(this.refs.root);
72 | const parentId = root.parentElement.getAttribute("data-id");
73 | const set = Utils.createSet(parentId,this.props,this.handleLoad.bind(this));
74 | this.set = set;
75 | setTimeout(()=>{
76 | this.setState({
77 | loaded: true,
78 | id: set.id
79 | });
80 | });
81 | }
82 | getSet(){
83 | return this.set;
84 | }
85 | handleLoad(set){
86 | if(this.props.load){
87 | this.props.load(set);
88 | }
89 | }
90 | componentWillUnmout(){
91 | Utils.removeSet(this.set);
92 | }
93 | render(){
94 | if(this.state.loaded){
95 | return ({this.props.children}
);
96 | }else{
97 | return (
);
98 | }
99 | }
100 | }
101 |
102 | class Element extends React.Component{
103 | constructor(props){
104 | super(props);
105 | this.state = {
106 | loaded: false
107 | };
108 | }
109 | componentDidMount(){
110 | const root = ReactDOM.findDOMNode(this.refs.root);
111 | const parentId = root.parentElement.getAttribute("data-id");
112 | const element = Utils.createElement(parentId,this.props.type,this.props,this.handleLoad.bind(this));
113 | this.element = element;
114 | setTimeout(()=>{
115 | this.setState({
116 | loaded: true
117 | });
118 | });
119 | }
120 | componentDidUpdate(){
121 | Utils.updateElement(this.element,this.props.type,this.props,this.handleUpdate.bind(this));
122 | }
123 | componentWillUnmount(){
124 | Utils.removeElement(this.element);
125 | }
126 | getElement(){
127 | return this.element;
128 | }
129 | handleLoad(element){
130 | if(this.props.load){
131 | this.props.load(element);
132 | }
133 | }
134 | handleUpdate(element){
135 | if(this.props.update){
136 | this.props.update(element);
137 | }
138 | }
139 | render(){
140 | if(this.state.loaded) return null;
141 | return (
);
142 | }
143 | }
144 |
145 | Element.propTypes = {
146 | attr: PropTypes.object,
147 | animate: PropTypes.oneOfType([
148 | PropTypes.shape({
149 | anim: PropTypes.shape({
150 | transform: PropTypes.string
151 | }),
152 | ms: PropTypes.number,
153 | percents: PropTypes.array,
154 | times: PropTypes.number
155 | }),
156 | PropTypes.string
157 | ]),
158 | animateWith: PropTypes.object,
159 | click: PropTypes.func,
160 | data: PropTypes.object,
161 | dblclick: PropTypes.func,
162 | drag: PropTypes.object,
163 | glow: PropTypes.func,
164 | hover: PropTypes.object,
165 | hide: PropTypes.bool,
166 | mousedown: PropTypes.func,
167 | mousemove: PropTypes.func,
168 | mouseout: PropTypes.func,
169 | mouseover: PropTypes.func,
170 | mouseup: PropTypes.func,
171 | load: PropTypes.func,
172 | rotate: PropTypes.object,
173 | scale: PropTypes.object,
174 | stop: PropTypes.bool,
175 | toBack: PropTypes.bool,
176 | toFront: PropTypes.bool,
177 | touchcancel: PropTypes.func,
178 | touchend: PropTypes.func,
179 | touchmove: PropTypes.func,
180 | touchstart: PropTypes.func,
181 | transform: PropTypes.string,
182 | update: PropTypes.func,
183 | };
184 |
185 | class Circle extends React.Component{
186 | getElement() { return this.refs.element.getElement(); }
187 | render(){ return ( ); }
188 | }
189 | Circle.propTypes = {
190 | x: PropTypes.number,
191 | y: PropTypes.number,
192 | r: PropTypes.number,
193 | };
194 | Circle.defaultProps = { x: 0, y: 0,r: 10 };
195 |
196 | class Ellipse extends React.Component{
197 | getElement() { return this.refs.element.getElement(); }
198 | render(){ return ( ); }
199 | }
200 |
201 | Ellipse.propTypes = {
202 | x: PropTypes.number,
203 | y: PropTypes.number,
204 | rx: PropTypes.number,
205 | ry: PropTypes.number,
206 | };
207 | Ellipse.defaultProps = { x: 0, y: 0,rx: 10,ry: 20 };
208 |
209 | class Image extends React.Component{
210 | getElement() { return this.refs.element.getElement(); }
211 | render(){ return ( ); }
212 | }
213 | Image.propTypes = {
214 | x: PropTypes.number,
215 | y: PropTypes.number,
216 | src: PropTypes.string,
217 | width: PropTypes.number,
218 | height: PropTypes.number,
219 | };
220 | Image.defaultProps = { x: 0, y: 0, src: "", width: 0,height: 0 };
221 |
222 | class Path extends React.Component{
223 | getElement() { return this.refs.element.getElement(); }
224 | render(){ return ( ); }
225 | }
226 | Path.propTypes = {
227 | d: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
228 | };
229 | Path.defaultProps = { d: "M0,0L0,0Z" };
230 |
231 | class Rect extends React.Component{
232 | getElement() { return this.refs.element.getElement(); }
233 | render(){ return ( ); }
234 | }
235 | Rect.propTypes = {
236 | x: PropTypes.number,
237 | y: PropTypes.number,
238 | width: PropTypes.number,
239 | height: PropTypes.number,
240 | r: PropTypes.number,
241 | };
242 | Rect.defaultProps = { x: 0, y: 0, width: 0,height: 0, r: 0 };
243 |
244 | class Print extends React.Component{
245 | getElement() { return this.refs.element.getElement(); }
246 | render(){ return ( ); }
247 | }
248 | Print.propTypes = {
249 | x: PropTypes.number,
250 | y: PropTypes.number,
251 | text: PropTypes.string,
252 | fontFamily: PropTypes.string,
253 | };
254 | Print.defaultProps = { x: 0, y: 0, text: "", fontFamily: "Arial" };
255 |
256 | class Text extends React.Component{
257 | getElement() { return this.refs.element.getElement(); }
258 | render(){ return ( ); }
259 | }
260 | Text.propTypes = {
261 | x: PropTypes.number,
262 | y: PropTypes.number,
263 | text: PropTypes.string,
264 | };
265 | Text.defaultProps = { x: 0, y: 0, text: "" };
266 |
267 | class Line extends React.Component{
268 | getElement() { return this.refs.path.getElement(); }
269 | render(){
270 | const {x1,x2,y1,y2,animate,attr,...others} = this.props;
271 | if(animate){
272 | if(animate.anim){
273 | for(const key in animate.anim) {
274 | animate.anim[key].x1 = animate.anim[key].x1 || x1;
275 | animate.anim[key].x2 = animate.anim[key].x2 || x2;
276 | animate.anim[key].y1 = animate.anim[key].y1 || y1;
277 | animate.anim[key].y2 = animate.anim[key].y2 || y2;
278 | animate.anim[key].path = [ "M",animate.anim[key].x1,animate.anim[key].y1, "L",animate.anim[key].x2,animate.anim[key].y2 ];
279 | }
280 | }else{
281 | animate.x1 = animate.x1 || x1;
282 | animate.x2 = animate.x2 || x2;
283 | animate.y1 = animate.y1 || y1;
284 | animate.y2 = animate.y2 || y2;
285 | animate.path = [ "M",animate.x1,animate.y1, "L",animate.x2,animate.y2 ];
286 | }
287 | }
288 | if(attr){
289 | attr.x1 = attr.x1 || x1;
290 | attr.x2 = attr.x2 || x2;
291 | attr.y1 = attr.y1 || y1;
292 | attr.y2 = attr.y2 || y2;
293 | attr.path = [ "M",attr.x1,attr.y1, "L",attr.x2,attr.y2 ];
294 | }
295 | return ;
296 | }
297 | }
298 | Line.propTypes = {
299 | x1: PropTypes.number,
300 | y1: PropTypes.number,
301 | x2: PropTypes.number,
302 | y2: PropTypes.number,
303 | };
304 | Line.defaultProps = { x1: 0, y1: 0, x2: 0,y2: 0 };
305 |
306 | module.exports = {
307 | Paper: Paper,
308 | Set: Set,
309 | Element: Element,
310 | Circle: Circle,
311 | Ellipse: Ellipse,
312 | Image: Image,
313 | Path: Path,
314 | Print: Print,
315 | Rect: Rect,
316 | Text: Text,
317 | Line: Line
318 | };
319 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | const Raphael = require("raphael");
2 |
3 | const Utils = {
4 | createPaper:function(container,props){
5 | const { width,height } = props;
6 | const paper = Raphael(container,width,height);
7 | if(props.viewbox) {
8 | const v = props.viewbox.split(" ");
9 | paper.setViewBox(v[0] || 0, v[1] || 0, v[2] || 0, v[3] || 3, true);
10 | }
11 | paper.id = container.id || ("paper-" + new Date().valueOf() +"-"+ Math.random().toFixed(10));
12 | Utils.papers.push(paper);
13 | return paper;
14 | },
15 | findParentById: function(id){
16 | const papers = Utils.papers.filter(function(ele){
17 | return ele.id == id;
18 | });
19 | if(papers.length>0){
20 | return {
21 | parent: papers[0],
22 | paper: papers[0]
23 | };
24 | }else{
25 | const sets = Utils.elements.filter(function(ele){
26 | return ele.element.id == id;
27 | });
28 | if(sets.length>0){
29 | if(!sets[0].element) return sets[0].element;
30 | return {
31 | parent: sets[0].element,
32 | paper: sets[0].element.paper
33 | };
34 | }
35 | }
36 | return {
37 | parent: null,
38 | paper: null
39 | };
40 | },
41 | create:function(parentId,type,props){
42 | let element = null;
43 | const findedParent = Utils.findParentById(parentId);
44 | if(!findedParent.paper) return findedParent.paper;
45 | switch(type){
46 | case "set":{
47 | element = findedParent.paper.set();
48 | element.id = "set-" + new Date().valueOf() +"-"+ Math.random().toFixed(10);
49 | break;
50 | }
51 | case "circle":{
52 | const {x,y,r} = props;
53 | element = findedParent.paper.circle(x,y,r);
54 | break;
55 | }
56 | case "ellipse":{
57 | const {x, y, rx, ry} = props;
58 | element = findedParent.paper.ellipse(x, y, rx, ry);
59 | break;
60 | }
61 | case "image":{
62 | const {src, x, y, width, height} = props;
63 | element = findedParent.paper.image(src, x, y, width, height);
64 | break;
65 | }
66 | case "path":{
67 | let {d} = props;
68 | if(!d || d.length==0) d="M0,0L0,0Z";
69 | element = findedParent.paper.path(d);
70 | break;
71 | }
72 | case "print":{
73 | const {x, y, text, fontFamily,fontWeight,fontStyle,fontStretch,fontSize,letterSpacing} = props;
74 | const font = findedParent.paper.getFont(fontFamily,fontWeight,fontStyle,fontStretch);
75 | element = findedParent.paper.print(x, y, text,font,fontSize,letterSpacing);
76 | break;
77 | }
78 | case "rect":{
79 | let {x, y, width, height, r} = props;
80 | element = findedParent.paper.rect(x, y, width, height, r);
81 | break;
82 | }
83 | case "text":{
84 | const {x, y, text} = props;
85 | element = findedParent.paper.text(x, y, text);
86 | break;
87 | }
88 | default: break;
89 | }
90 |
91 | if(element){
92 | if(findedParent.parent.type=="set"){
93 | element.set = findedParent.parent;
94 | findedParent.parent.push(element);
95 | }
96 | }
97 | Utils.updateElementProps(element,props);
98 | return element;
99 | },
100 | createElement:function(parentId,type,props,callback){
101 | const element = Utils.create(parentId,type,props);
102 | Utils.elements.push({
103 | type: type,
104 | props: props,
105 | callback: callback,
106 | element: element
107 | });
108 | if(callback) callback(element);
109 | return element;
110 | },
111 | createSet:function(parentId,props,callback){
112 | const set = Utils.create(parentId,"set",props);
113 | Utils.elements.push({
114 | type: "set",
115 | element: set
116 | });
117 | if(callback) callback(set);
118 | return set;
119 | },
120 | updatePaper: function(paper,props){
121 | const {width,height} = props;
122 | paper.setSize(width, height);
123 | },
124 | updateElementProps: function(element,props){
125 | if(element){
126 | // fix matrix bug
127 | element.matrix = Raphael.matrix();
128 | element.attr("transform","");
129 | for(const key in props){
130 | switch(key){
131 | case "attr":{
132 | if(typeof props[key] ==="object") element.attr(props.attr);
133 | break;
134 | }
135 | case "animate":{
136 | if(typeof props[key] ==="object") element.animate(props.animate);
137 | break;
138 | }
139 | case "animateWith":{
140 | if(typeof props[key] ==="object") element.animateWith(props.animateWith);
141 | break;
142 | }
143 | case "click": {
144 | if(typeof props[key] ==="function") {element.unclick();element.click(props.click);}
145 | break;
146 | }
147 | case "data": {
148 | if(typeof props[key] ==="object") {
149 | for(const key in props.data)
150 | element.data(key,props.data[key]);
151 | element.items = props.data;
152 | }
153 | break;
154 | }
155 | case "dblclick": {
156 | if(typeof props[key] ==="function") {element.undblclick();element.dblclick(props.dblclick);}
157 | break;
158 | }
159 | case "drag": {
160 | if(typeof props[key] ==="object") {
161 | element.undrag();
162 | element.drag(props.drag.move, props.drag.start, props.drag.end, props.drag.mcontext, props.drag.scontext, props.drag.econtext );
163 | }
164 | break;
165 | }
166 | case "glow": {
167 | if(typeof props[key] ==="object") element.glow(props.glow);
168 | break;
169 | }
170 | case "hover": {
171 | if(typeof props[key] ==="object") {
172 | element.unhover();
173 | element.hover(props.hover.in, props.hover.out, props.hover.icontext, props.hover.ocontext);
174 | }
175 | break;
176 | }
177 | case "hide": {
178 | if(typeof props[key] ==="boolean") props.hide?element.hide():element.show();
179 | break;
180 | }
181 | case "mousedown": {
182 | if(typeof props[key] ==="function") {element.unmousedown();element.mousedown(props.mousedown);}
183 | break;
184 | }
185 | case "mousemove": {
186 | if(typeof props[key] ==="function") {element.unmousemove();element.mousemove(props.mousemove);}
187 | break;
188 | }
189 | case "mouseout": {
190 | if(typeof props[key] ==="function") {element.unmouseout();element.mouseout(props.mouseout);}
191 | break;
192 | }
193 | case "mouseover": {
194 | if(typeof props[key] ==="function") {element.unmouseover();element.mouseover(props.mouseover);}
195 | break;
196 | }
197 | case "mouseup":{
198 | if(typeof props[key] ==="function") {element.unmouseup();element.mouseup(props.mouseup);}
199 | break;
200 | }
201 | case "rotate":{
202 | if(typeof props[key] ==="object") { const {deg, cx, cy} = props.rotate; element.rotate(deg, cx, cy); }
203 | break;
204 | }
205 | case "scale":{
206 | if(typeof props[key] ==="object") { const {sx,sy,cx,cy} = props.scale; element.scale(sx,sy,cx,cy); }
207 | break;
208 | }
209 | case "stop":{
210 | if(typeof props[key] ==="boolean" && props.stop) { element.stop(); }
211 | break;
212 | }
213 | case "touchcancel":{
214 | if(typeof props[key] ==="function") {element.untouchcancel();element.touchcancel(props.touchcancel);}
215 | break;
216 | }
217 | case "touchend":{
218 | if(typeof props[key] ==="function") {element.untouchend();element.touchend(props.touchend);}
219 | break;
220 | }
221 | case "touchmove":{
222 | if(typeof props[key] ==="function") {element.untouchmove();element.touchmove(props.touchmove);}
223 | break;
224 | }
225 | case "touchstart":{
226 | if(typeof props[key] ==="function") {element.untouchstart();element.touchstart(props.touchstart);}
227 | break;
228 | }
229 | case "transform":{
230 | if(typeof props[key] ==="object") element.transform(props.transform);
231 | break;
232 | }
233 | case "translate":{
234 | if(typeof props[key] ==="object") element.translate(props.translate.x,props.translate.y);
235 | break;
236 | }
237 | }
238 | }
239 | // fix raphael #491
240 | if(Raphael.svg && element.node && element.node.nodeName=="text" && element.node.childNodes.length>0){
241 | setTimeout(function(){
242 | if(element.node){
243 | const nodeY = element.node.getAttribute("y");
244 | const childDy = element.node.childNodes[0].getAttribute("dy");
245 | if(nodeY == childDy){
246 | element.node.childNodes[0].setAttribute("dy",0);
247 | }
248 | }
249 | });
250 | }
251 | }
252 | },
253 | updateElement:function(element,type,props,callback){
254 | switch(type){
255 | case "circle":{
256 | const {x,y,r} = props;
257 | element.attr({cx:x,cy:y,r:r});
258 | break;
259 | }
260 | case "ellipse":{
261 | const {x, y, rx, ry} = props;
262 | element.attr({cx:x,cy:y,rx:rx,ry:ry});
263 | break;
264 | }
265 | case "image":{
266 | const {src, x, y, width, height} = props;
267 | element.attr({src, x, y, width, height});
268 | break;
269 | }
270 | case "path":{
271 | let {d} = props;
272 | if(!d || d.length==0) d="M0,0L0,0Z";
273 | element.attr({path:d});
274 | break;
275 | }
276 | case "print":{
277 | const {x,y,text,fontFamily,fontWeight,fontStyle,fontStretch,fontSize,letterSpacing} = props;
278 | element.attr({x,y,text,"font-style":fontStyle, "font-family":fontFamily,"font-size":fontSize,"font-weight": fontWeight,"font-stretch": fontStretch, "letter-scpacing": letterSpacing});
279 | break;
280 | }
281 | case "rect":{
282 | const {x, y, width, height, r} = props;
283 | element.attr({x, y, width, height, r});
284 | break;
285 | }
286 | case "text":{
287 | const {x, y, text} = props;
288 | element.attr({x, y, text});
289 | break;
290 | }
291 |
292 | }
293 | Utils.updateElementProps(element,props);
294 | if(callback) callback(element);
295 | return element;
296 | },
297 | removePaper: function(paper){
298 | const papers = Utils.papers.filter(function(ele){
299 | return ele === paper;
300 | });
301 | if(papers.length>0){
302 | papers[0].remove();
303 | }
304 | },
305 | removeSet:function(set){
306 | Utils.removeElement(set);
307 | },
308 | removeElement:function(element){
309 | const elements = Utils.elements.filter(function(ele){
310 | return ele.element === element;
311 | });
312 | if(elements.length>0){
313 | elements[0].element.remove();
314 | }
315 | },
316 | papers: [],
317 | elements: []
318 | };
319 |
320 | module.exports = Utils;
321 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4 |
5 | var Raphael = require("raphael");
6 |
7 | var Utils = {
8 | createPaper: function createPaper(container, props) {
9 | var width = props.width,
10 | height = props.height;
11 |
12 | var paper = Raphael(container, width, height);
13 | if (props.viewbox) {
14 | var v = props.viewbox.split(" ");
15 | paper.setViewBox(v[0] || 0, v[1] || 0, v[2] || 0, v[3] || 3, true);
16 | }
17 | paper.id = container.id || "paper-" + new Date().valueOf() + "-" + Math.random().toFixed(10);
18 | Utils.papers.push(paper);
19 | return paper;
20 | },
21 | findParentById: function findParentById(id) {
22 | var papers = Utils.papers.filter(function (ele) {
23 | return ele.id == id;
24 | });
25 | if (papers.length > 0) {
26 | return {
27 | parent: papers[0],
28 | paper: papers[0]
29 | };
30 | } else {
31 | var sets = Utils.elements.filter(function (ele) {
32 | return ele.element.id == id;
33 | });
34 | if (sets.length > 0) {
35 | if (!sets[0].element) return sets[0].element;
36 | return {
37 | parent: sets[0].element,
38 | paper: sets[0].element.paper
39 | };
40 | }
41 | }
42 | return {
43 | parent: null,
44 | paper: null
45 | };
46 | },
47 | create: function create(parentId, type, props) {
48 | var element = null;
49 | var findedParent = Utils.findParentById(parentId);
50 | if (!findedParent.paper) return findedParent.paper;
51 | switch (type) {
52 | case "set":
53 | {
54 | element = findedParent.paper.set();
55 | element.id = "set-" + new Date().valueOf() + "-" + Math.random().toFixed(10);
56 | break;
57 | }
58 | case "circle":
59 | {
60 | var x = props.x,
61 | y = props.y,
62 | r = props.r;
63 |
64 | element = findedParent.paper.circle(x, y, r);
65 | break;
66 | }
67 | case "ellipse":
68 | {
69 | var _x = props.x,
70 | _y = props.y,
71 | rx = props.rx,
72 | ry = props.ry;
73 |
74 | element = findedParent.paper.ellipse(_x, _y, rx, ry);
75 | break;
76 | }
77 | case "image":
78 | {
79 | var src = props.src,
80 | _x2 = props.x,
81 | _y2 = props.y,
82 | width = props.width,
83 | height = props.height;
84 |
85 | element = findedParent.paper.image(src, _x2, _y2, width, height);
86 | break;
87 | }
88 | case "path":
89 | {
90 | var d = props.d;
91 |
92 | if (!d || d.length == 0) d = "M0,0L0,0Z";
93 | element = findedParent.paper.path(d);
94 | break;
95 | }
96 | case "print":
97 | {
98 | var _x3 = props.x,
99 | _y3 = props.y,
100 | text = props.text,
101 | fontFamily = props.fontFamily,
102 | fontWeight = props.fontWeight,
103 | fontStyle = props.fontStyle,
104 | fontStretch = props.fontStretch,
105 | fontSize = props.fontSize,
106 | letterSpacing = props.letterSpacing;
107 |
108 | var font = findedParent.paper.getFont(fontFamily, fontWeight, fontStyle, fontStretch);
109 | element = findedParent.paper.print(_x3, _y3, text, font, fontSize, letterSpacing);
110 | break;
111 | }
112 | case "rect":
113 | {
114 | var _x4 = props.x,
115 | _y4 = props.y,
116 | _width = props.width,
117 | _height = props.height,
118 | _r = props.r;
119 |
120 | element = findedParent.paper.rect(_x4, _y4, _width, _height, _r);
121 | break;
122 | }
123 | case "text":
124 | {
125 | var _x5 = props.x,
126 | _y5 = props.y,
127 | _text = props.text;
128 |
129 | element = findedParent.paper.text(_x5, _y5, _text);
130 | break;
131 | }
132 | default:
133 | break;
134 | }
135 |
136 | if (element) {
137 | if (findedParent.parent.type == "set") {
138 | element.set = findedParent.parent;
139 | findedParent.parent.push(element);
140 | }
141 | }
142 | Utils.updateElementProps(element, props);
143 | return element;
144 | },
145 | createElement: function createElement(parentId, type, props, callback) {
146 | var element = Utils.create(parentId, type, props);
147 | Utils.elements.push({
148 | type: type,
149 | props: props,
150 | callback: callback,
151 | element: element
152 | });
153 | if (callback) callback(element);
154 | return element;
155 | },
156 | createSet: function createSet(parentId, props, callback) {
157 | var set = Utils.create(parentId, "set", props);
158 | Utils.elements.push({
159 | type: "set",
160 | element: set
161 | });
162 | if (callback) callback(set);
163 | return set;
164 | },
165 | updatePaper: function updatePaper(paper, props) {
166 | var width = props.width,
167 | height = props.height;
168 |
169 | paper.setSize(width, height);
170 | },
171 | updateElementProps: function updateElementProps(element, props) {
172 | if (element) {
173 | // fix matrix bug
174 | element.matrix = Raphael.matrix();
175 | element.attr("transform", "");
176 | for (var key in props) {
177 | switch (key) {
178 | case "attr":
179 | {
180 | if (_typeof(props[key]) === "object") element.attr(props.attr);
181 | break;
182 | }
183 | case "animate":
184 | {
185 | if (_typeof(props[key]) === "object") element.animate(props.animate);
186 | break;
187 | }
188 | case "animateWith":
189 | {
190 | if (_typeof(props[key]) === "object") element.animateWith(props.animateWith);
191 | break;
192 | }
193 | case "click":
194 | {
195 | if (typeof props[key] === "function") {
196 | element.unclick();element.click(props.click);
197 | }
198 | break;
199 | }
200 | case "data":
201 | {
202 | if (_typeof(props[key]) === "object") {
203 | for (var _key in props.data) {
204 | element.data(_key, props.data[_key]);
205 | }element.items = props.data;
206 | }
207 | break;
208 | }
209 | case "dblclick":
210 | {
211 | if (typeof props[key] === "function") {
212 | element.undblclick();element.dblclick(props.dblclick);
213 | }
214 | break;
215 | }
216 | case "drag":
217 | {
218 | if (_typeof(props[key]) === "object") {
219 | element.undrag();
220 | element.drag(props.drag.move, props.drag.start, props.drag.end, props.drag.mcontext, props.drag.scontext, props.drag.econtext);
221 | }
222 | break;
223 | }
224 | case "glow":
225 | {
226 | if (_typeof(props[key]) === "object") element.glow(props.glow);
227 | break;
228 | }
229 | case "hover":
230 | {
231 | if (_typeof(props[key]) === "object") {
232 | element.unhover();
233 | element.hover(props.hover.in, props.hover.out, props.hover.icontext, props.hover.ocontext);
234 | }
235 | break;
236 | }
237 | case "hide":
238 | {
239 | if (typeof props[key] === "boolean") props.hide ? element.hide() : element.show();
240 | break;
241 | }
242 | case "mousedown":
243 | {
244 | if (typeof props[key] === "function") {
245 | element.unmousedown();element.mousedown(props.mousedown);
246 | }
247 | break;
248 | }
249 | case "mousemove":
250 | {
251 | if (typeof props[key] === "function") {
252 | element.unmousemove();element.mousemove(props.mousemove);
253 | }
254 | break;
255 | }
256 | case "mouseout":
257 | {
258 | if (typeof props[key] === "function") {
259 | element.unmouseout();element.mouseout(props.mouseout);
260 | }
261 | break;
262 | }
263 | case "mouseover":
264 | {
265 | if (typeof props[key] === "function") {
266 | element.unmouseover();element.mouseover(props.mouseover);
267 | }
268 | break;
269 | }
270 | case "mouseup":
271 | {
272 | if (typeof props[key] === "function") {
273 | element.unmouseup();element.mouseup(props.mouseup);
274 | }
275 | break;
276 | }
277 | case "rotate":
278 | {
279 | if (_typeof(props[key]) === "object") {
280 | var _props$rotate = props.rotate,
281 | deg = _props$rotate.deg,
282 | cx = _props$rotate.cx,
283 | cy = _props$rotate.cy;
284 | element.rotate(deg, cx, cy);
285 | }
286 | break;
287 | }
288 | case "scale":
289 | {
290 | if (_typeof(props[key]) === "object") {
291 | var _props$scale = props.scale,
292 | sx = _props$scale.sx,
293 | sy = _props$scale.sy,
294 | _cx = _props$scale.cx,
295 | _cy = _props$scale.cy;
296 | element.scale(sx, sy, _cx, _cy);
297 | }
298 | break;
299 | }
300 | case "stop":
301 | {
302 | if (typeof props[key] === "boolean" && props.stop) {
303 | element.stop();
304 | }
305 | break;
306 | }
307 | case "touchcancel":
308 | {
309 | if (typeof props[key] === "function") {
310 | element.untouchcancel();element.touchcancel(props.touchcancel);
311 | }
312 | break;
313 | }
314 | case "touchend":
315 | {
316 | if (typeof props[key] === "function") {
317 | element.untouchend();element.touchend(props.touchend);
318 | }
319 | break;
320 | }
321 | case "touchmove":
322 | {
323 | if (typeof props[key] === "function") {
324 | element.untouchmove();element.touchmove(props.touchmove);
325 | }
326 | break;
327 | }
328 | case "touchstart":
329 | {
330 | if (typeof props[key] === "function") {
331 | element.untouchstart();element.touchstart(props.touchstart);
332 | }
333 | break;
334 | }
335 | case "transform":
336 | {
337 | if (_typeof(props[key]) === "object") element.transform(props.transform);
338 | break;
339 | }
340 | case "translate":
341 | {
342 | if (_typeof(props[key]) === "object") element.translate(props.translate.x, props.translate.y);
343 | break;
344 | }
345 | }
346 | }
347 | // fix raphael #491
348 | if (Raphael.svg && element.node && element.node.nodeName == "text" && element.node.childNodes.length > 0) {
349 | setTimeout(function () {
350 | if (element.node) {
351 | var nodeY = element.node.getAttribute("y");
352 | var childDy = element.node.childNodes[0].getAttribute("dy");
353 | if (nodeY == childDy) {
354 | element.node.childNodes[0].setAttribute("dy", 0);
355 | }
356 | }
357 | });
358 | }
359 | }
360 | },
361 | updateElement: function updateElement(element, type, props, callback) {
362 | switch (type) {
363 | case "circle":
364 | {
365 | var x = props.x,
366 | y = props.y,
367 | r = props.r;
368 |
369 | element.attr({ cx: x, cy: y, r: r });
370 | break;
371 | }
372 | case "ellipse":
373 | {
374 | var _x6 = props.x,
375 | _y6 = props.y,
376 | rx = props.rx,
377 | ry = props.ry;
378 |
379 | element.attr({ cx: _x6, cy: _y6, rx: rx, ry: ry });
380 | break;
381 | }
382 | case "image":
383 | {
384 | var src = props.src,
385 | _x7 = props.x,
386 | _y7 = props.y,
387 | width = props.width,
388 | height = props.height;
389 |
390 | element.attr({ src: src, x: _x7, y: _y7, width: width, height: height });
391 | break;
392 | }
393 | case "path":
394 | {
395 | var d = props.d;
396 |
397 | if (!d || d.length == 0) d = "M0,0L0,0Z";
398 | element.attr({ path: d });
399 | break;
400 | }
401 | case "print":
402 | {
403 | var _x8 = props.x,
404 | _y8 = props.y,
405 | text = props.text,
406 | fontFamily = props.fontFamily,
407 | fontWeight = props.fontWeight,
408 | fontStyle = props.fontStyle,
409 | fontStretch = props.fontStretch,
410 | fontSize = props.fontSize,
411 | letterSpacing = props.letterSpacing;
412 |
413 | element.attr({ x: _x8, y: _y8, text: text, "font-style": fontStyle, "font-family": fontFamily, "font-size": fontSize, "font-weight": fontWeight, "font-stretch": fontStretch, "letter-scpacing": letterSpacing });
414 | break;
415 | }
416 | case "rect":
417 | {
418 | var _x9 = props.x,
419 | _y9 = props.y,
420 | _width2 = props.width,
421 | _height2 = props.height,
422 | _r2 = props.r;
423 |
424 | element.attr({ x: _x9, y: _y9, width: _width2, height: _height2, r: _r2 });
425 | break;
426 | }
427 | case "text":
428 | {
429 | var _x10 = props.x,
430 | _y10 = props.y,
431 | _text2 = props.text;
432 |
433 | element.attr({ x: _x10, y: _y10, text: _text2 });
434 | break;
435 | }
436 |
437 | }
438 | Utils.updateElementProps(element, props);
439 | if (callback) callback(element);
440 | return element;
441 | },
442 | removePaper: function removePaper(paper) {
443 | var papers = Utils.papers.filter(function (ele) {
444 | return ele === paper;
445 | });
446 | if (papers.length > 0) {
447 | papers[0].remove();
448 | }
449 | },
450 | removeSet: function removeSet(set) {
451 | Utils.removeElement(set);
452 | },
453 | removeElement: function removeElement(element) {
454 | var elements = Utils.elements.filter(function (ele) {
455 | return ele.element === element;
456 | });
457 | if (elements.length > 0) {
458 | elements[0].element.remove();
459 | }
460 | },
461 | papers: [],
462 | elements: []
463 | };
464 |
465 | module.exports = Utils;
--------------------------------------------------------------------------------
/lib/elements.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | 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; };
4 |
5 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
6 |
7 | function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
8 |
9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10 |
11 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12 |
13 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
14 |
15 | var React = require("react");
16 | var ReactDOM = require("react-dom");
17 | var Utils = require("./utils");
18 |
19 | var PropTypes = require("prop-types");
20 |
21 | var Paper = function (_React$Component) {
22 | _inherits(Paper, _React$Component);
23 |
24 | function Paper(props) {
25 | _classCallCheck(this, Paper);
26 |
27 | var _this = _possibleConstructorReturn(this, (Paper.__proto__ || Object.getPrototypeOf(Paper)).call(this, props));
28 |
29 | _this.state = {
30 | loaded: false
31 | };
32 | return _this;
33 | }
34 |
35 | _createClass(Paper, [{
36 | key: "componentDidMount",
37 | value: function componentDidMount() {
38 | var container = ReactDOM.findDOMNode(this.refs.container);
39 | var paper = Utils.createPaper(container, this.props);
40 | this.paper = paper;
41 | this.setState({
42 | loaded: true,
43 | id: paper.id
44 | });
45 | }
46 | }, {
47 | key: "componentDidUpdate",
48 | value: function componentDidUpdate() {
49 | Utils.updatePaper(this.paper, this.props);
50 | }
51 | }, {
52 | key: "componentWillUnmount",
53 | value: function componentWillUnmount() {
54 | this.paper.remove();
55 | }
56 | }, {
57 | key: "getPaper",
58 | value: function getPaper() {
59 | return this.paper;
60 | }
61 | }, {
62 | key: "genElementsContainer",
63 | value: function genElementsContainer() {
64 | if (this.state.loaded) {
65 | return React.createElement(
66 | "div",
67 | { className: "raphael-paper", "data-id": this.state.id },
68 | this.props.children
69 | );
70 | } else {
71 | return React.createElement("div", { className: "raphael-paper" });
72 | }
73 | }
74 | }, {
75 | key: "render",
76 | value: function render() {
77 | var eleContainer = this.genElementsContainer();
78 |
79 | var _props$container = this.props.container,
80 | style = _props$container.style,
81 | className = _props$container.className,
82 | others = _objectWithoutProperties(_props$container, ["style", "className"]);
83 |
84 | return React.createElement(
85 | "div",
86 | { className: "react-raphael" },
87 | eleContainer,
88 | React.createElement("div", _extends({ ref: "container", className: "paper-container " + className, style: style }, others))
89 | );
90 | }
91 | }]);
92 |
93 | return Paper;
94 | }(React.Component);
95 |
96 | Paper.propTypes = {
97 | x: PropTypes.number,
98 | y: PropTypes.number,
99 | width: PropTypes.number,
100 | height: PropTypes.number,
101 | viewbox: PropTypes.string,
102 | container: PropTypes.object
103 | };
104 | Paper.defaultProps = { x: 0, y: 0, width: 100, height: 100, container: { style: {}, className: "" }, viewbox: "" };
105 |
106 | var Set = function (_React$Component2) {
107 | _inherits(Set, _React$Component2);
108 |
109 | function Set(props) {
110 | _classCallCheck(this, Set);
111 |
112 | var _this2 = _possibleConstructorReturn(this, (Set.__proto__ || Object.getPrototypeOf(Set)).call(this, props));
113 |
114 | _this2.state = {
115 | loaded: false
116 | };
117 | return _this2;
118 | }
119 |
120 | _createClass(Set, [{
121 | key: "componentDidMount",
122 | value: function componentDidMount() {
123 | var root = ReactDOM.findDOMNode(this.refs.root);
124 | var parentId = root.parentElement.getAttribute("data-id");
125 | var set = Utils.createSet(parentId, this.props, this.handleLoad.bind(this));
126 | this.set = set;
127 | this.setState({
128 | loaded: true,
129 | id: set.id
130 | });
131 | }
132 | }, {
133 | key: "getSet",
134 | value: function getSet() {
135 | return this.set;
136 | }
137 | }, {
138 | key: "handleLoad",
139 | value: function handleLoad(set) {
140 | if (this.props.load) {
141 | this.props.load(set);
142 | }
143 | }
144 | }, {
145 | key: "componentWillUnmout",
146 | value: function componentWillUnmout() {
147 | Utils.removeSet(this.set);
148 | }
149 | }, {
150 | key: "render",
151 | value: function render() {
152 | if (this.state.loaded) {
153 | return React.createElement(
154 | "div",
155 | { ref: "root", className: "raphael-set", "data-id": this.state.id },
156 | this.props.children
157 | );
158 | } else {
159 | return React.createElement("div", { ref: "root", className: "raphael-set", "data-id": this.state.id });
160 | }
161 | }
162 | }]);
163 |
164 | return Set;
165 | }(React.Component);
166 |
167 | var Element = function (_React$Component3) {
168 | _inherits(Element, _React$Component3);
169 |
170 | function Element(props) {
171 | _classCallCheck(this, Element);
172 |
173 | var _this3 = _possibleConstructorReturn(this, (Element.__proto__ || Object.getPrototypeOf(Element)).call(this, props));
174 |
175 | _this3.state = {
176 | loaded: false
177 | };
178 | return _this3;
179 | }
180 |
181 | _createClass(Element, [{
182 | key: "componentDidMount",
183 | value: function componentDidMount() {
184 | var root = ReactDOM.findDOMNode(this.refs.root);
185 | var parentId = root.parentElement.getAttribute("data-id");
186 | var element = Utils.createElement(parentId, this.props.type, this.props, this.handleLoad.bind(this));
187 | this.element = element;
188 | this.setState({
189 | loaded: true
190 | });
191 | }
192 | }, {
193 | key: "componentDidUpdate",
194 | value: function componentDidUpdate() {
195 | Utils.updateElement(this.element, this.props.type, this.props, this.handleUpdate.bind(this));
196 | }
197 | }, {
198 | key: "componentWillUnmount",
199 | value: function componentWillUnmount() {
200 | Utils.removeElement(this.element);
201 | }
202 | }, {
203 | key: "getElement",
204 | value: function getElement() {
205 | return this.element;
206 | }
207 | }, {
208 | key: "handleLoad",
209 | value: function handleLoad(element) {
210 | if (this.props.load) {
211 | this.props.load(element);
212 | }
213 | }
214 | }, {
215 | key: "handleUpdate",
216 | value: function handleUpdate(element) {
217 | if (this.props.update) {
218 | this.props.update(element);
219 | }
220 | }
221 | }, {
222 | key: "render",
223 | value: function render() {
224 | if (this.state.loaded) return null;
225 | return React.createElement("div", { ref: "root", className: "raphael-" + this.props.type });
226 | }
227 | }]);
228 |
229 | return Element;
230 | }(React.Component);
231 |
232 | Element.propTypes = {
233 | animate: PropTypes.oneOfType([PropTypes.shape({
234 | anim: PropTypes.shape({
235 | transform: PropTypes.string
236 | }),
237 | ms: PropTypes.number,
238 | percents: PropTypes.array,
239 | times: PropTypes.number
240 | }), PropTypes.string]),
241 | stop: PropTypes.bool
242 | };
243 |
244 | var Circle = function (_React$Component4) {
245 | _inherits(Circle, _React$Component4);
246 |
247 | function Circle() {
248 | _classCallCheck(this, Circle);
249 |
250 | return _possibleConstructorReturn(this, (Circle.__proto__ || Object.getPrototypeOf(Circle)).apply(this, arguments));
251 | }
252 |
253 | _createClass(Circle, [{
254 | key: "getElement",
255 | value: function getElement() {
256 | return this.refs.element.getElement();
257 | }
258 | }, {
259 | key: "render",
260 | value: function render() {
261 | return React.createElement(Element, _extends({ ref: "element", type: "circle" }, this.props));
262 | }
263 | }]);
264 |
265 | return Circle;
266 | }(React.Component);
267 |
268 | Circle.propTypes = {
269 | x: PropTypes.number,
270 | y: PropTypes.number,
271 | r: PropTypes.number, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool
272 | };
273 | Circle.defaultProps = { x: 0, y: 0, r: 10 };
274 |
275 | var Ellipse = function (_React$Component5) {
276 | _inherits(Ellipse, _React$Component5);
277 |
278 | function Ellipse() {
279 | _classCallCheck(this, Ellipse);
280 |
281 | return _possibleConstructorReturn(this, (Ellipse.__proto__ || Object.getPrototypeOf(Ellipse)).apply(this, arguments));
282 | }
283 |
284 | _createClass(Ellipse, [{
285 | key: "getElement",
286 | value: function getElement() {
287 | return this.refs.element.getElement();
288 | }
289 | }, {
290 | key: "render",
291 | value: function render() {
292 | return React.createElement(Element, _extends({ ref: "element", type: "ellipse" }, this.props));
293 | }
294 | }]);
295 |
296 | return Ellipse;
297 | }(React.Component);
298 |
299 | Ellipse.propTypes = { x: PropTypes.number, y: PropTypes.number, rx: PropTypes.number, ry: PropTypes.number, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
300 | Ellipse.defaultProps = { x: 0, y: 0, rx: 10, ry: 20 };
301 |
302 | var Image = function (_React$Component6) {
303 | _inherits(Image, _React$Component6);
304 |
305 | function Image() {
306 | _classCallCheck(this, Image);
307 |
308 | return _possibleConstructorReturn(this, (Image.__proto__ || Object.getPrototypeOf(Image)).apply(this, arguments));
309 | }
310 |
311 | _createClass(Image, [{
312 | key: "getElement",
313 | value: function getElement() {
314 | return this.refs.element.getElement();
315 | }
316 | }, {
317 | key: "render",
318 | value: function render() {
319 | return React.createElement(Element, _extends({ ref: "element", type: "image" }, this.props));
320 | }
321 | }]);
322 |
323 | return Image;
324 | }(React.Component);
325 |
326 | Image.propTypes = { x: PropTypes.number, y: PropTypes.number, src: PropTypes.string, width: PropTypes.number, height: PropTypes.number, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
327 | Image.defaultProps = { x: 0, y: 0, src: "", width: 0, height: 0 };
328 |
329 | var Path = function (_React$Component7) {
330 | _inherits(Path, _React$Component7);
331 |
332 | function Path() {
333 | _classCallCheck(this, Path);
334 |
335 | return _possibleConstructorReturn(this, (Path.__proto__ || Object.getPrototypeOf(Path)).apply(this, arguments));
336 | }
337 |
338 | _createClass(Path, [{
339 | key: "getElement",
340 | value: function getElement() {
341 | return this.refs.element.getElement();
342 | }
343 | }, {
344 | key: "render",
345 | value: function render() {
346 | return React.createElement(Element, _extends({ ref: "element", type: "path" }, this.props));
347 | }
348 | }]);
349 |
350 | return Path;
351 | }(React.Component);
352 |
353 | Path.propTypes = { d: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
354 | Path.defaultProps = { d: "M0,0L0,0Z" };
355 |
356 | var Rect = function (_React$Component8) {
357 | _inherits(Rect, _React$Component8);
358 |
359 | function Rect() {
360 | _classCallCheck(this, Rect);
361 |
362 | return _possibleConstructorReturn(this, (Rect.__proto__ || Object.getPrototypeOf(Rect)).apply(this, arguments));
363 | }
364 |
365 | _createClass(Rect, [{
366 | key: "getElement",
367 | value: function getElement() {
368 | return this.refs.element.getElement();
369 | }
370 | }, {
371 | key: "render",
372 | value: function render() {
373 | return React.createElement(Element, _extends({ ref: "element", type: "rect" }, this.props));
374 | }
375 | }]);
376 |
377 | return Rect;
378 | }(React.Component);
379 |
380 | Rect.propTypes = { x: PropTypes.number, y: PropTypes.number, width: PropTypes.number, height: PropTypes.number, r: PropTypes.number, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
381 | Rect.defaultProps = { x: 0, y: 0, width: 0, height: 0, r: 0 };
382 |
383 | var Print = function (_React$Component9) {
384 | _inherits(Print, _React$Component9);
385 |
386 | function Print() {
387 | _classCallCheck(this, Print);
388 |
389 | return _possibleConstructorReturn(this, (Print.__proto__ || Object.getPrototypeOf(Print)).apply(this, arguments));
390 | }
391 |
392 | _createClass(Print, [{
393 | key: "getElement",
394 | value: function getElement() {
395 | return this.refs.element.getElement();
396 | }
397 | }, {
398 | key: "render",
399 | value: function render() {
400 | return React.createElement(Element, _extends({ ref: "element", type: "print" }, this.props));
401 | }
402 | }]);
403 |
404 | return Print;
405 | }(React.Component);
406 |
407 | Print.propTypes = { x: PropTypes.number, y: PropTypes.number, text: PropTypes.string, fontFamily: PropTypes.string, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
408 | Print.defaultProps = { x: 0, y: 0, text: "", fontFamily: "Arial" };
409 |
410 | var Text = function (_React$Component10) {
411 | _inherits(Text, _React$Component10);
412 |
413 | function Text() {
414 | _classCallCheck(this, Text);
415 |
416 | return _possibleConstructorReturn(this, (Text.__proto__ || Object.getPrototypeOf(Text)).apply(this, arguments));
417 | }
418 |
419 | _createClass(Text, [{
420 | key: "getElement",
421 | value: function getElement() {
422 | return this.refs.element.getElement();
423 | }
424 | }, {
425 | key: "render",
426 | value: function render() {
427 | return React.createElement(Element, _extends({ ref: "element", type: "text" }, this.props));
428 | }
429 | }]);
430 |
431 | return Text;
432 | }(React.Component);
433 |
434 | Text.propTypes = { x: PropTypes.number, y: PropTypes.number, text: PropTypes.string, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
435 | Text.defaultProps = { x: 0, y: 0, text: "" };
436 |
437 | var Line = function (_React$Component11) {
438 | _inherits(Line, _React$Component11);
439 |
440 | function Line() {
441 | _classCallCheck(this, Line);
442 |
443 | return _possibleConstructorReturn(this, (Line.__proto__ || Object.getPrototypeOf(Line)).apply(this, arguments));
444 | }
445 |
446 | _createClass(Line, [{
447 | key: "getElement",
448 | value: function getElement() {
449 | return this.refs.path.getElement();
450 | }
451 | }, {
452 | key: "render",
453 | value: function render() {
454 | var _props = this.props,
455 | x1 = _props.x1,
456 | x2 = _props.x2,
457 | y1 = _props.y1,
458 | y2 = _props.y2,
459 | animate = _props.animate,
460 | attr = _props.attr,
461 | others = _objectWithoutProperties(_props, ["x1", "x2", "y1", "y2", "animate", "attr"]);
462 |
463 | if (animate) {
464 | if (animate.anim) {
465 | for (var key in animate.anim) {
466 | animate.anim[key].x1 = animate.anim[key].x1 || x1;
467 | animate.anim[key].x2 = animate.anim[key].x2 || x2;
468 | animate.anim[key].y1 = animate.anim[key].y1 || y1;
469 | animate.anim[key].y2 = animate.anim[key].y2 || y2;
470 | animate.anim[key].path = ["M", animate.anim[key].x1, animate.anim[key].y1, "L", animate.anim[key].x2, animate.anim[key].y2];
471 | }
472 | } else {
473 | animate.x1 = animate.x1 || x1;
474 | animate.x2 = animate.x2 || x2;
475 | animate.y1 = animate.y1 || y1;
476 | animate.y2 = animate.y2 || y2;
477 | animate.path = ["M", animate.x1, animate.y1, "L", animate.x2, animate.y2];
478 | }
479 | }
480 | if (attr) {
481 | attr.x1 = attr.x1 || x1;
482 | attr.x2 = attr.x2 || x2;
483 | attr.y1 = attr.y1 || y1;
484 | attr.y2 = attr.y2 || y2;
485 | attr.path = ["M", attr.x1, attr.y1, "L", attr.x2, attr.y2];
486 | }
487 | return React.createElement(Path, _extends({ ref: "path", d: ["M", x1, y1, "L", x2, y2], attr: attr, animate: animate }, others));
488 | }
489 | }]);
490 |
491 | return Line;
492 | }(React.Component);
493 |
494 | Line.propTypes = { x1: PropTypes.number, y1: PropTypes.number, x2: PropTypes.number, y2: PropTypes.number, animate: PropTypes.oneOfType([PropTypes.shape({ anim: PropTypes.shape({ transform: PropTypes.string }), ms: PropTypes.number, percents: PropTypes.array, times: PropTypes.number }), PropTypes.string]), stop: PropTypes.bool };
495 | Line.defaultProps = { x1: 0, y1: 0, x2: 0, y2: 0 };
496 |
497 | module.exports = {
498 | Paper: Paper,
499 | Set: Set,
500 | Element: Element,
501 | Circle: Circle,
502 | Ellipse: Ellipse,
503 | Image: Image,
504 | Path: Path,
505 | Print: Print,
506 | Rect: Rect,
507 | Text: Text,
508 | Line: Line
509 | };
--------------------------------------------------------------------------------