Html 如何使用 html5 和(画布或 svg)绘制网格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14208673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 04:48:31  来源:igfitidea点击:

how to draw grid using html5 and (canvas or svg)

htmlsvghtml5-canvas

提问by Sandeep Kumar

I want to draw a grid as shown in image but I totally don't have idea that where should I begin. Should I use SVGor should I use Canvaswith HTML5and how to draw it.
Please guide on this. I want this grid to draw rectangle, circle or other diagrams on it and I will calculate area of that diagram like area of square.

我想画一个如图所示的网格,但我完全不知道我应该从哪里开始。我应该使用SVG还是应该使用带有HTML5 的Canvas以及如何绘制它。 请对此进行指导。我希望这个网格在其上绘制矩形、圆形或其他图表,我将计算该图表的面积,如正方形面积。

enter image description here

在此处输入图片说明

回答by Thomas W

SVG can do this nicely using patterns:

SVG 可以使用模式很好地做到这一点:

<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="smallGrid" width="8" height="8" patternUnits="userSpaceOnUse">
      <path d="M 8 0 L 0 0 0 8" fill="none" stroke="gray" stroke-width="0.5"/>
    </pattern>
    <pattern id="grid" width="80" height="80" patternUnits="userSpaceOnUse">
      <rect width="80" height="80" fill="url(#smallGrid)"/>
      <path d="M 80 0 L 0 0 0 80" fill="none" stroke="gray" stroke-width="1"/>
    </pattern>
  </defs>

  <rect width="100%" height="100%" fill="url(#grid)" />
</svg>

I set widthand heightto 100%, so you can define the actual width and height on use, either for inline SVG:

我将width和设置height100%,因此您可以为内联 SVG 定义实际使用的宽度和高度:

<div style="width:400px;height:300px">
  <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <pattern id="smallGrid" width="8" height="8" patternUnits="userSpaceOnUse">
        <path d="M 8 0 L 0 0 0 8" fill="none" stroke="gray" stroke-width="0.5"/>
      </pattern>
      <pattern id="grid" width="80" height="80" patternUnits="userSpaceOnUse">
        <rect width="80" height="80" fill="url(#smallGrid)"/>
        <path d="M 80 0 L 0 0 0 80" fill="none" stroke="gray" stroke-width="1"/>
      </pattern>
    </defs>

    <rect width="100%" height="100%" fill="url(#grid)" />
  </svg>
</div>

or an <img>element:

或一个<img>元素:

<img src="https://svgshare.com/i/9Eo.svg" width="700" height="200"/>

results in:

结果是:

<img src="https://svgshare.com/i/9Eo.svg" width="241" height="401"/>

results in

结果是

Note that for this particular grid you have to use widths and heights of the form n x 80 + 1(with nbeing any integer) if you want the grid to start and end with a thick stroke.

请注意,对于这个特定的网格,如果您希望网格以粗笔画开始和结束,则必须使用表单的宽度和高度n x 80 + 1(可以n是任何整数)。

回答by Tanzeel Kazi

I am posting my code using canvashere on SO but I am also creating a working sample on JSFiddle here.

canvas在 SO 上使用here发布我的代码,但我也在此处在 JSFiddle 上创建了一个工作示例。

<!DOCTYPE html>
<html>
<head>
    <title>StackOverflow test bed</title>
    <script type="text/javascript">
        function drawGrid() {
            var cnv = document.getElementById("cnv");

            var gridOptions = {
                minorLines: {
                    separation: 5,
                    color: '#00FF00'
                },
                majorLines: {
                    separation: 30,
                    color: '#FF0000'
                }
            };

            drawGridLines(cnv, gridOptions.minorLines);
            drawGridLines(cnv, gridOptions.majorLines);

            return;
        }

        function drawGridLines(cnv, lineOptions) {


            var iWidth = cnv.width;
            var iHeight = cnv.height;

            var ctx = cnv.getContext('2d');

            ctx.strokeStyle = lineOptions.color;
            ctx.strokeWidth = 1;

            ctx.beginPath();

            var iCount = null;
            var i = null;
            var x = null;
            var y = null;

            iCount = Math.floor(iWidth / lineOptions.separation);

            for (i = 1; i <= iCount; i++) {
                x = (i * lineOptions.separation);
                ctx.moveTo(x, 0);
                ctx.lineTo(x, iHeight);
                ctx.stroke();
            }


            iCount = Math.floor(iHeight / lineOptions.separation);

            for (i = 1; i <= iCount; i++) {
                y = (i * lineOptions.separation);
                ctx.moveTo(0, y);
                ctx.lineTo(iWidth, y);
                ctx.stroke();
            }

            ctx.closePath();

            return;
        }

    </script>
</head>
<body onload="drawGrid()">
    <canvas id="cnv" width="500" height="500"></canvas>
</body>
</html>

Using the canvasapproach you can make the grid size dynamic by changing the separationparameter.

使用该canvas方法,您可以通过更改separation参数使网格大小动态化。

However, if your grid size is going to be staticI feel that maybeyou don't need to drawthe grid. Just for the sake of displaying a grid to the user you could use CSS to repeat a background image as demonstrated in the fiddle here. That will also be good on page performance.

但是,如果您的网格大小将是静态的,我觉得您可能不需要绘制网格。只是为了显示网格可以使用CSS重复的背景图像作为小提琴证明用户着想这里。这对页面性能也有好处。

回答by Ben Crowhurst

In the interest of coverage, how about a CSS based approach?

为了便于报道,基于 CSS 的方法如何?

<!DOCTYPE html>
<html>
  <head>
      <style>
      html {
        height: 100%;
      }

      body {
        margin: 0;
        padding: 0;
        height: 100%;
        background-color: #434343;    
        background-size: 75px 75px;
        background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent);
      }

      canvas {
          width:100%;
          height:100%;
          position:absolute;

          background-color: transparent;
          background-size: 15px 15px;
          background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent);
      }

      </style>
  </head>
  <body>
      <canvas></canvas>
  </body>
</html>

回答by bjorke

it's very easy to do using canvas, that's what I recommend. I'm responding quickly on mobile here, but you should get the idea even if the psuedocode below isn't EXACTLY right:

使用画布很容易做到,这就是我推荐的。我在这里在移动设备上快速响应,但即使下面的伪代码不完全正确,您也应该明白这个想法:

you'll have a loop something like:

你会有一个类似的循环:

// "Ctx" is your canvas context
// "Width," "Height," and other vars that start with a capital letter are set according
//   to your canvas size or preference

var i;
for (i=0; i < Height; i += GridSize) {
   ctx.lineWidth(1.0+((i%10)==0));
   ctx.moveTo(0,i);
   ctx.lineTo(Width,i);
   ctx.stroke();
}
for (i=0; i < Width; i += GridSize) {
   ctx.lineWidth(1.0+((i%10)==0));
   ctx.moveTo(i,0);
   ctx.lineTo(i,Height);
   ctx.stroke();
}