2013-01-08 15 views
59

Tôi muốn vẽ một lưới như được hiển thị trong hình ảnh nhưng tôi hoàn toàn không có ý tưởng rằng nơi tôi nên bắt đầu. Tôi có nên sử dụng SVG hoặc tôi nên sử dụng Canvas với HTML5 và cách vẽ.
Vui lòng hướng dẫn về điều này. Tôi muốn lưới này để vẽ hình chữ nhật, hình tròn hoặc sơ đồ khác trên nó và tôi sẽ tính diện tích của sơ đồ đó như diện tích hình vuông.làm thế nào để vẽ lưới bằng cách sử dụng html5 và (canvas hoặc svg)

enter image description here

+0

Bạn chỉ muốn vẽ lưới?Tôi không muốn đi theo hướng khác nhưng tôi đã tự hỏi bạn có thể 'background-repeat' một hình ảnh lưới nhỏ để hiển thị lưới lớn hơn. Tất nhiên nếu bạn muốn vẽ nó dựa trên tính toán thì bạn nên sử dụng 'canvas'. –

Trả lời

106

SVG có thể làm điều này độc đáo sử dụng các mẫu:

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

tôi đặt widthheight để 100%, vì vậy bạn có thể xác định chiều rộng và chiều cao thực tế về việc sử dụng, hoặc cho SVG inline:

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

hoặc một <img> yếu tố:

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

kết quả trong:

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

kết quả trong

Lưu ý rằng đối với lưới cụ thể này, bạn phải sử dụng chiều rộng và chiều cao của biểu mẫu n x 80 + 1 (với n là bất kỳ số nguyên nào) nếu bạn muốn lưới bắt đầu và kết thúc bằng nét dày.

+0

Nếu bạn cần một mạng lưới linh hoạt hơn về khoảng cách giữa các đường lưới là bao nhiêu, hoặc màu gì, chiều rộng nét và màu nền được sử dụng, điều này có thể dễ dàng được thực hiện là tốt. Vui lòng hỏi nếu bạn cần thêm bất kỳ trợ giúp nào về vấn đề này. –

+0

Tôi thực sự thích giải pháp này. Tuy nhiên trong firefox và safari nếu svg có được kéo dài thực sự lớn (bằng cách thiết lập với: 100% và sử dụng một khung nhìn thực sự nhỏ) có vẻ như làm tròn lỗi gây ra lưới nhỏ và lưới lớn không căn chỉnh hoàn hảo: http: // imgur.com/qitOro2 có cách nào để sửa lỗi này không? –

+2

điều này là rực rỡ – xxstevenxo

10

Tôi gửi bài mã của tôi sử dụng canvas đây trên SO nhưng tôi cũng đang tạo ra một mẫu làm việc trên 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> 

Sử dụng cách tiếp cận canvas bạn có thể làm cho kích thước lưới năng động bằng cách thay đổi các tham số separation.

Tuy nhiên, nếu kích thước lưới của bạn sẽ là tĩnh Tôi cảm thấy rằng lẽ bạn không cần phải vẽ lưới điện. Chỉ vì mục đích hiển thị lưới cho người dùng, bạn có thể sử dụng CSS để lặp lại hình nền như được minh họa trong fiddle here. Điều đó cũng sẽ tốt về hiệu suất trang.

+0

Có thể giảm chiều rộng đột quỵ trên các dòng này không? Tôi đã cố gắng sử dụng một số ít hơn 1. Hoạt động tuyệt vời trong ví dụ SVG ở trên nhưng tôi không thể tái tạo độ sắc nét của nó với giải pháp Canvas này. – JohnDevelops

+1

Độ giòn mà bạn đang đề cập đến là do cách canvas hiển thị đường kẻ. Tham khảo bài viết này http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/. Cũng có một jsFiddle cập nhật cho bạn http://jsfiddle.net/B2EBw/137/ –

4

rất dễ dàng để thực hiện bằng canvas, đó là những gì tôi đề xuất. Tôi đang trả lời một cách nhanh chóng trên điện thoại di động ở đây, nhưng bạn sẽ nhận được các ý tưởng ngay cả khi psuedocode dưới đây là không chính xác đúng:

bạn sẽ có một cái gì đó vòng lặp như:

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

Vì lợi ích của mức độ phù hợp, cách tiếp cận dựa trên 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

Đã thêm jsfiddle cho câu trả lời ở trên - https://jsfiddle.net/3pfc4avp/ – Murukesh