如何在react-native中制作圆形滑块 [英] How to make a circular slider in react-native

查看:87
本文介绍了如何在react-native中制作圆形滑块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加一个类似范围的组件.但是实际上是圆形的,我不知道该怎么做.您能帮我指点什么吗?

我想要的例子:

解决方案

我最近一直在使用react-native-svg,我认为这太棒了-SVG和React是极客天堂的完美搭档,非常完美用于创建自定义UI,而无需下拉至本机绘图代码.

这里有一个 CircularSlider 组件,它实现了您上面描述的内容:

  import'react'中的React,{Component}从'react-native'导入{PanResponder,View}从'react-native-svg'导入Svg,{Path,Circle,G,Text}圆弧滑动器类扩展了Component {构造函数(道具){超级(道具)this.handlePanResponderMove = this.handlePanResponderMove.bind(this)this.cartesianToPolar = this.cartesianToPolar.bind(this)this.polarToCartesian = this.polarToCartesian.bind(this)const {width,height} =道具const minimumSide =(Math.min(width,height))this.state = {cx:宽度/2,cy:高度/2,r :(最小边宽/2)*0.85}}componentWillMount =()=>{this._panResponder = PanResponder.create({onStartShouldSetPanResponder:()=>真的,onMoveShouldSetPanResponder:()=>真的,onPanResponderMove:this.handlePanResponderMove})}polarToCartesian(角度){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))返回{x,y}}cartesianToPolar(x,y){const {cx,cy} = this.state返回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))}使成为(){const {width,height,value,meterColor,textColor,onValueChange} = this.props,{cx,cy,r} = this.state,startCoord = this.polarToCartesian(0),endCoord = this.polarToCartesian(值)返回 (< Svg onLayout = {this.onLayout} width = {width} height = {height}><圆圈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}><圆cx = {7.5} cy = {7.5} r = {10} fill = {meterColor} {... this._panResponder.panHandlers}/><文本键= {value +''} x = {7.5} y = {1} fontSize = {10} fill = {textColor} textAnchor ="middle"> {value +''}</Text></G></Svg>)}}导出默认的CircularSlider 

完整的示例项目代码位于github

I want to add a like range component. But one that is actually circular and i have no idea how to do it. Can you point me to some help please.

Te example of what i want:

解决方案

I've been working with react-native-svg lately and I think it is fantastic - SVG and React are a match made in geek-heaven, just perfect for creating custom UI's with no need to drop down to native drawing code.

Here's a little CircularSlider component that implements what you described above:

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

The full sample project code is in github here.

This is just a quick prototype to give you the idea, but here's how it looks (two instances of CircularSlider, absolutely positioned so they have the same centres):

这篇关于如何在react-native中制作圆形滑块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