Leon hace 2 años
padre
commit
3d36f84f2a
Se han modificado 2 ficheros con 321 adiciones y 56 borrados
  1. 1 1
      src/app.config.ts
  2. 320 55
      src/pages/demo.tsx

+ 1 - 1
src/app.config.ts

@@ -1,6 +1,6 @@
 const appConfig = defineAppConfig({
   pages: [
-    // 'pages/demo',
+    'pages/demo',
     'pages/Clock',
     'pages/index/index',
     'pages/Login',

+ 320 - 55
src/pages/demo.tsx

@@ -1,68 +1,333 @@
 import Taro from '@tarojs/taro';
-import { View, Canvas } from '@tarojs/components';
-import { useRef, useState } from 'react';
-
-function MyComponent() {
-  const [ringX, setRingX] = useState(150);
-  const [ringY, setRingY] = useState(150);
-  const [dotX, setDotX] = useState(150);
-  const [dotY, setDotY] = useState(50);
-  const touchStartRef = useRef({ x: 0, y: 0 });
-  const dotRef = useRef<any>(null);
+import { Canvas, View } from '@tarojs/components';
+import { useEffect, useRef } from 'react';
+
+export default function Demo() {
   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; // 获取设备的像素比
+
+  const canvasId = 'canvasId';
+
+  var canDrag = false;
+  var canStartDrag = false;
+  var canEndDrag = false;
+  var canRingDrag = false;
+
+  var currentContext;
+
+  var startAngle,endAngle;
+  var lastAngle;
+
+  useEffect(() => {
+
+    const query = Taro.createSelectorQuery();
+    query.select(`.${canvasId}`).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');
+      currentContext = ctx;
+
+      // 设置画布尺寸
+      ctx.scale(dpr, dpr);
+
+
+      drawCanvas(ctx);
+    });
+  }, []);
+
+  const drawCanvas = (ctx: any) => {
+    ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+
+    // 绘制圆环
+    const centerX = canvasWidth / 2;
+    const centerY = canvasHeight / 2;
+    const radius = Math.min(centerX, centerY) - 10;
+
+    ctx.beginPath();
+    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
+    ctx.strokeStyle = "rgba(0,0,0,0.5)";
+    ctx.lineWidth = 10;
+    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.arc(centerX, centerY, radius, startAngle, endAngle);
+    ctx.strokeStyle = canRingDrag?"red":"rgba(255,0,0,0.5)";
+    ctx.lineWidth = 10;
+    ctx.stroke();
 
-  const handleTouchStart = (e) => {
-    const { clientX, clientY } = e.touches[0];
-    touchStartRef.current = { x: clientX, y: clientY };
+
+    ctx.beginPath();
+    ctx.arc(pointX, pointY, 5, 0, 2 * Math.PI);
+    ctx.fillStyle = '#00ff00';
+    ctx.fill();
+
+    
+
+    
+
+    ctx.beginPath();
+    ctx.arc(pointEndX, pointEndY, 5, 0, 2 * Math.PI);
+    ctx.fillStyle = 'blue';
+    ctx.fill();
   };
 
-  const handleTouchMove = (e) => {
-    const { clientX, clientY } = e.touches[0];
-    const deltaX = clientX - touchStartRef.current.x;
-    const deltaY = clientY - touchStartRef.current.y;
-    const newDotX = dotX + deltaX;
-    const newDotY = dotY + deltaY;
-    const distance = Math.sqrt((newDotX - ringX) ** 2 + (newDotY - ringY) ** 2);
-
-    if (distance <= 50) {
-      setDotX(newDotX);
-      setDotY(newDotY);
+  function twoPointDistance(p1, p2) {
+    let dep = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2));
+    return dep;
+  }
+
+  const handleTouchMove = (e: any) => {
+    if (!canStartDrag && !canEndDrag && !canRingDrag){
+      return;
+    }
+    const ctx = currentContext;//canvasRef.current.getContext('2d');
+    ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+    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)
+
+    if (canStartDrag){
+      startAngle = angle;
     }
 
-    touchStartRef.current = { x: clientX, y: clientY };
-    drawRingAndDot();
+    if (canEndDrag){
+      endAngle = angle;
+    }
+
+    if (canRingDrag){
+      console.log(`lastAngle:${lastAngle}  angle:${angle}`)
+      let delta = angle - lastAngle;
+      startAngle += delta;
+      endAngle += delta;
+      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;
+
+    ctx.beginPath();
+    ctx.arc(pointX2, pointY2, 5, 0, 2 * Math.PI);
+    ctx.fillStyle = 'blue';
+    ctx.fill();
   };
 
-  const drawRingAndDot = () => {
-    const context = Taro.createCanvasContext('myCanvas', this.$scope);
-    context.clearRect(0, 0, 300, 300);
-    context.beginPath();
-    context.arc(ringX, ringY, 50, 0, 2 * Math.PI);
-    context.setStrokeStyle('gray');
-    context.setLineWidth(10);
-    context.stroke();
-    context.closePath();
-
-    context.beginPath();
-    context.arc(dotX, dotY, 10, 0, 2 * Math.PI);
-    context.setFillStyle('red');
-    context.fill();
-    context.closePath();
-
-    context.draw();
+  const handleClick = (e) => {
+
+    const scaleX = 1//dpr//canvasRect.width / canvasRect.width;
+    const scaleY = 1//dpr//canvasRect.height / canvasRect.height;
+    const canvasX = (e.touches[0].x - 0) * scaleX;
+    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 centerY = canvasWidth / 2;
+    const radius = Math.min(centerX, centerY) - 10;
+
+
+    const pointX = centerX + Math.cos(startAngle) * radius;
+    const pointY = centerY + Math.sin(startAngle) * radius;
+    const distance = Math.sqrt(Math.pow(canvasX - pointX, 2) + Math.pow(canvasY - pointY, 2));
+
+    if (distance <= 5) {
+      canStartDrag = true;
+    } else {
+      canStartDrag = false;
+    }
+
+    const pointX2 = centerX + Math.cos(endAngle) * radius;
+    const pointY2 = centerY + Math.sin(endAngle) * radius;
+    const distance2 = Math.sqrt(Math.pow(canvasX - pointX2, 2) + Math.pow(canvasY - pointY2, 2));
+
+    if (distance2 <= 5) {
+      canEndDrag = true;
+    } else {
+      canEndDrag = false;
+    }
+
+    if (canStartDrag || canEndDrag){
+      canRingDrag = false;
+      return;
+    }
+
+    const distance3 = twoPointDistance({x:canvasX,y:canvasY},{x:centerX,y:centerY});
+    let angle = Math.atan2(canvasY-canvasWidth/2.0, canvasX-canvasWidth/2.0)
+    if (distance3>80&& distance3<105 && startAngle<angle && angle<endAngle){
+      canRingDrag = true;
+      console.log("canRingDrag")
+    }
+    console.log(distance3);
+    lastAngle = angle;
   };
 
-  return (
-    <View>
-      <Canvas
-        id="myCanvas"
-        style={{ width: '300px', height: '300px' }}
-        onTouchStart={handleTouchStart}
-        onTouchMove={handleTouchMove}
-        ref={canvasRef}
-      />
-    </View>
-  );
+  const handleTouchEnd = (e) =>{
+    canStartDrag = false;
+    canEndDrag = false;
+    canRingDrag = false;
+    console.log('end')
+    handleTouchMove(e)
+  }
+
+  return <View style={{ width: '100%', height: 600, backgroundColor: 'white' }}>
+    <Canvas canvasId={canvasId} id={canvasId} className={canvasId} type="2d"
+      style={{ width: 300, height: 300, zIndex: 0, backgroundColor: 'yellow' }}
+      onTouchMove={handleTouchMove}
+      onTouchEnd={handleTouchEnd}
+      onTouchStart={handleClick}
+      ref={canvasRef} />
+  </View>
 }
 
-export default MyComponent;
+// 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;