Javascript: сетка из правильных шестиугольников на канве
Одноразово для ребёнка, так как аналогии с пчелиными сотами не хватило. Дело в том, что в сказку про Ёжку-Кошку неожиданно вкралась Вавилонская библиотека - пожалуй, лучшее из известных мне художественных произведений вообще, я не преувеличиваю :)
Как известно, Кот и Таракан (из Другой Сказки, те самые, что едва не стрясли Дерево Мира), в итоге оказались в Лесу, где Кот, наконец, смог поселиться на берегу молочной реки с кисельными берегами, а Таракан стал библиотекарем в замке Волшебника.
Когда они всё же собрались снова, Ёжка-Кошка привезла Кота и Таракана на ковре-самолёте в Замок. Волшебника не было дома, а эти трое ухитрились заблудиться в Бесконечной Библиотеке Волшебника, которая снаружи казалась просто пыльным скопищем из нескольких стеллажей, а внутри представляла собой правильную сетку гексов, заставленных рандомными книгами. Двери, стеллажи и угловые удобства в виде кроваток, санузлов и Неправильных Автоматов для заказа пищи (они работали, но всегда выдавали не то, что ты заказал), я рисовать поленился, а вот саму сеточку из шестиугольников - пожалуйста (javascript + canvas). Текущая комната меняется движением мыши.
Исходник вместе с обрамлением HTML - под катом. Он может быть сохранён как файл типа .html в кодировке Юникод (UTF-8).
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Hexagons on canvas</title> </head> <body> <canvas id="hexagonCanvas" width="460" height="400" style="border: 0; display: block; margin: 0 auto;"> Извините, ваш браузер не поддерживает тег canvas </canvas> <script type="text/javascript"> (function() { var canvas = document.getElementById('hexagonCanvas'); var hexHeight, hexRadius, hexRectangleHeight, hexRectangleWidth, hexagonAngle = 0.523598776, //30 градусов в радианах sideLength = 32, //длина стороны, пискелов boardWidth = 8, //ширина "доски" по вертикали boardHeight = 8; //высота "доски" по вертикали hexHeight = Math.sin(hexagonAngle) * sideLength; hexRadius = Math.cos(hexagonAngle) * sideLength; hexRectangleHeight = sideLength + 2 * hexHeight; hexRectangleWidth = 2 * hexRadius; if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.fillStyle = "#000000"; ctx.strokeStyle = "#333333"; ctx.lineWidth = 2; drawBoard(ctx, boardWidth, boardHeight); //первичная отрисовка canvas.addEventListener("mousemove", function(eventInfo) { //слушатель перемещения мыши var x = eventInfo.offsetX || eventInfo.layerX; var y = eventInfo.offsetY || eventInfo.layerY; var hexY = Math.floor(y / (hexHeight + sideLength)); var hexX = Math.floor((x - (hexY % 2) * hexRadius) / hexRectangleWidth); var screenX = hexX * hexRectangleWidth + ((hexY % 2) * hexRadius); var screenY = hexY * (hexHeight + sideLength); ctx.clearRect(0, 0, canvas.width, canvas.height); drawBoard(ctx, boardWidth, boardHeight); //перерисовка на mousemove //На доске ли координаты грызуна? if (hexX >= -boardWidth/2 && hexX <= boardWidth) { if (hexY >= -boardHeight/2 && hexY <= boardHeight) { ctx.fillStyle = "#008000"; drawHexagon (ctx, screenX, screenY, true); } } }); } function drawBoard (canvasContext, width, height) { for (var i = 0; i < width; i++) { for (var j = 0; j < height; j++) { drawHexagon (ctx, i * hexRectangleWidth + ((j % 2) * hexRadius), j * (sideLength + hexHeight), false); } } } function drawHexagon (canvasContext, x, y, fill) { var fill = fill || false; canvasContext.beginPath(); canvasContext.moveTo (x + hexRadius, y); canvasContext.lineTo (x + hexRectangleWidth, y + hexHeight); canvasContext.lineTo (x + hexRectangleWidth, y + hexHeight + sideLength); canvasContext.lineTo (x + hexRadius, y + hexRectangleHeight); canvasContext.lineTo (x, y + sideLength + hexHeight); canvasContext.lineTo (x, y + hexHeight); canvasContext.closePath(); if (fill) canvasContext.fill(); else canvasContext.stroke(); } })(); </script> <noscript><div>Извините, требуется включённый Javascript для работы приложения!</div></noscript> </body></html>
17.11.2017, 23:43 [3918 просмотров]