2013-01-08 13 views
59

Chcę narysować siatkę, jak pokazano na obrazku, ale zupełnie nie mam pojęcia, od czego mam zacząć. Czy powinienem użyć SVG, czy też powinienem użyć Płótno z HTML5 i jak go narysować.
Proszę o poradę na ten temat. Chcę, aby ta siatka narysowała na niej prostokąt, okrąg lub inne diagramy, a ja obliczyłbym obszar tego diagramu, jak obszar kwadratu.jak narysować siatkę używając html5 i (płótno lub svg)

enter image description here

+0

Po prostu chcesz narysować siatkę?Nie chcę podążać w innym kierunku, ale zastanawiałem się, czy można "powtórzyć tło" małego obrazu siatki, aby wyświetlić większą siatkę. Oczywiście, jeśli chcesz narysować ją na podstawie obliczeń, lepiej jest użyć 'canvas'. –

Odpowiedz

106

SVG można to zrobić ładnie wykorzystujące wzory:

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

ustawić width i height do 100%, więc można określić rzeczywistą szerokość i wysokość w użyciu, zarówno dla 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> 

lub <img> Element:

<img src="https://imgh.us/grid.svg" width="700" height="200"/> 

skutkuje:

<img src="https://imgh.us/grid.svg" width="241" height="401"/> 

Wyniki w

Należy zauważyć, że w przypadku tej konkretnej siatki należy użyć szerokości i wysokości formularza n x 80 + 1 (gdzie n jest dowolną liczbą całkowitą), jeśli chcesz, aby kratka zaczynała się i kończyła grubym obrysem.

+0

Jeśli potrzebujesz bardziej elastycznej siatki pod względem tego, jak duża jest odległość między liniami siatki, jaki jest jej kolor, szerokość obrysu i kolor tła są używane, można to łatwo zrobić również. Możesz zapytać, czy potrzebujesz dalszej pomocy w tej sprawie. –

+0

Bardzo podoba mi się to rozwiązanie. Jednak w przypadku firefox i safari, jeśli svg zostanie rozciągnięty naprawdę duże (ustawiając z: 100% i używa naprawdę małej widoczności), wydaje się, że błędy zaokrąglania powodują, że mała siatka i duża siatka nie są idealnie wyrównane: http: // imgur.com/qitOro2 Czy istnieje sposób, aby to naprawić? –

+2

to jest genialny – xxstevenxo

10

jestem delegowania mój kod korzystając canvas tutaj na SO, ale jestem również tworząc próbkę roboczą o JSFiddle here.

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

Stosując podejście canvas można dokonać rozmiar siatka dynamiczna poprzez zmianę parametru separation.

Jeśli jednak rozmiar siatki będzie statycznego czuję, że może nie trzeba do narysować siatka. W celu wyświetlania siatki użytkownikowi można użyć CSS do powtórzenia obrazu tła, jak pokazano na skrzypcach here. Będzie to również dobre na wydajności strony.

+0

Czy można zmniejszyć szerokość obrysu na tych liniach? Próbowałem użyć liczby mniejszej niż 1. Działa wspaniale w powyższym przykładzie SVG, ale nie mogę powtórzyć ostrości tego rozwiązania Canvas. – JohnDevelops

+1

Chrupkość, o której mówisz, polega na tym, że płótno renderuje linie. Zapoznaj się z tym artykułem http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/. Mam również zaktualizowany jsFiddle http://jsfiddle.net/B2EBw/137/ –

4

bardzo łatwo zrobić przy użyciu płótna, to właśnie polecam. Ja reaguje szybko na komórkę tutaj, ale należy się pomysł, nawet jeśli poniżej psuedocode nie jest dokładnie prawo:

będziesz miał coś podobnego pętli:

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

W interesie zasięgu, a co z podejściem opartym na 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> 
+1

Dodano jsfiddle dla powyższej odpowiedzi - https://jsfiddle.net/3pfc4avp/ – Murukesh

Powiązane problemy