如何在 react-native 中制作圆形滑块

IT技术 javascript reactjs react-native reactive-programming
2021-05-05 02:39:08

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

我想要的例子:

圈子范围

2个回答

我最近一直在使用 react-native-svg,我认为它很棒 - SVG 和 React 是极客天堂中的匹配项,非常适合创建自定义 UI,而无需下拉到本地绘图代码。

这是一个CircularSlider实现上述内容的小组件:

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

完整的示例项目的代码是在github上这里

这只是一个快速原型,可以为您提供想法,但它的外观如下(CircularSlider 的两个实例,绝对定位,因此它们具有相同的中心):

在此处输入图片说明

很酷的项目。一定要分享你创造的东西。我认为其他人也会觉得这很有用。不幸的是,我还没有看到太多类似的东西。如果我这样做,我会先看看 jQuery 插件是如何做到的。https://github.com/magicismight/react-native-svg这样的东西可以帮助你绘制形状。希望我能更有帮助。祝你好运!