美文网首页
canvas 如何绘制可拖拽的网格

canvas 如何绘制可拖拽的网格

作者: littlesunn | 来源:发表于2023-06-08 09:22 被阅读0次
image.png
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="myCanvas" width="1080" height="630"></canvas>
</body>
</html>
<script>
    // 当前 canvas 的 0 0 坐标,我们设置 canvas 左上角顶点为 0 0,向右👉和向下👇是 X Y 轴正方向,0,0 为 pageSlicePos 初始值
    const pageSlicePos = {  // 坐标系的原点
        x: 0,
        y: 0,
    };
    var scale = 10; // 缩放比例
    // ----------- pageSlicePos, scale 这两个值是重点------------------

    const solidColor = '#999'; // 实线颜色
    const dashedColor = '#ccc'; // 虚线颜色
    const zeroColor = '#358bf3'; // 0 点坐标系颜色

    const myCanvas = document.querySelector('#myCanvas');
    const ctx = myCanvas.getContext('2d'); // 获取canvas上下文
    myCanvas.addEventListener("mousedown", mouseDown);
    myCanvas.addEventListener("mousewheel", mouseWheel);

    setInterval(() => {
        drawLineGrid();
    }, 0);

    /**
     * 绘制网格
     * @param scaleVal 缩放倍数
     */
    var drawLineGrid = (scaleVal = scale) => {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        /*获取绘图工具*/
        // 设置网格大小
        var girdSize = 5 * scaleVal;  // 5表示一个单位的小正方形的基本宽高大小;5 * scaleVal表示放大或缩小后的小正方形实际像素宽高大小
        // 获取Canvas的width、height
        var CanvasWidth = ctx.canvas.width;
        var CanvasHeight = ctx.canvas.height;

        // 在 pageSlicePos 的 x,y 点位画一个 10 * 10 的红色标记用来表示当前页面的 0 0 坐标
        ctx.fillStyle = 'red';
        ctx.fillRect(pageSlicePos.x - 5, pageSlicePos.y-5, 10, 10); // 效果图红色小方块

        const canvasXHeight = CanvasHeight - pageSlicePos.y;
        const canvasYWidth = CanvasWidth - pageSlicePos.x;
        // 从 pageSlicePos.y 处开始往 Y 轴正方向画 X 轴网格
        const xPageSliceTotal = Math.ceil(canvasXHeight / girdSize);   // 每隔一个单位画一条线
        for (let i = 0; i < xPageSliceTotal; i++) {
            ctx.beginPath(); // 开启路径,设置不同的样式
            ctx.moveTo(0, pageSlicePos.y + girdSize * i);
            ctx.lineTo(CanvasWidth, pageSlicePos.y + girdSize * i);
            ctx.strokeStyle = i === 0 ? zeroColor : (i % 5 === 0 ? solidColor : dashedColor); // 如果为 0 则用蓝色标记,取余 5 为实线,其余为比较淡的线
            ctx.stroke();
        }

        // 从 pageSlicePos.y 处开始往 Y 轴负方向画 X 轴网格
        const xRemaining = pageSlicePos.y;
        const xRemainingTotal = Math.ceil(xRemaining / girdSize);
        for (let i = 0; i < xRemainingTotal; i++) {
            if (i === 0) continue;
            ctx.beginPath(); // 开启路径,设置不同的样式
            ctx.moveTo(0, pageSlicePos.y - girdSize * i); // -0.5是为了解决像素模糊问题
            ctx.lineTo(CanvasWidth, pageSlicePos.y - girdSize * i);
            ctx.strokeStyle = i === 0 ? zeroColor : (i % 5 === 0 ? solidColor : dashedColor);// 如果为 0 则用蓝色标记,取余 5 为实线,其余为比较淡的线
            ctx.stroke();
        }

        // 从 pageSlicePos.x 处开始往 X 轴正方向画 Y 轴网格
        const yPageSliceTotal = Math.ceil(canvasYWidth / girdSize); // 计算需要绘画y轴的条数
        for (let j = 0; j < yPageSliceTotal; j++) {
            ctx.beginPath(); // 开启路径,设置不同的样式
            ctx.moveTo(pageSlicePos.x + girdSize * j, 0);
            ctx.lineTo(pageSlicePos.x + girdSize * j, CanvasHeight);
            ctx.strokeStyle = j === 0 ? zeroColor : (j % 5 === 0 ? solidColor : dashedColor);// 如果为 0 则用蓝色标记,取余 5 为实线,其余为比较淡的线
            ctx.stroke();
        }

        // 从 pageSlicePos.x 处开始往 X 轴负方向画 Y 轴网格
        const yRemaining = pageSlicePos.x;
        const yRemainingTotal = Math.ceil(yRemaining / girdSize);
        for (let j = 0; j < yRemainingTotal; j++) {
            if (j === 0) continue;
            ctx.beginPath(); // 开启路径,设置不同的样式
            ctx.moveTo(pageSlicePos.x - girdSize * j, 0);
            ctx.lineTo(pageSlicePos.x - girdSize * j, CanvasHeight);
            ctx.strokeStyle = j === 0 ? zeroColor : (j % 5 === 0 ? solidColor : dashedColor);// 如果为 0 则用蓝色标记,取余 5 为实线,其余为比较淡的线
            ctx.stroke();
        }
    };

    /**
     * 滚轮缩放倍数
     */
    function mouseWheel(e) {
        if (e.wheelDelta > 0) {
            if (scale < 10) {
                scale++;
            }
        } else {
            if (scale > 1) {
                scale--;
            }
        }
    }

    /**
     * 拖动 canvas 动态渲染,拖动时,动态设置 pageSlicePos 的值
     * @param e Event
     */
    function mouseDown(e) {
        const downX = e.clientX;
        const downY = e.clientY;
        const { x, y } = pageSlicePos;
        myCanvas.onmousemove = (ev) => {
            const moveX = ev.clientX;
            const moveY = ev.clientY;
            pageSlicePos.x = x + (moveX - downX);
            pageSlicePos.y = y + (moveY - downY);
            myCanvas.onmouseup = (en) => {
                myCanvas.onmousemove = null;
                myCanvas.onmouseup = null;
            };
        }
        myCanvas.onmouseup = (en) => {
            myCanvas.onmousemove = null;
            myCanvas.onmouseup = null;
        };
    }

