Skip to content

Instantly share code, notes, and snippets.

@renso3x
Last active October 19, 2017 08:40
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 renso3x/38e4b120404bd7f57fa2dc90951978fc to your computer and use it in GitHub Desktop.
Save renso3x/38e4b120404bd7f57fa2dc90951978fc to your computer and use it in GitHub Desktop.
import React,{ Component } from 'react';
import { PanResponder, View, Platform } from 'react-native';
import Svg,{ Path, Circle, G,Text } from 'react-native-svg';
class CircularSlider extends Component {
constructor(props){
super(props);
this.handlePanResponderMove = this.handlePanResponderMove.bind(this);
this.cartesianToPolar = this.cartesianToPolar.bind(this);
this.polarToCartesian = this.polarToCartesian.bind(this);
const { width,height } = props;
const smallestSide = (Math.min(width,height));
this.state = {
cx: width/2,
cy: height/2,
r: (smallestSide/2)*0.85
}
}
componentWillMount = () => {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderMove: this.handlePanResponderMove
});
}
polarToCartesian(angle) {
const {cx,cy,r} = this.state
, a = (angle-270) * Math.PI / 180.0
, x = cx + (r * Math.cos(a))
, y = cy + (r * Math.sin(a));
return { x, y };
}
cartesianToPolar(x,y) {
const {cx,cy} = this.state
return Math.round((Math.atan((y-cy)/(x-cx)))/(Math.PI/180)+((x>cx) ? 270 : 90))
}
handlePanResponderMove({nativeEvent:{locationX,locationY}}){
this.props.onValueChange(this.cartesianToPolar(locationX,locationY))
}
render() {
const {
width,
height,
value,
meterColor,
textColor,
onValueChange
} = this.props;
const { cx, cy, r } = this.state;
const startCoord = this.polarToCartesian(0);
const endCoord = this.polarToCartesian(value);
return (
<View>
<Svg
onLayout={this.onLayout}
width={width}
height={height}
rotation={360 + (360) / 2}
>
<Circle
cx={cx}
cy={cy}
r={r}
stroke='#eee'
strokeWidth={5}
fill='none'
/>
<Path
stroke={meterColor}
strokeWidth={5}
fill='none'
d={`M${startCoord.x} ${startCoord.y} A ${r} ${r} 0 ${value>180?1:0} 1 ${endCoord.x} ${endCoord.y}`}
/>
<G
x={endCoord.x-7.5}
y={endCoord.y-7.5}
>
<Circle
cx={7.5}
cy={7.5}
r={8}
fill={meterColor}
{...this._panResponder.panHandlers}
/>
</G>
</Svg>
{ this.props.children }
</View>
)
}
}
export default CircularSlider;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment