Wie zeichnet man ein Raster mit HTML5 und (Canvas oder SVG)


77

Ich möchte ein Raster wie im Bild gezeigt zeichnen, habe aber keine Ahnung, wo ich anfangen soll. Soll ich SVG verwenden oder sollte ich Canvas mit HTML5 verwenden und wie man es zeichnet.
Bitte führen Sie dazu. Ich möchte, dass dieses Gitter Rechtecke, Kreise oder andere Diagramme darauf zeichnet, und ich werde die Fläche dieses Diagramms wie die Fläche des Quadrats berechnen.

Geben Sie hier die Bildbeschreibung ein


Sie möchten nur ein Raster zeichnen? Ich möchte nicht in eine andere Richtung ablaufen, aber ich habe mich gefragt, ob Sie background-repeatein kleines Rasterbild verwenden können, um das größere Raster anzuzeigen. Wenn Sie es auf der Grundlage von Berechnungen zeichnen möchten, ist es natürlich besser, es zu verwenden canvas.
Tanzeel Kazi

Antworten:


149

SVG kann dies gut mit Mustern tun:

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

Ich setze widthund heightauf 100%, damit Sie die tatsächliche Breite und Höhe bei Verwendung definieren können, entweder für Inline-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>

oder ein <img>Element:

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

Ergebnisse in:

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

führt zu

Beachten Sie, dass Sie für dieses bestimmte Raster Breiten und Höhen des Formulars n x 80 + 1(mit neiner beliebigen Ganzzahl) verwenden müssen, wenn das Raster mit einem dicken Strich beginnen und enden soll.


Wenn Sie ein flexibleres Raster benötigen, um festzustellen, wie groß der Abstand zwischen den Rasterlinien ist oder welche Farbe, Strichbreite und Hintergrundfarbe verwendet werden, können Sie dies ebenfalls problemlos tun. Fragen Sie einfach, ob Sie hierzu weitere Hilfe benötigen.
Thomas W

Diese Lösung gefällt mir sehr gut. In Firefox und Safari scheint es jedoch Rundungsfehler zu geben, die dazu führen, dass das kleine und das große Raster nicht perfekt ausgerichtet sind, wenn das SVG sehr groß gedehnt wird (durch Festlegen von: 100% und Verwenden eines sehr kleinen Ansichtsfensters): imgur.com/ qitOro2 gibt es eine Möglichkeit, dies zu beheben?
Laszlo Korte

Es funktioniert gut mit dünnen Linien, wenn Sie die Strichbreiten erhöhen (versuchen Sie es beispielsweise mit 4.0), treten einige asymetrische Probleme auf.
Guid

@ThomasW Wie ändern wir, wie breit die Gitterlinien sind?
Gaurav Ramanan

10

Ich poste meinen Code canvashier auf SO, aber ich erstelle hier auch ein funktionierendes Beispiel für 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>

Mit dem canvasAnsatz können Sie die Rastergröße dynamisch gestalten, indem Sie den separationParameter ändern .

Wenn Ihre Rastergröße jedoch statisch sein soll , müssen Sie das Raster möglicherweise nicht zeichnen . Nur um dem Benutzer ein Raster anzuzeigen, können Sie mit CSS ein Hintergrundbild wiederholen, wie in der Geige hier gezeigt . Das ist auch eine gute Leistung auf der Seite.


Ist es möglich, die Strichbreite auf diesen Linien zu reduzieren? Ich habe versucht, eine Zahl unter 1 zu verwenden. Funktioniert im obigen SVG-Beispiel hervorragend, aber ich kann die Knusprigkeit mit dieser Canvas-Lösung nicht reproduzieren.
JohnDevelops

1
Die Schärfe, auf die Sie sich beziehen, ist darauf zurückzuführen, wie Leinwand Linien rendert. Lesen Sie diesen Artikel mobtowers.com/html5-canvas-crisp-lines-every-time . Haben Sie auch eine aktualisierte jsFiddle für Sie jsfiddle.net/B2EBw/137
Tanzeel Kazi

6

Wie wäre es mit einem CSS-basierten Ansatz im Interesse der Berichterstattung?

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

4

Es ist sehr einfach, Leinwand zu verwenden, das empfehle ich. Ich reagiere hier schnell auf dem Handy, aber Sie sollten auf die Idee kommen, auch wenn der Pseudocode unten nicht genau richtig ist:

Sie haben eine Schleife wie:

// "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();
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.