canvas 画出vconsole

<!-- 全屏透明Canvas -->
<canvas id="overlay-canvas"></canvas>
#overlay-canvas {
  position: fixed;
  top:100px;
  left:0;
  width: 100%;
  height: 50%;
  z-index: 1000000;
}
<script>
window.addEventListener('DOMContentLoaded', ()=>{
  setTimeout(() => {
    canvas.style.display = 'none'; // 允许父元素点击穿透
    canvas.style.position = 'relative'; // 允许父元素点击穿透
  }, 1500);
  const canvas = document.getElementById('overlay-canvas');
  const ctx = canvas.getContext('2d');
  function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
  }
  window.addEventListener('resize', resizeCanvas);
  resizeCanvas();
// 绘制参数
  const V_PATH = [
    {x: 0.3, y: 0.2}, // V左起点 (相对坐标)
    {x: 0.5, y: 0.4}, // V底部中点
    {x: 0.7, y: 0.2} // V右终点
  ];
 
// 转换为绝对坐标
  function getAbsolutePoints() {
    return V_PATH.map(p => ({
      x: p.x * canvas.width,
      y: p.y * canvas.height
    }));  
  }
// 触摸跟踪变量
  let isDrawing = false;
  let touchPoints = [];
  let lastTouchTime = 0;
 
// 计算两点距离
  function distance(p1, p2) {
    return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
  }
 
// 检测是否匹配V路径
  function checkVShape(points) {
    const absVPath = getAbsolutePoints();
    const tolerance = 50; // 匹配容差(像素)
 
// 1. 检查点数量是否足够
    if (points.length < 10) return false;
 
// 2. 检查总体方向是否先下后上
    const firstThird = Math.floor(points.length / 3);
    const lastThird = points.length - firstThird;
 
    const startY = points[0].y;
    const midY = points[firstThird].y;
    const endY = points[points.length-1].y;
 
    if (!(midY > startY + 50 && midY > endY + 50)) {
      return false;
    }
 
// 3. 检查是否接近预设V路径
    let matchedLeft = false;
    let matchedRight = false;
 
    for (let i = 0; i < points.length; i++) {
      const p = points[i]; 
// 检查左斜线
      if (!matchedLeft && distance(p, absVPath[0]) < tolerance &&i < points.length/2) {
        matchedLeft = true;
      } 
// 检查底部区域
      if (matchedLeft && !matchedRight &&distance(p, absVPath[1]) < tolerance) {
// 继续检查右斜线
        for (let j = i; j < points.length; j++) {
          if (distance(points[j], absVPath[2]) < tolerance) {
            matchedRight = true;
            break;
          }
        }
        break;
      }
    }
    return matchedLeft && matchedRight;
  }
 
// 触摸事件处理
  canvas.addEventListener('touchstart', (e) => {
    e.preventDefault();
    const touch = e.touches[0];
    const rect = canvas.getBoundingClientRect();
 
    touchPoints = [{
      x: touch.clientX - rect.left,
      y: touch.clientY - rect.top,
      time: Date.now()
    }];
 
    isDrawing = true;
    lastTouchTime = Date.now();
 
// 清空Canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }, { once: true });
 
  canvas.addEventListener('touchmove', (e) => {
    if (!isDrawing) return;
    e.preventDefault();
 
    const touch = e.touches[0];
    const rect = canvas.getBoundingClientRect();
    const newPoint = {
      x: touch.clientX - rect.left,
      y: touch.clientY - rect.top,
      time: Date.now()
    };
 
// 过滤太近的点
    if (touchPoints.length > 0) {
      const lastPoint = touchPoints[touchPoints.length-1];
      if (distance(lastPoint, newPoint) < 5) {
        return;
      }
    }
 
    touchPoints.push(newPoint);
    lastTouchTime = Date.now();
 
// 实时绘制路径
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.moveTo(touchPoints[0].x, touchPoints[0].y);
 
    for (let i = 1; i < touchPoints.length; i++) {
      ctx.lineTo(touchPoints[i].x, touchPoints[i].y);
    }
 
    ctx.strokeStyle = 'transparent';
    ctx.lineWidth = 8;
    ctx.lineCap = 'round';
    ctx.stroke();
  });
 
  canvas.addEventListener('touchend', (e) => {
    if (!isDrawing) return;
    e.preventDefault();
 
    isDrawing = false;
 
// 检查是否绘制了V字形
    if (checkVShape(touchPoints)) {
      console.log("V路径绘制成功!", window.vconsole);
      const vconsole = window.vconsole
      new vconsole();
// 绘制绿色成功提示
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath();
      ctx.moveTo(touchPoints[0].x, touchPoints[0].y);
 
      for (let i = 1; i < touchPoints.length; i++) {
        ctx.lineTo(touchPoints[i].x, touchPoints[i].y);
      }
 
      ctx.strokeStyle = 'transparent';
      ctx.lineWidth = 10;
      ctx.stroke();
 
// 3秒后清除
      setTimeout(() => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
      }, 3000);
    } else {
      console.log("V路径绘制失败!", touchPoints);
      setTimeout(() => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
      }, 2000);
    }
  }, { once: true });
 
// 防止页面滚动
  document.addEventListener('touchmove', (e) => {
    if (isDrawing) {
      e.preventDefault();
    }
  }, { passive: false });
});
</script>
posted @ 2025-03-31 15:10  kimsaerono  阅读(18)  评论(0)    收藏  举报