RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1532573
Accepted
WTFisGoingOn
WTFisGoingOn
Asked:2023-07-26 19:48:47 +0000 UTC2023-07-26 19:48:47 +0000 UTC 2023-07-26 19:48:47 +0000 UTC

如何在Canvas上制作漂亮的网格?

  • 772

您需要用细线在画布上绘制网格。我正在制作像素艺术画布。

我用了ctx.lineWidth = 0.1;,然后网格就模糊了。模糊通过放大镜非常明显。当您在绘制网格时
添加偏移量时,一切都变得很好,但是它的边​​缘进入了图片,这是一个问题,因为单元格大小只有。0.5px5х5px

为了使网格不会绘制在像素之上,我决定将绘图本身移动0.5px。结果却是相反的效果——网格清晰漂亮,画面模糊不美观。

然后我决定在 Photoshop 中绘制一个网格,画布的大小(它是固定大小)并以这种方式放置网格会更容易。Photoshop 断然拒绝绘制较小的线条1px(这是可以理解的),但我仍然决定看看会发生什么。结果,我们得到了一个均匀的网格,一个均匀的图像,但同时,每个像素现在不是5x5,但是4х4(谁会想到)

问题:如何用单元格绘制细网格5x5px,以最小的线条粗细,使网格清晰且图像本身不变形?

网格无位移:

网格无位移

带偏移的网格,图像 - 无:

带偏移的网格,图像 - 无

网格和偏移图像:

网格和偏移图像

// Canvas с сеткой без смещения
var canvas = document.getElementById('example1');
var ctx = canvas.getContext('2d');

//Рисуем пиксели для наглядности
  ctx.fillStyle = "yellow";
  ctx.fillRect(20, 20, 5, 5);
  ctx.fillRect(20, 30, 5, 5);
  ctx.fillRect(30, 30, 5, 5);
  
//Задаём толщину линии и цвет
ctx.lineWidth = 0.1;
ctx.strokeStyle = "red"

// Рисуем вертикальные линии
for (var x = 0; x < canvas.width; x += 5) {
  ctx.beginPath();
  ctx.moveTo(x, 0);
  ctx.lineTo(x, canvas.height);
  ctx.stroke();
}

// Рисуем горизонтальные линии
for (var y = 0; y < canvas.height; y += 5) {
  ctx.beginPath();
  ctx.moveTo(0, y);
  ctx.lineTo(canvas.width, y);
  ctx.stroke();
}

// Canvas с сеткой со смещением в 0.5
var canvas = document.getElementById('example2');
var ctx = canvas.getContext('2d');

//Рисуем пиксели для наглядности
  ctx.fillStyle = "yellow";
  ctx.fillRect(20, 20, 5, 5);
  ctx.fillRect(20, 30, 5, 5);
  ctx.fillRect(30, 30, 5, 5);
  
//Задаём толщину линии и цвет
ctx.lineWidth = 0.1;
ctx.strokeStyle = "red"

// Рисуем вертикальные линии
for (var x = 0.5; x < canvas.width; x += 5) {
  ctx.beginPath();
  ctx.moveTo(x, 0);
  ctx.lineTo(x, canvas.height);
  ctx.stroke();
}

// Рисуем горизонтальные линии
for (var y = 0.5; y < canvas.height; y += 5) {
  ctx.beginPath();
  ctx.moveTo(0, y);
  ctx.lineTo(canvas.width, y);
  ctx.stroke();
}

// Canvas с сеткой со смещением в 0.5
var canvas = document.getElementById('example3');
var ctx = canvas.getContext('2d');

//Рисуем пиксели для наглядности
  ctx.fillStyle = "yellow";
  ctx.fillRect(20.5, 20.5, 5, 5);
  ctx.fillRect(20.5, 30.5, 5, 5);
  ctx.fillRect(30.5, 30.5, 5, 5);
  
//Задаём толщину линии и цвет
ctx.lineWidth = 0.1;
ctx.strokeStyle = "red"

// Рисуем вертикальные линии
for (var x = 0.5; x < canvas.width; x += 5) {
  ctx.beginPath();
  ctx.moveTo(x, 0);
  ctx.lineTo(x, canvas.height);
  ctx.stroke();
}

// Рисуем горизонтальные линии
for (var y = 0.5; y < canvas.height; y += 5) {
  ctx.beginPath();
  ctx.moveTo(0, y);
  ctx.lineTo(canvas.width, y);
  ctx.stroke();
}
canvas{
background-color: lightgrey;
}
<p>Canvas с сеткой без смещения</p>
<canvas id="example1" width="100" height="100"></canvas>

<p>Canvas с сеткой со смещением в 0.5</p>
<canvas id="example2" width="100" height="100"></canvas>

