Создание настраиваемой сетки в веб-браузере

Я хочу нарисовать сетку из 10 x 10 квадратов на холсте HTML5 с номером 1-100, отображаемым на квадратах. Щелчок по квадрату должен вызвать функцию JavaScript с квадратным числом, переданным в качестве переменной в функцию.

Ответ 1

Во-первых, я рекомендую вам прочитать этот ответ на другой вопрос, связанный с холстом HTML5. Вам нужно понять, что нет квадратов. Чтобы обнаружить щелчок на квадрате, вам нужно будет отслеживать сопоставление каждой координаты холста на квадрат (ы), который он логически содержит, обрабатывать событие с одним кликом на всем холсте, выработать квадрат (ы), которые вы хотите изменить, а затем перерисовать холст с нужными изменениями.

Тогда, поскольку у вас нет возражений против использования более подходящей технологии, я рекомендую вам сделать это в любом HTML (где каждый квадрат - это что-то вроде <div>, которое абсолютно позиционируется и имеет размер и цвет используя CSS) или SVG (используя <rect>, если вам нужны квадраты для поворота или хотите ввести другие фигуры).

HTML и SVG - это режимы графического режима с сохраненным режимом, где рисунок формы "сохраняет" концепцию этой формы. Вы можете перемещать фигуру, изменять ее цвета, размер и т.д., И компьютер будет автоматически перерисовывать ее для вас. Более того, и что более важно для вашего случая использования, вы можете (как с HTML, так и с SVG):

function changeColor(evt){
  var clickedOn = evt.target;
  // for HTML
  clickedOn.style.backgroundColor = '#f00';

  // for SVG
  clickedOn.setAttribute('fill','red');
}
mySquare.addEventListener('click',changeColor,false);

Изменить. Я создал простую реализацию в JavaScript и HTML: http://jsfiddle.net/6qkdP/2/

Здесь основной код, если JSFiddle не работает:

function clickableGrid( rows, cols, callback ){
  var i=0;
  var grid = document.createElement('table');
  grid.className = 'grid';
  for (var r=0;r<rows;++r){
    var tr = grid.appendChild(document.createElement('tr'));
    for (var c=0;c<cols;++c){
      var cell = tr.appendChild(document.createElement('td'));
      cell.innerHTML = ++i;
      cell.addEventListener('click',(function(el,r,c,i){
        return function(){ callback(el,r,c,i); }
       })(cell,r,c,i),false);
    }
  }
  return grid;
}

Ответ 2

EDIT: использование HTML-элементов, а не рисование этих вещей на холсте или использование SVG - это еще один вариант и, возможно, предпочтительнее.

enter image description here

Следуя рекомендациям Phrogz, см. здесь о реализации SVG:

пример jsfiddle

document.createSvg = function(tagName) {
    var svgNS = "http://www.w3.org/2000/svg";
    return this.createElementNS(svgNS, tagName);
};

var numberPerSide = 20;
var size = 10;
var pixelsPerSide = 400;



var grid = function(numberPerSide, size, pixelsPerSide, colors) {
    var svg = document.createSvg("svg");
    svg.setAttribute("width", pixelsPerSide);
    svg.setAttribute("height", pixelsPerSide);
    svg.setAttribute("viewBox", [0, 0, numberPerSide * size, numberPerSide * size].join(" "));

    for(var i = 0; i < numberPerSide; i++) {
        for(var j = 0; j < numberPerSide; j++) {
          var color1 = colors[(i+j) % colors.length];
          var color2 = colors[(i+j+1) % colors.length];  
          var g = document.createSvg("g");
          g.setAttribute("transform", ["translate(", i*size, ",", j*size, ")"].join(""));
          var number = numberPerSide * i + j;
          var box = document.createSvg("rect");
          box.setAttribute("width", size);
          box.setAttribute("height", size);
          box.setAttribute("fill", color1);
          box.setAttribute("id", "b" + number); 
          g.appendChild(box);
          var text = document.createSvg("text");
          text.appendChild(document.createTextNode(i * numberPerSide + j));
          text.setAttribute("fill", color2);
          text.setAttribute("font-size", 6);
          text.setAttribute("x", 0);
          text.setAttribute("y", size/2);
          text.setAttribute("id", "t" + number);
          g.appendChild(text);
          svg.appendChild(g);
        }  
    }
    svg.addEventListener(
        "click",
        function(e){
            var id = e.target.id;
            if(id)
                alert(id.substring(1));
        },
        false);
    return svg;
};

var container = document.getElementById("container");
container.appendChild(grid(5, 10, 200, ["red", "white"]));
container.appendChild(grid(3, 10, 200, ["white", "black", "yellow"]));
container.appendChild(grid(7, 10, 200, ["blue", "magenta", "cyan", "cornflowerblue"]));
container.appendChild(grid(2, 8, 200, ["turquoise", "gold"]));