</script> 作者:__SomeBody https://www.bilibili.com/read/cv23969868 出处:bilibili

相关文章

  • Android canvas绘制心电图

    通过蓝牙获取到心电数据,使用canvas绘制心电图及背景网格,代码如下 至此,canvas绘制心电图的代码已完成

  • Canvas学习笔记

    Canvas 学习笔记 画布创建 绘制形状 如下图所示 canvas元素默认被网格所覆盖 通常来说 网格中的一个单...

  • Android自定义控件探索之旅一6(笔记)

    上两篇文章主要介绍了Canvas如何绘制图片以及绘制图片的两种实现方式,本篇文章主要学习Canvas如何绘制文字。...

  • view绘制:draw阶段&dispatchDraw实现

    如何将View绘制到屏幕上? View --- > darw(Canvas canvas) Draw the ba...

  • canvas初识

    canvas是html5中新增的标签,用于配合js绘制图形 创建一个画布 canvas 是一个二维网格。左上角坐标...

  • html5 canvas 绘制网格

  • Android Drawable 详解

    1、Drawable 简介 Drawable——可简单理解为可绘制物,表示一些可以绘制在 Canvas 上的对象。...

  • canvas 可拖拽图片选区

    近日,在完成了毕设的大部分功能之后,指导老师认为还需要在添加一些功能,我最后决定添加一个图片编辑功能——图片编辑,...

  • SVG绘制环图

    上篇<原生Canvas绘制饼图>介绍了如何使用Canvas来绘制环图,这篇用SVG标签来实现一下。 上面是完整效果...

  • 自动寻路(二)

    上一章主要内容是如何绘制网格并尽可能降低网格的复杂度,利用最终绘制好的网格(即点之间的关系)根据A*算法就可以实现...

网友评论

      本文标题:canvas 如何绘制可拖拽的网格

      本文链接:https://www.haomeiwen.com/subject/llunedtx.html