web-dev-qa-db-fra.com

comment dessiner une grille en utilisant html5 et (canvas ou svg)

Je veux dessiner une grille comme indiqué dans l'image mais je ne sais absolument pas par où commencer. Dois-je utiliser SVG ou dois-je utiliser Canvas avec HTML5 et comment le dessiner.
Veuillez guider à ce sujet. Je veux que cette grille dessine un rectangle, un cercle ou d'autres diagrammes dessus et je calculerai l'aire de ce diagramme comme l'aire du carré.

enter image description here

63
Sandeep Kumar

SVG peut le faire très bien en utilisant des modèles:

<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>

J'ai défini width et height sur 100%, vous pouvez donc définir la largeur et la hauteur réelles à utiliser, soit pour le SVG en ligne:

<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>

ou un <img> élément:

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

résulte en:

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

résulte en

Notez que pour cette grille particulière, vous devez utiliser les largeurs et les hauteurs du formulaire n x 80 + 1 (avec n étant n'importe quel entier) si vous voulez que la grille commence et se termine par un trait épais.

126
Thomas W

Je publie mon code en utilisant canvas ici sur SO mais je crée également un exemple de travail sur JSFiddle ici .

<!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>

En utilisant l'approche canvas, vous pouvez dynamiser la taille de la grille en modifiant le paramètre separation.

Cependant, si la taille de votre grille va être statique je pense que peut-être vous n'avez pas besoin de dessiner la grille. Juste pour afficher une grille à l'utilisateur, vous pouvez utiliser CSS pour répéter une image d'arrière-plan comme illustré dans le violon ici . Ce sera également une bonne performance sur la page.

10
Tanzeel Kazi

Dans l'intérêt de la couverture, que diriez-vous d'une approche basée sur 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>
5
Ben Crowhurst

c'est très simple à faire en utilisant canvas, c'est ce que je recommande. Je réponds rapidement sur mobile ici, mais vous devriez avoir l'idée même si le pseudo-code ci-dessous n'est pas EXACTEMENT correct:

vous aurez une boucle quelque chose comme:

// "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();
}
4
bjorke