2016-07-16 04:45:54 +08:00
|
|
|
import React, { Component, PropTypes } from 'react';
|
2017-03-23 07:24:36 +08:00
|
|
|
import { findDOMNode } from 'react-dom';
|
2016-07-16 04:45:54 +08:00
|
|
|
|
|
|
|
const propTypes = {
|
2016-07-18 23:30:04 +08:00
|
|
|
//Width of the view box
|
|
|
|
viewBoxWidth: PropTypes.number.isRequired,
|
|
|
|
|
|
|
|
//Height of the view box
|
|
|
|
viewBoxHeight: PropTypes.number.isRequired,
|
|
|
|
|
|
|
|
//x Position of the view box
|
|
|
|
viewBoxX: PropTypes.number.isRequired,
|
|
|
|
|
|
|
|
//y Position of the view box
|
|
|
|
viewBoxY: PropTypes.number.isRequired,
|
|
|
|
|
|
|
|
//Slide to view box width ratio
|
|
|
|
widthRatio: PropTypes.number.isRequired,
|
2016-07-16 04:45:54 +08:00
|
|
|
|
|
|
|
//Defines the cursor x position
|
2016-07-18 23:30:04 +08:00
|
|
|
cursorX: PropTypes.number.isRequired,
|
2016-07-16 04:45:54 +08:00
|
|
|
|
|
|
|
//Defines the cursor y position
|
2016-07-18 23:30:04 +08:00
|
|
|
cursorY: PropTypes.number.isRequired,
|
2016-07-16 04:45:54 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Defines the cursor fill colour
|
|
|
|
* @defaultValue 'red'
|
|
|
|
*/
|
|
|
|
fill: PropTypes.string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Defines the cursor radius
|
|
|
|
* @defaultValue 5
|
|
|
|
*/
|
|
|
|
radius: PropTypes.number,
|
|
|
|
};
|
|
|
|
|
|
|
|
const defaultProps = {
|
|
|
|
fill: 'red',
|
|
|
|
radius: 5,
|
|
|
|
};
|
|
|
|
|
|
|
|
export default class Cursor extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2017-03-23 07:24:36 +08:00
|
|
|
this.state = {
|
|
|
|
cx: 0,
|
|
|
|
cy: 0,
|
|
|
|
finalRadius: 5,
|
|
|
|
fill: 'red',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
|
|
|
let calculatedData = this.calculatePositionAndRadius(this.props);
|
|
|
|
this.setState({
|
|
|
|
currentData: calculatedData,
|
|
|
|
prevData: calculatedData,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
let calculatedData = this.calculatePositionAndRadius(nextProps);
|
|
|
|
this.setState({
|
|
|
|
prevData: this.state.currentData,
|
|
|
|
currentData: calculatedData,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate() {
|
|
|
|
const { cursor } = this.refs;
|
|
|
|
var node = findDOMNode(cursor);
|
|
|
|
node.beginElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
calculatePositionAndRadius(propsObj) {
|
|
|
|
return {
|
|
|
|
//Adjust the x,y cursor position according to zoom
|
|
|
|
cx: (propsObj.cursorX * propsObj.viewBoxWidth) + propsObj.viewBoxX,
|
|
|
|
cy: (propsObj.cursorY * propsObj.viewBoxHeight) + propsObj.viewBoxY,
|
|
|
|
//Adjust the radius of the cursor according to zoom
|
|
|
|
finalRadius: propsObj.radius * propsObj.widthRatio / 100,
|
|
|
|
fill: propsObj.fill,
|
|
|
|
}
|
2016-07-16 04:45:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
2017-03-23 07:24:36 +08:00
|
|
|
currentData,
|
|
|
|
prevData
|
|
|
|
} = this.state;
|
2016-07-16 04:45:54 +08:00
|
|
|
|
|
|
|
return (
|
|
|
|
<circle
|
2017-03-23 07:24:36 +08:00
|
|
|
r={currentData.finalRadius}
|
|
|
|
fill={currentData.fill}
|
|
|
|
>
|
|
|
|
<animateTransform
|
|
|
|
ref="cursor"
|
|
|
|
attributeName="transform"
|
|
|
|
type="translate"
|
|
|
|
from={prevData.cx + " " + prevData.cy}
|
|
|
|
to={currentData.cx + " " + currentData.cy}
|
|
|
|
begin={'indefinite'}
|
|
|
|
dur="0.1s"
|
|
|
|
repeatCount="0"
|
|
|
|
fill="freeze"
|
|
|
|
/>
|
|
|
|
</circle>
|
2016-07-16 04:45:54 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Cursor.propTypes = propTypes;
|
|
|
|
Cursor.defaultProps = defaultProps;
|