You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue Canvas带平移系统的无限网格点实现问题

Vue Canvas 无限网格高效渲染问题

我正在为Vue应用中的Canvas添加平移系统,目前已成功实现平移功能,但在高效渲染无限网格点方面遇到了挑战。

以下是我的组件代码:

<template>
  <div>
    <div>
      <canvas
        @mousedown="baseEditorMouseDown"
        @mouseup="baseEditorMouseUp"
        @mousemove="baseEditorMouseMove"
        ref="baseEditor"
      ></canvas>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, type Ref, computed, onMounted } from "vue";

const baseEditor: Ref<HTMLCanvasElement | null> = ref(null);

const context: Ref<CanvasRenderingContext2D | null> = ref(null);
const gridOffset = ref(50);
const imagePosition: Ref<any> = ref({
  x: 0,
  y: 0,
});

const canvasBaseImage = ref(new Image());
const isMasking = ref(false);
const lastMaskPosition: Ref<any> = ref({
  x: 0,
  y: 0,
});

const isPanning = ref(false);
const lastClickPosition = ref({ x: 0, y: 0 });
const lastOffsetTemp = ref({ x: 0, y: 0 });
const lastOffset = ref({ x: 0, y: 0 });

const computedGridCircles = computed(() => {
  var coords = [];
  for (
    let x = -window.innerWidth + gridOffset.value / 2;
    x < window.innerWidth * 2;
    x += gridOffset.value
  ) {
    for (
      let y = -window.innerHeight + gridOffset.value / 2;
      y < window.innerHeight * 2;
      y += gridOffset.value
    ) {
      coords.push({
        x,
        y,
      });
    }
  }

  return coords;
});

function drawGridCircles() {
  if (context.value) {
    context.value.beginPath();

    for (let i = 0; i < computedGridCircles.value.length; i++) {
      const coord = computedGridCircles.value[i];
      context.value.rect(
        coord.x + lastOffsetTemp.value.x + lastOffset.value.x,
        coord.y + lastOffsetTemp.value.y + lastOffset.value.y,
        3,
        3
      );
    }
    context.value.fillStyle = "#333";
    context.value.fill();
  }
}

function baseEditorMouseMove(event: MouseEvent) {
  if (isPanning.value) {
    lastOffset.value.x = event.clientX - lastClickPosition.value.x;
    lastOffset.value.y = event.clientY - lastClickPosition.value.y;
    updatePanning();
  }
}

function baseEditorMouseDown(event: MouseEvent) {
  isPanning.value = true;
  lastClickPosition.value.x = event.clientX;
  lastClickPosition.value.y = event.clientY;
}

function baseEditorMouseUp(event: MouseEvent) {
  isMasking.value = false;
  isPanning.value = false;

  lastOffsetTemp.value.x += lastOffset.value.x;
  lastOffsetTemp.value.y += lastOffset.value.y;
}

function clearCanvas() {
  if (context.value) {
    context.value.clearRect(0, 0, window.innerWidth, window.innerHeight);
  }
}
function updatePanning() {
  clearCanvas();
  drawGridCircles();
}

onMounted(() => {
  if (baseEditor.value) {
    context.value = baseEditor.value.getContext("2d");

    baseEditor.value.width = window.innerWidth;
    baseEditor.value.height = window.innerHeight;
  }

  drawGridCircles();
});
</script>

在computedGridCircles函数中,我基于窗口尺寸计算网格点坐标,但无法实现真正的无限网格。我已参考多个相关资源,但在数学计算部分仍有缺失。

内容的提问来源于stack exchange,提问作者muzak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:53:10