|
@@ -1,5 +1,5 @@
|
|
|
import { TimeFormatter } from "@/utils/time_format";
|
|
import { TimeFormatter } from "@/utils/time_format";
|
|
|
-import Svg, { Circle, Path, SvgUri, Image } from 'react-native-svg';
|
|
|
|
|
|
|
+import Svg, { Circle, Path, SvgUri, Image, Defs, Mask, Rect,Text } from 'react-native-svg';
|
|
|
import { useSelector } from "react-redux";
|
|
import { useSelector } from "react-redux";
|
|
|
import { NativeAppEventEmitter } from 'react-native';
|
|
import { NativeAppEventEmitter } from 'react-native';
|
|
|
import { MainColorType } from "@/context/themes/color";
|
|
import { MainColorType } from "@/context/themes/color";
|
|
@@ -27,5 +27,177 @@ export default function RNRingProgress(props: {
|
|
|
}) {
|
|
}) {
|
|
|
const canvasWidth = props.width ?? rpxToPx(900)
|
|
const canvasWidth = props.width ?? rpxToPx(900)
|
|
|
const canvasHeight = props.height ?? rpxToPx(720)
|
|
const canvasHeight = props.height ?? rpxToPx(720)
|
|
|
- return <Svg width={canvasWidth} height={canvasHeight}></Svg>
|
|
|
|
|
|
|
+ const centerX = canvasWidth / 2.0
|
|
|
|
|
+ const centerY = canvasHeight / 2.0
|
|
|
|
|
+
|
|
|
|
|
+ function currentTimePoint() {
|
|
|
|
|
+ if (!props.isCompleted) {
|
|
|
|
|
+ var time = new Date();
|
|
|
|
|
+ var seconds = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds();
|
|
|
|
|
+ // seconds += props.currentDot.offset! * 60
|
|
|
|
|
+ if (seconds > 24 * 3600) {
|
|
|
|
|
+ seconds -= 24 * 3600
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (seconds < 0) {
|
|
|
|
|
+ seconds += 24 * 3600
|
|
|
|
|
+ }
|
|
|
|
|
+ var arc = seconds / 86400 * 2 * Math.PI - Math.PI / 2.0;
|
|
|
|
|
+ const radians = arc;//angle * Math.PI / 180; // 将角度转换为弧度
|
|
|
|
|
+ const xPrime = canvasWidth / 2.0 + props.radius * Math.cos(radians);
|
|
|
|
|
+ const yPrime = canvasHeight / 2.0 + props.radius * Math.sin(radians);
|
|
|
|
|
+
|
|
|
|
|
+ return <Circle
|
|
|
|
|
+ cx={xPrime}
|
|
|
|
|
+ cy={yPrime}
|
|
|
|
|
+ r={props.target.width / 2.0 + rpxToPx(3)}
|
|
|
|
|
+ fillOpacity={0}
|
|
|
|
|
+ stroke={'white'}
|
|
|
|
|
+ strokeWidth={rpxToPx(14)}
|
|
|
|
|
+ strokeLinecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ // return <Defs>
|
|
|
|
|
+ // <Mask id="hole">
|
|
|
|
|
+ // <Circle
|
|
|
|
|
+ // cx={xPrime}
|
|
|
|
|
+ // cy={yPrime}
|
|
|
|
|
+ // r={props.target.width / 2.0 + rpxToPx(3)}
|
|
|
|
|
+ // fillOpacity={0}
|
|
|
|
|
+ // stroke={'red'}
|
|
|
|
|
+ // strokeWidth={rpxToPx(14)}
|
|
|
|
|
+ // strokeLinecap="round"
|
|
|
|
|
+ // />
|
|
|
|
|
+ // </Mask>
|
|
|
|
|
+ // </Defs>
|
|
|
|
|
+ }
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function extra(){
|
|
|
|
|
+ if (props.extra) {
|
|
|
|
|
+ const { goal, target, progress, value, footer, color, result } = props.extra
|
|
|
|
|
+ return <>
|
|
|
|
|
+ {
|
|
|
|
|
+ target && <Text
|
|
|
|
|
+ x={rpxToPx(450)}
|
|
|
|
|
+ y={rpxToPx(324)}
|
|
|
|
|
+ fontSize={rpxToPx(50)}
|
|
|
|
|
+ fontWeight={'bold'}
|
|
|
|
|
+ alignmentBaseline="top"
|
|
|
|
|
+ textAnchor="middle"
|
|
|
|
|
+ >
|
|
|
|
|
+ {target}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ progress && <Text
|
|
|
|
|
+ x={rpxToPx(450)}
|
|
|
|
|
+ y={rpxToPx(314)}
|
|
|
|
|
+ fontSize={rpxToPx(72)}
|
|
|
|
|
+ fontWeight={'bold'}
|
|
|
|
|
+ alignmentBaseline="top"
|
|
|
|
|
+ textAnchor="middle"
|
|
|
|
|
+ >
|
|
|
|
|
+ {progress}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ goal && <Text
|
|
|
|
|
+ x={rpxToPx(450)}
|
|
|
|
|
+ y={rpxToPx(416)}
|
|
|
|
|
+ fill={MainColorType.orange}
|
|
|
|
|
+ fontSize={rpxToPx(30)}
|
|
|
|
|
+ fontWeight={'bold'}
|
|
|
|
|
+ alignmentBaseline="top"
|
|
|
|
|
+ textAnchor="middle"
|
|
|
|
|
+ >
|
|
|
|
|
+ {goal}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ footer && <Text
|
|
|
|
|
+ x={rpxToPx(450)}
|
|
|
|
|
+ y={rpxToPx(420)}
|
|
|
|
|
+ fill={'rgba(0,0,0,0.5)'}
|
|
|
|
|
+ fontSize={rpxToPx(24)}
|
|
|
|
|
+ fontWeight={'bold'}
|
|
|
|
|
+ alignmentBaseline="top"
|
|
|
|
|
+ textAnchor="middle"
|
|
|
|
|
+ >
|
|
|
|
|
+ {footer}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ result && <Text
|
|
|
|
|
+ x={rpxToPx(450)}
|
|
|
|
|
+ y={rpxToPx(414)}
|
|
|
|
|
+ fontSize={rpxToPx(44)}
|
|
|
|
|
+ fontWeight={'bold'}
|
|
|
|
|
+ alignmentBaseline="top"
|
|
|
|
|
+ textAnchor="middle"
|
|
|
|
|
+ >
|
|
|
|
|
+ {result}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ </>
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return <Svg width={canvasWidth} height={canvasHeight}>
|
|
|
|
|
+ <Circle
|
|
|
|
|
+ cx={centerX}
|
|
|
|
|
+ cy={centerY}
|
|
|
|
|
+ r={props.radius}
|
|
|
|
|
+ fillOpacity={0}
|
|
|
|
|
+ stroke={props.bgRing.color}
|
|
|
|
|
+ strokeWidth={props.bgRing.width}
|
|
|
|
|
+ strokeLinecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ {
|
|
|
|
|
+ props.target && <Circle
|
|
|
|
|
+ cx={centerX}
|
|
|
|
|
+ cy={centerY}
|
|
|
|
|
+ r={props.radius}
|
|
|
|
|
+ fillOpacity={0}
|
|
|
|
|
+ stroke={props.target.color}
|
|
|
|
|
+ strokeWidth={props.target.width}
|
|
|
|
|
+ transform={`rotate(${props.target.start / (2 * Math.PI) * 360} ${centerX} ${centerY})`}
|
|
|
|
|
+ strokeDasharray={`${props.target.duration * props.radius},1000`}
|
|
|
|
|
+ strokeLinecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ props.real && props.isCompleted && <Circle
|
|
|
|
|
+ cx={centerX}
|
|
|
|
|
+ cy={centerY}
|
|
|
|
|
+ r={props.radius}
|
|
|
|
|
+ fillOpacity={0}
|
|
|
|
|
+ stroke={'rgba(0,0,0,0.05)'}
|
|
|
|
|
+ strokeWidth={rpxToPx(4)}
|
|
|
|
|
+ strokeLinecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ props.real && <Circle
|
|
|
|
|
+ cx={centerX}
|
|
|
|
|
+ cy={centerY}
|
|
|
|
|
+ r={props.radius}
|
|
|
|
|
+ fillOpacity={0}
|
|
|
|
|
+ stroke={props.real.color}
|
|
|
|
|
+ strokeWidth={props.real.width}
|
|
|
|
|
+ transform={`rotate(${props.real.start / (2 * Math.PI) * 360} ${centerX} ${centerY})`}
|
|
|
|
|
+ strokeDasharray={`${Math.max(props.real.duration, 0.01) * props.radius},1000`}
|
|
|
|
|
+ strokeLinecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ currentTimePoint()
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ extra()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ {/* {
|
|
|
|
|
+ !props.isCompleted && <Rect width="100%" height="100%" fill="rgba(0,0,0,0.5)" mask="url(#hole)"/>
|
|
|
|
|
+ } */}
|
|
|
|
|
+ </Svg>
|
|
|
}
|
|
}
|