|
@@ -20,8 +20,10 @@ export default function Demo() {
|
|
|
|
|
|
|
|
var currentContext;
|
|
var currentContext;
|
|
|
|
|
|
|
|
- var startAngle,endAngle;
|
|
|
|
|
|
|
+ var startAngle = 45*Math.PI/180;
|
|
|
|
|
+ var endAngle = 120*Math.PI/180;
|
|
|
var lastAngle;
|
|
var lastAngle;
|
|
|
|
|
+ var lastDuration = 0;
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
|
|
|
|
@@ -51,43 +53,39 @@ export default function Demo() {
|
|
|
const centerY = canvasHeight / 2;
|
|
const centerY = canvasHeight / 2;
|
|
|
const radius = Math.min(centerX, centerY) - 10;
|
|
const radius = Math.min(centerX, centerY) - 10;
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
|
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
|
|
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
|
|
|
ctx.strokeStyle = "rgba(0,0,0,0.5)";
|
|
ctx.strokeStyle = "rgba(0,0,0,0.5)";
|
|
|
ctx.lineWidth = 10;
|
|
ctx.lineWidth = 10;
|
|
|
ctx.stroke();
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
- // 绘制绿色起点圆点
|
|
|
|
|
- const pointAngle = 45; // 圆环上的角度
|
|
|
|
|
- const pointX = centerX + Math.cos((pointAngle * Math.PI) / 180) * radius;
|
|
|
|
|
- const pointY = centerY + Math.sin((pointAngle * Math.PI) / 180) * radius;
|
|
|
|
|
-
|
|
|
|
|
- // 绘制蓝色终点圆点
|
|
|
|
|
- const pointEndAngle = 120; // 圆环上的角度
|
|
|
|
|
- const pointEndX = centerX + Math.cos((pointEndAngle * Math.PI) / 180) * radius;
|
|
|
|
|
- const pointEndY = centerY + Math.sin((pointEndAngle * Math.PI) / 180) * radius;
|
|
|
|
|
-
|
|
|
|
|
- startAngle = (pointAngle * Math.PI) / 180;
|
|
|
|
|
- endAngle = (pointEndAngle * Math.PI) / 180;
|
|
|
|
|
-
|
|
|
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
|
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
|
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
|
|
ctx.strokeStyle = canRingDrag?"red":"rgba(255,0,0,0.5)";
|
|
ctx.strokeStyle = canRingDrag?"red":"rgba(255,0,0,0.5)";
|
|
|
ctx.lineWidth = 10;
|
|
ctx.lineWidth = 10;
|
|
|
ctx.stroke();
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
|
|
+ const pointX = centerX + Math.cos(startAngle) * radius;
|
|
|
|
|
+ const pointY = centerY + Math.sin(startAngle) * radius;
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
|
ctx.arc(pointX, pointY, 5, 0, 2 * Math.PI);
|
|
ctx.arc(pointX, pointY, 5, 0, 2 * Math.PI);
|
|
|
ctx.fillStyle = '#00ff00';
|
|
ctx.fillStyle = '#00ff00';
|
|
|
ctx.fill();
|
|
ctx.fill();
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制蓝色终点圆点
|
|
|
|
|
+ const pointX2 = centerX + Math.cos(endAngle) * radius;
|
|
|
|
|
+ const pointY2 = centerY + Math.sin(endAngle) * radius;
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
|
- ctx.arc(pointEndX, pointEndY, 5, 0, 2 * Math.PI);
|
|
|
|
|
|
|
+ ctx.arc(pointX2, pointY2, 5, 0, 2 * Math.PI);
|
|
|
ctx.fillStyle = 'blue';
|
|
ctx.fillStyle = 'blue';
|
|
|
ctx.fill();
|
|
ctx.fill();
|
|
|
};
|
|
};
|
|
@@ -97,67 +95,96 @@ export default function Demo() {
|
|
|
return dep;
|
|
return dep;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ function limitAngle(start,end) {
|
|
|
|
|
+ var angle1 = start<0?start+2*Math.PI:start;
|
|
|
|
|
+ var angle2 = end<0?end+2*Math.PI:end;
|
|
|
|
|
+ if (angle2<angle1){
|
|
|
|
|
+ angle2 = angle2+2*Math.PI;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var leftAngle = angle2-angle1;
|
|
|
|
|
+ if (leftAngle>Math.PI*23/12){
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (leftAngle<Math.PI/12){
|
|
|
|
|
+ return 2;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function durationAngle(end,start) {
|
|
|
|
|
+ var angle1 = start<0?start+2*Math.PI:start;
|
|
|
|
|
+ var angle2 = end<0?end+2*Math.PI:end;
|
|
|
|
|
+ if (angle2<angle1){
|
|
|
|
|
+ angle2 = angle2+2*Math.PI;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return angle2-angle1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const handleTouchMove = (e: any) => {
|
|
const handleTouchMove = (e: any) => {
|
|
|
|
|
+ const ctx = currentContext;//canvasRef.current.getContext('2d');
|
|
|
if (!canStartDrag && !canEndDrag && !canRingDrag){
|
|
if (!canStartDrag && !canEndDrag && !canRingDrag){
|
|
|
|
|
+ drawCanvas(ctx);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- const ctx = currentContext;//canvasRef.current.getContext('2d');
|
|
|
|
|
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
|
|
|
+
|
|
|
const { x, y } = e.touches[0];
|
|
const { x, y } = e.touches[0];
|
|
|
|
|
|
|
|
- const centerX = canvasWidth / 2;
|
|
|
|
|
- const centerY = canvasHeight / 2;
|
|
|
|
|
- const radius = Math.min(centerX, centerY) - 10;
|
|
|
|
|
-
|
|
|
|
|
let angle = Math.atan2(y-canvasWidth/2.0, x-canvasWidth/2.0)
|
|
let angle = Math.atan2(y-canvasWidth/2.0, x-canvasWidth/2.0)
|
|
|
|
|
|
|
|
if (canStartDrag){
|
|
if (canStartDrag){
|
|
|
- startAngle = angle;
|
|
|
|
|
|
|
+ if (Math.abs(durationAngle(endAngle,angle)-lastDuration)>Math.PI){
|
|
|
|
|
+ //禁止跨越
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var result = limitAngle(angle,endAngle);
|
|
|
|
|
+ switch (result){
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ startAngle = angle;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ startAngle = endAngle-23*Math.PI/12;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ startAngle = endAngle-Math.PI/12;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (canEndDrag){
|
|
if (canEndDrag){
|
|
|
- endAngle = angle;
|
|
|
|
|
|
|
+ if (Math.abs(durationAngle(angle,startAngle)-lastDuration)>Math.PI){
|
|
|
|
|
+ //禁止跨越
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var result = limitAngle(startAngle,angle);
|
|
|
|
|
+ switch (result){
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ endAngle = angle;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ endAngle = startAngle+23*Math.PI/12;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ endAngle = startAngle+Math.PI/12;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (canRingDrag){
|
|
if (canRingDrag){
|
|
|
- console.log(`lastAngle:${lastAngle} angle:${angle}`)
|
|
|
|
|
let delta = angle - lastAngle;
|
|
let delta = angle - lastAngle;
|
|
|
startAngle += delta;
|
|
startAngle += delta;
|
|
|
endAngle += delta;
|
|
endAngle += delta;
|
|
|
lastAngle = angle;
|
|
lastAngle = angle;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- ctx.beginPath();
|
|
|
|
|
- ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
|
|
|
|
|
- ctx.strokeStyle = "rgba(0,0,0,0.5)";
|
|
|
|
|
- ctx.lineWidth = 10;
|
|
|
|
|
- ctx.stroke();
|
|
|
|
|
-
|
|
|
|
|
- ctx.beginPath();
|
|
|
|
|
- ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
|
|
|
|
- ctx.strokeStyle = canRingDrag?"red":"rgba(255,0,0,0.5)";
|
|
|
|
|
- ctx.lineWidth = 10;
|
|
|
|
|
- ctx.stroke();
|
|
|
|
|
-
|
|
|
|
|
- const pointX = centerX + Math.cos(startAngle) * radius;
|
|
|
|
|
- const pointY = centerY + Math.sin(startAngle) * radius;
|
|
|
|
|
|
|
|
|
|
- ctx.beginPath();
|
|
|
|
|
- ctx.arc(pointX, pointY, 5, 0, 2 * Math.PI);
|
|
|
|
|
- ctx.fillStyle = '#00ff00';
|
|
|
|
|
- ctx.fill();
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // 绘制蓝色终点圆点
|
|
|
|
|
- const pointX2 = centerX + Math.cos(endAngle) * radius;
|
|
|
|
|
- const pointY2 = centerY + Math.sin(endAngle) * radius;
|
|
|
|
|
|
|
+ drawCanvas(ctx);
|
|
|
|
|
|
|
|
- ctx.beginPath();
|
|
|
|
|
- ctx.arc(pointX2, pointY2, 5, 0, 2 * Math.PI);
|
|
|
|
|
- ctx.fillStyle = 'blue';
|
|
|
|
|
- ctx.fill();
|
|
|
|
|
|
|
+ lastDuration = durationAngle(endAngle,startAngle);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleClick = (e) => {
|
|
const handleClick = (e) => {
|
|
@@ -166,9 +193,6 @@ export default function Demo() {
|
|
|
const scaleY = 1//dpr//canvasRect.height / canvasRect.height;
|
|
const scaleY = 1//dpr//canvasRect.height / canvasRect.height;
|
|
|
const canvasX = (e.touches[0].x - 0) * scaleX;
|
|
const canvasX = (e.touches[0].x - 0) * scaleX;
|
|
|
const canvasY = (e.touches[0].y - 0) * scaleY;
|
|
const canvasY = (e.touches[0].y - 0) * scaleY;
|
|
|
- console.log(`x:${canvasX} y:${canvasY}`)
|
|
|
|
|
-
|
|
|
|
|
- // const ctx = canvasRef.current.getContext('2d');
|
|
|
|
|
|
|
|
|
|
// 判断点击位置是否在圆点范围内
|
|
// 判断点击位置是否在圆点范围内
|
|
|
const centerX = canvasWidth / 2;
|
|
const centerX = canvasWidth / 2;
|
|
@@ -180,7 +204,7 @@ export default function Demo() {
|
|
|
const pointY = centerY + Math.sin(startAngle) * radius;
|
|
const pointY = centerY + Math.sin(startAngle) * radius;
|
|
|
const distance = Math.sqrt(Math.pow(canvasX - pointX, 2) + Math.pow(canvasY - pointY, 2));
|
|
const distance = Math.sqrt(Math.pow(canvasX - pointX, 2) + Math.pow(canvasY - pointY, 2));
|
|
|
|
|
|
|
|
- if (distance <= 5) {
|
|
|
|
|
|
|
+ if (distance <= 8) {
|
|
|
canStartDrag = true;
|
|
canStartDrag = true;
|
|
|
} else {
|
|
} else {
|
|
|
canStartDrag = false;
|
|
canStartDrag = false;
|
|
@@ -190,7 +214,7 @@ export default function Demo() {
|
|
|
const pointY2 = centerY + Math.sin(endAngle) * radius;
|
|
const pointY2 = centerY + Math.sin(endAngle) * radius;
|
|
|
const distance2 = Math.sqrt(Math.pow(canvasX - pointX2, 2) + Math.pow(canvasY - pointY2, 2));
|
|
const distance2 = Math.sqrt(Math.pow(canvasX - pointX2, 2) + Math.pow(canvasY - pointY2, 2));
|
|
|
|
|
|
|
|
- if (distance2 <= 5) {
|
|
|
|
|
|
|
+ if (distance2 <= 8) {
|
|
|
canEndDrag = true;
|
|
canEndDrag = true;
|
|
|
} else {
|
|
} else {
|
|
|
canEndDrag = false;
|
|
canEndDrag = false;
|
|
@@ -205,17 +229,16 @@ export default function Demo() {
|
|
|
let angle = Math.atan2(canvasY-canvasWidth/2.0, canvasX-canvasWidth/2.0)
|
|
let angle = Math.atan2(canvasY-canvasWidth/2.0, canvasX-canvasWidth/2.0)
|
|
|
if (distance3>80&& distance3<105 && startAngle<angle && angle<endAngle){
|
|
if (distance3>80&& distance3<105 && startAngle<angle && angle<endAngle){
|
|
|
canRingDrag = true;
|
|
canRingDrag = true;
|
|
|
- console.log("canRingDrag")
|
|
|
|
|
}
|
|
}
|
|
|
- console.log(distance3);
|
|
|
|
|
lastAngle = angle;
|
|
lastAngle = angle;
|
|
|
|
|
+
|
|
|
|
|
+ drawCanvas(currentContext);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleTouchEnd = (e) =>{
|
|
const handleTouchEnd = (e) =>{
|
|
|
canStartDrag = false;
|
|
canStartDrag = false;
|
|
|
canEndDrag = false;
|
|
canEndDrag = false;
|
|
|
canRingDrag = false;
|
|
canRingDrag = false;
|
|
|
- console.log('end')
|
|
|
|
|
handleTouchMove(e)
|
|
handleTouchMove(e)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -228,106 +251,3 @@ export default function Demo() {
|
|
|
ref={canvasRef} />
|
|
ref={canvasRef} />
|
|
|
</View>
|
|
</View>
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-// const CircleCanvas = () => {
|
|
|
|
|
-// const canvasRef = useRef<any>(null);
|
|
|
|
|
-// const canvasWidth: number = 200;
|
|
|
|
|
-// const canvasHeight: number = 200;
|
|
|
|
|
-// const circleRadius: number = 100;
|
|
|
|
|
-// const ringWidth: number = 30;
|
|
|
|
|
-// const dotRadius: number = 10;
|
|
|
|
|
-// const dpr = Taro.getSystemInfoSync().pixelRatio; // 获取设备的像素比
|
|
|
|
|
-
|
|
|
|
|
-// useEffect(() => {
|
|
|
|
|
-// const query = Taro.createSelectorQuery();
|
|
|
|
|
-// query.select('.111').fields({ node: true, size: true });
|
|
|
|
|
-// query.exec((res) => {
|
|
|
|
|
-// if (res[0] == null) return;
|
|
|
|
|
-// const _canvas = res[0].node;
|
|
|
|
|
-// _canvas.width = res[0].width * dpr;
|
|
|
|
|
-// _canvas.height = res[0].height * dpr;
|
|
|
|
|
-// const ctx = _canvas.getContext('2d');
|
|
|
|
|
-
|
|
|
|
|
-// // const center = radius + lineWidth / 2; // 圆心坐标
|
|
|
|
|
-// // ctx.clearRect(0, 0, radius * 2, radius * 2); // 清除画布
|
|
|
|
|
-
|
|
|
|
|
-// // 设置画布尺寸
|
|
|
|
|
-// ctx.scale(dpr, dpr);
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-// drawCanvas(ctx);
|
|
|
|
|
-// });
|
|
|
|
|
-// }, []);
|
|
|
|
|
-
|
|
|
|
|
-// const drawCanvas = (context: any) => {
|
|
|
|
|
-// context.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
|
-
|
|
|
|
|
-// // 绘制红色圆环
|
|
|
|
|
-// context.beginPath();
|
|
|
|
|
-// context.arc(
|
|
|
|
|
-// canvasWidth / 2,
|
|
|
|
|
-// canvasHeight / 2,
|
|
|
|
|
-// circleRadius,
|
|
|
|
|
-// 0,
|
|
|
|
|
-// 2 * Math.PI,
|
|
|
|
|
-// false
|
|
|
|
|
-// );
|
|
|
|
|
-// context.lineWidth = ringWidth;
|
|
|
|
|
-// context.strokeStyle = 'red';
|
|
|
|
|
-// context.stroke();
|
|
|
|
|
-
|
|
|
|
|
-// // 绘制绿色圆点
|
|
|
|
|
-// context.beginPath();
|
|
|
|
|
-// context.arc(
|
|
|
|
|
-// canvasWidth / 2,
|
|
|
|
|
-// canvasHeight / 2,
|
|
|
|
|
-// dotRadius,
|
|
|
|
|
-// 0,
|
|
|
|
|
-// 2 * Math.PI,
|
|
|
|
|
-// false
|
|
|
|
|
-// );
|
|
|
|
|
-// context.fillStyle = 'green';
|
|
|
|
|
-// context.fill();
|
|
|
|
|
-// };
|
|
|
|
|
-
|
|
|
|
|
-// const handleTouchMove = (e: any) => {
|
|
|
|
|
-// const context = canvasRef.current.getContext('2d');
|
|
|
|
|
-// const { x, y } = e.touches[0];
|
|
|
|
|
-// drawCanvas(context);
|
|
|
|
|
-
|
|
|
|
|
-// // 绘制拖动后的红色圆环
|
|
|
|
|
-// context.beginPath();
|
|
|
|
|
-// context.arc(x, y, circleRadius, 0, 2 * Math.PI, false);
|
|
|
|
|
-// context.lineWidth = ringWidth;
|
|
|
|
|
-// context.strokeStyle = 'red';
|
|
|
|
|
-// context.stroke();
|
|
|
|
|
-
|
|
|
|
|
-// // 绘制绿色圆点
|
|
|
|
|
-// context.beginPath();
|
|
|
|
|
-// context.arc(x, y, dotRadius, 0, 2 * Math.PI, false);
|
|
|
|
|
-// context.fillStyle = 'green';
|
|
|
|
|
-// context.fill();
|
|
|
|
|
-// };
|
|
|
|
|
-
|
|
|
|
|
-// return <View>
|
|
|
|
|
-// <Canvas canvasId='111' id='111' className='111' type="2d"
|
|
|
|
|
-// style={{ width: 400, height: 400, zIndex: 0 }}
|
|
|
|
|
-// onTouchMove={handleTouchMove}
|
|
|
|
|
-// onTouchEnd={drawCanvas}
|
|
|
|
|
-// ref={canvasRef} />
|
|
|
|
|
-// </View>
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-// // return (
|
|
|
|
|
-// // <View className='circle-canvas'>
|
|
|
|
|
-// // <canvas
|
|
|
|
|
-// // ref={canvasRef}
|
|
|
|
|
-// // style={`width: ${canvasWidth}px; height: ${canvasHeight}px;`}
|
|
|
|
|
-// // onTouchMove={handleTouchMove}
|
|
|
|
|
-// // onTouchEnd={drawCanvas}
|
|
|
|
|
-// // />
|
|
|
|
|
-// // </View>
|
|
|
|
|
-// // );
|
|
|
|
|
-// };
|
|
|
|
|
-
|
|
|
|
|
-// export default CircleCanvas;
|
|
|