<p>Canvas с сеткой со смещением в 0.5 и смещением изображения</p>
<canvas id="example3" width="100" height="100"></canvas>

javascript
  • 1 1 个回答
  • 31 Views

1 个回答

  • Voted
  1. Best Answer
    Eennou
    2023-07-26T20:40:00Z2023-07-26T20:40:00Z

    您可以在保持画布大小的同时提高画布的分辨率。增加画布,保持尺寸:

    canvas.style.width = canvas.width + "px";
    canvas.style.height = canvas.height + "px";
    var scale = 2;
    canvas.width = canvas.width * scale;
    canvas.height = canvas.height * scale;
    

    更改 ctx 比例以在相同坐标处绘制

    ctx.scale(scale, scale);
    

    所有代码:

    // Canvas с сеткой без смещения
    var canvas = document.getElementById('example1');
    canvas.style.width = canvas.width + "px";
    canvas.style.height = canvas.height + "px";
    var scale = 2;
    canvas.width = canvas.width * scale;
    canvas.height = canvas.height * scale;
    var ctx = canvas.getContext('2d');
    ctx.scale(scale, scale);
    
    //Рисуем пиксели для наглядности
      ctx.fillStyle = "yellow";
      ctx.fillRect(20, 20, 5, 5);
      ctx.fillRect(20, 30, 5, 5);
      ctx.fillRect(30, 30, 5, 5);
      
    //Задаём толщину линии и цвет
    ctx.lineWidth = 0.1;
    ctx.strokeStyle = "red"
    
    // Рисуем вертикальные линии
    for (var x = 0; x < canvas.width; x += 5) {
      ctx.beginPath();
      ctx.moveTo(x, 0);
      ctx.lineTo(x, canvas.height);
      ctx.stroke();
    }
    
    // Рисуем горизонтальные линии
    for (var y = 0; y < canvas.height; y += 5) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(canvas.width, y);
      ctx.stroke();
    }
    
    // Canvas с сеткой со смещением в 0.5
    var canvas = document.getElementById('example2');
    canvas.style.width = canvas.width + "px";
    canvas.style.height = canvas.height + "px";
    var scale = 2;
    canvas.width = canvas.width * scale;
    canvas.height = canvas.height * scale;
    var ctx = canvas.getContext('2d');
    ctx.scale(scale, scale);
    
    //Рисуем пиксели для наглядности
      ctx.fillStyle = "yellow";
      ctx.fillRect(20, 20, 5, 5);
      ctx.fillRect(20, 30, 5, 5);
      ctx.fillRect(30, 30, 5, 5);
      
    //Задаём толщину линии и цвет
    ctx.lineWidth = 0.1;
    ctx.strokeStyle = "red"
    
    // Рисуем вертикальные линии
    for (var x = 0.5; x < canvas.width; x += 5) {
      ctx.beginPath();
      ctx.moveTo(x, 0);
      ctx.lineTo(x, canvas.height);
      ctx.stroke();
    }
    
    // Рисуем горизонтальные линии
    for (var y = 0.5; y < canvas.height; y += 5) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(canvas.width, y);
      ctx.stroke();
    }
    
    // Canvas с сеткой со смещением в 0.5
    var canvas = document.getElementById('example3');
    canvas.style.width = canvas.width + "px";
    canvas.style.height = canvas.height + "px";
    var scale = 2;
    canvas.width = canvas.width * scale;
    canvas.height = canvas.height * scale;
    var ctx = canvas.getContext('2d');
    ctx.scale(scale, scale);
    
    //Рисуем пиксели для наглядности
      ctx.fillStyle = "yellow";
      ctx.fillRect(20.5, 20.5, 5, 5);
      ctx.fillRect(20.5, 30.5, 5, 5);
      ctx.fillRect(30.5, 30.5, 5, 5);
      
    //Задаём толщину линии и цвет
    ctx.lineWidth = 0.1;
    ctx.strokeStyle = "red"
    
    // Рисуем вертикальные линии
    for (var x = 0.5; x < canvas.width; x += 5) {
      ctx.beginPath();
      ctx.moveTo(x, 0);
      ctx.lineTo(x, canvas.height);
      ctx.stroke();
    }
    
    // Рисуем горизонтальные линии
    for (var y = 0.5; y < canvas.height; y += 5) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(canvas.width, y);
      ctx.stroke();
    }
    canvas {
      background-color: lightgrey;
    }
    <p>Canvas с сеткой без смещения</p>
    <canvas id="example1" width="100px" height="100px"></canvas>
    
    <p>Canvas с сеткой со смещением в 0.5</p>
    <canvas id="example2" width="100px" height="100px"></canvas>
    
    <p>Canvas с сеткой со смещением в 0.5 и смещением изображения</p>
    <canvas id="example3" width="100px" height="100px"></canvas>

    • 1

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5