Вращайте диски с прикосновением пользователя в React Native
Я хочу создать диск как компонент в react-native
, который пользователь может вращать касанием и выравнивать сегменты соответственно относительно маркера.
Ниже приведено изображение компонента, который я собираюсь сделать:
В центре находятся 3 диска, каждый из которых должен вращаться по отдельности. На каждом диске есть несколько сегментов с некоторыми значениями. Как только сегменты выровнены, это может выглядеть как на картинке ниже:
Я ищу способ вращать диски касанием пользователя так, чтобы сегменты могли быть выровнены и отображать соответствующие значения.
Я пытался увидеть React Native Animated
API, но не уверен, смогу ли я добиться этого с ним.
Кроме того, я не знаю, как поступить с сенсорным вводом пользователя, чтобы вращать диски.
1 ответ
Сначала вам нужно вычислить положение вашего элемента на диске style creatore
Функция рассчитает стиль и вернет его, если вы хотите добавить элемент на ваш диск с вашим вращением, вам нужна структура Round Queue, если нет, и ваш элемент на диске всегда одинаковый, просто используйте простой массив
styleCreator = (Ncircle,radius) => {
//this.Styles = new RoundQueue()
this.Styles = []
var step = 360 / (Ncircle);
var degrees = [];
for(let index = 0; index < Ncircle ; index ++ ){
degrees.push(0 + index * step)
}
for(let index = 0; index < Ncircle ; index ++ ){
let radTdeg = degrees[index] * Math.PI / 180
let TX = radius * Math.cos(radTdeg)
let TY = radius * Math.sin(radTdeg)
let Rotate = degrees[index]
//this.Styles.enqueue
this.Styles.push({
position: 'absolute',
transform: [
{translateX : TX},
{translateY : TY},
]
})
}
}
и для того, чтобы позволить вашему компоненту взять под контроль использование сенсорного Pan responder
(см. реагировать на родной документ)
handleStartShouldSetPanResponder = (e, gestureState) => {
return true
}
handlePanResponderGrant = (e, gestureState) => {
this.setState({dragging: true})
}
Вы можете справиться с движением касания следующим образом:
handlePanResponderMove = (e, gestureState) => {
let Moved = Math.sqrt(Math.pow(gestureState.dx,2)+Math.pow(gestureState.dy,2))
if(Math.sign(gestureState.dx) == -1 && Math.abs(gestureState.dx) > Math.abs(gestureState.dy) || Math.sign(gestureState.dy) == -1 && Math.abs(gestureState.dy) > Math.abs(gestureState.dx)) {
Moved = -1 * Moved
}
if(Moved > 10 ){
if(10 < Moved ) {
var Tm = Moved / 360
this.state.rotation.setValue(Tm)
}
} else if (Moved < -10) {
if(-80 < Moved && Moved < -10) {
var Tm = Moved / 360
this.state.rotation.setValue(Tm)
}
}
}
и ваш компонент рендерера должен выглядеть так:
this.state = {
rotation : new Animated.Value(0),
animatedValuedeg : new Animated.Value(0)
}
render() {
return(
<Animated.View style = {{backgroundColor: 'transparent',
transform: [{ rotate: this.MainRotate }]}}>
<Animated.View style = {{
transform: [{ rotate: this.spin }],
backgroundColor: 'transparent',
position : 'relative',
alignItems:'center' ,
justifyContent: 'center',
}}
>
{this.Components}
</Animated.View>
</Animated.View>
)
}
и вы должны написать метод для рендеринга вашего элемента, который вы хотите поместить на диск и положить его в this.Components
переменная, так как я не совсем понял, что вы хотите реализовать, я просто попытался дать вам и идею, как это сделать
наслаждайся приятель