2016-07-07 20 views

Odpowiedz

1

fajny projekt. pamiętaj, aby dzielić się tym, co tworzysz. Myślę, że inni też by to uznali za użyteczne. Niestety nie widziałem jeszcze zbyt wiele. Jeśli jednak to robiłem, zacznę od sprawdzenia, w jaki sposób wtyczki jQuery to robią. Coś takiego jak https://github.com/magicismight/react-native-svg może pomóc ci narysować kształty. Chciałbym być bardziej pomocny. Powodzenia!

14

Ostatnio pracowałem z respond-native-svg i myślę, że to jest fantastyczne - SVG i React to mecz stworzony w geek-niebie, idealny do tworzenia niestandardowych interfejsów, bez konieczności rozwijania do natywnego rysunku kod.

Oto mały CircularSlider komponentem, który realizuje to, co opisane powyżej:

import React,{Component} from 'react' 
import {PanResponder,View} 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 
     , {cx,cy,r} = this.state 
     , startCoord = this.polarToCartesian(0) 
     , endCoord = this.polarToCartesian(value) 
    return (
     <Svg onLayout={this.onLayout} width={width} height={height}> 
     <Circle cx={cx} cy={cy} r={r} stroke='#eee' strokeWidth={0.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={10} fill={meterColor} {...this._panResponder.panHandlers}/> 
      <Text key={value+''} x={7.5} y={1} fontSize={10} fill={textColor} textAnchor="middle">{value+''}</Text> 
     </G> 
     </Svg> 
    ) 
    } 
} 

export default CircularSlider 

pełny kod przykładowy projekt jest w github here.

To jest po prostu szybki prototyp, aby dać Ci pomysł, ale oto jak to wygląda (dwie instancje CircularSlider, całkowicie umieszczone tak, że mają te same ośrodki):

enter image description here

+0

Wielkie dzięki, zapisane dużo czasu dla mnie. –

+0

@KD sprawdź tę naprawdę fajną implementację na github https://github.com/bgryszko/react-native-circular-slider – Stevie