React native 如何为24小时应用程序制作追踪720度的圆形滑块?
我正在尝试制作一个应用程序,在24小时内选择一个时间,以便根据选择的时间显示一些东西。我可以360度跟踪,但360度后会重置,所以我基本上无法得到我需要的东西。我只有12个小时。我还是JS的新手,而且是react native,所以如果你能给我解释一下,我会很高兴的 这里是我现在使用的圆形滑块:React native 如何为24小时应用程序制作追踪720度的圆形滑块?,react-native,React Native,我正在尝试制作一个应用程序,在24小时内选择一个时间,以便根据选择的时间显示一些东西。我可以360度跟踪,但360度后会重置,所以我基本上无法得到我需要的东西。我只有12个小时。我还是JS的新手,而且是react native,所以如果你能给我解释一下,我会很高兴的 这里是我现在使用的圆形滑块: import React, { Component } from "react"; import { PanResponder, Dimensions, View, ImageBac
import React, { Component } from "react";
import { PanResponder, Dimensions, View, ImageBackground, Image, Text } from "react-native";
import Svg, { Path, Circle, G } from "react-native-svg";
import ScrollableTabView from 'react-native-scrollable-tab-view';
import TabBar from 'react-native-underline-tabbar';
import { RFPercentage } from "react-native-responsive-fontsize";
import * as Font from "expo-font";
export default class CircleSlider extends Component {
constructor(props) {
super(props);
this.state = {
angle: this.props.value,
};
panResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, gs) => true,
onStartShouldSetPanResponderCapture: (e, gs) => true,
onMoveShouldSetPanResponder: (e, gs) => true,
onMoveShouldSetPanResponderCapture: (e, gs) => true,
onPanResponderMove: (e, gs) => {
let xOrigin =
this.props.xCenter - (this.props.dialRadius + this.props.btnRadius);
let yOrigin =
this.props.yCenter - (this.props.dialRadius + this.props.btnRadius);
let a = this.cartesianToPolar(gs.moveX - xOrigin, gs.moveY - yOrigin);
if (a <= this.props.min) {
this.setState({ angle: this.props.min });
} else if (a >= this.props.max) {
this.setState({ angle: this.props.max });
} else {
this.setState({ angle: a });
}
},
});
}
polarToCartesian(angle) {
let r = this.props.dialRadius;
let hC = this.props.dialRadius + this.props.btnRadius;
let a = ((angle - 90) * Math.PI) / 180.0;
let x = hC + r * Math.cos(a);
let y = hC + r * Math.sin(a);
return { x, y };
}
cartesianToPolar(x, y) {
let hC = this.props.dialRadius + this.props.btnRadius;
if (x === 0) {
return y > hC ? 0 : 180 ;
} else if (y === 0) {
return x > hC ? 90 : 270;
} else {
return (
Math.round((Math.atan((y - hC) / (x - hC)) * 180) / Math.PI) +
(x > hC ? 90 : 270)
);
}
}
render() {
if (!this.state.fontLoaded) { return null; }
let width = (this.props.dialRadius + this.props.btnRadius) * 2;
let bR = this.props.btnRadius;
let dR = this.props.dialRadius;
let startCoord = this.polarToCartesian(0);
let endCoord = this.polarToCartesian(this.state.angle);
return (
<View >
<ImageBackground
source={require("../../assets/SaatBackGround.png")}
resizeMode="contain"
style={{
width: "80%", height: "100%", position: "absolute", marginTop: "15%", alignSelf: "center",
}}
imageStyle={{ height: "100%", width: "100%" }}
>
<Image
style={{ height: "55%", width: "50.2%", alignSelf: "center", marginTop:"22%" }}
resizeMode="contain"
source={require("../../assets/ClockCircle.png")}></Image>
</ImageBackground>
<View style={{ justifyContent: "center", marginTop: "32%", marginLeft: "27.5%" }}>
<Svg width={width} height={width}>
<Circle
r={dR}
cx={width / 2}
cy={width / 2}
stroke={this.props.strokeColor}
strokeWidth={this.props.strokeWidth}
fill={this.props.fillColor}
/>
<Path
stroke={this.props.meterColor}
strokeWidth={this.props.dialWidth}
fill="none"
d={`M${startCoord.x} ${startCoord.y} A ${dR} ${dR} 0 ${
this.state.angle > 180 ? 1 : 0
} 1 ${endCoord.x} ${endCoord.y}`}
/>
<G x={endCoord.x - bR} y={endCoord.y - bR}>
<Circle
r={bR}
cx={bR}
cy={bR}
fill={this.props.meterColor}
{...panResponder.panHandlers}
/>
</G>
</Svg>
</View>
</View>
);
}
}
CircleSlider.defaultProps = {
btnRadius: 15,
dialRadius: 78,
dialWidth: 5,
meterColor: "#fff",
textColor: "#124F7B",
fillColor: "none",
strokeColor: "#fff",
strokeWidth: 0.1,
textSize: 10,
value: 0,
min: 0,
max: 719,
xCenter: Dimensions.get("window").width / 2,
yCenter: Dimensions.get("window").height / 2,
onValueChange: (x) => x,
};
import React,{Component}来自“React”;
从“react native”导入{PanResponder,Dimensions,View,ImageBackground,Image,Text};
从“react native Svg”导入Svg,{Path,Circle,G};
从“反应本机可滚动选项卡视图”导入可滚动选项卡视图;
从“react native underline TabBar”导入TabBar;
从“react native responsive fontsize”导入{RFPercentage};
从“expo字体”导入*作为字体;
导出默认类CircleSlider扩展组件{
建造师(道具){
超级(道具);
此.state={
角度:this.props.value,
};
panResponder=panResponder.create({
onStartShouldSetPanResponder:(e,gs)=>真,
onStartShouldSetPanResponderCapture:(e,gs)=>真,
onMoveShouldSetPanResponder:(e,gs)=>真,
onMoveShouldSetPanResponderCapture:(e,gs)=>真,
onPanResponderMove:(e,gs)=>{
让我来=
this.props.xCenter-(this.props.dialRadius+this.props.btnRadius);
让约里金=
this.props.yCenter-(this.props.diaradius+this.props.btnRadius);
设a=this.cartesianToPolar(gs.moveX-xOrigin,gs.moveY-yOrigin);
如果(a=此.props.max){
this.setState({angle:this.props.max});
}否则{
this.setState({angle:a});
}
},
});
}
极笛卡尔(角){
设r=this.props.dialRadius;
设hC=this.props.dialRadius+this.props.btnRadius;
设a=((角度-90)*Math.PI)/180.0;
设x=hC+r*Math.cos(a);
设y=hC+r*Math.sin(a);
返回{x,y};
}
笛卡尔南极(x,y){
设hC=this.props.dialRadius+this.props.btnRadius;
如果(x==0){
返回y>hC?0:180;
}如果(y==0),则为else{
返回x>hC?90:270;
}否则{
返回(
数学圆((数学圆((y-hC)/(x-hC))*180)/Math.PI)+
(x>hC?90:270)
);
}
}
render(){
如果(!this.state.fontload){return null;}
让宽度=(this.props.dialRadius+this.props.btnRadius)*2;
设bR=this.props.btnRadius;
设dR=this.props.dialRadius;
设startCoord=this.polartocatesian(0);
设endCoord=this.polarToCartesian(this.state.angle);
返回(
180 ? 1 : 0
}1${endCoord.x}${endCoord.y}`}
/>
);
}
}
CircleSlider.defaultProps={
btnRadius:15,
半径:78,
表盘宽度:5,
米色:“fff”,
textColor:#124F7B“,
fillColor:“无”,
strokeColor:#fff“,
冲程宽度:0.1,
文本大小:10,
值:0,
分:0,,
最高:719,
xCenter:Dimensions.get(“窗口”).width/2,
Y中心:尺寸。获取(“窗口”)。高度/2,
onValueChange:(x)=>x,
};