#javascript #canvas
Добрый день, может ли кто то подсказать как такое как на картинке можно нарисовать в canvas-е. План здания я нарисовал, теперь нужно сделать концентрические круги, что приставляют мощность сигнала, и там где стена, сигнал ухудшается сильнее и соответственно меняется цвет Есть точка от которой расходятся концентрические круги, возле точки сигнал 100% и постипенно он падает до 0, пускай каждый круг шириной 2px равен 1% сигнала. Стена глушит приблизитльно на 40%. Все ето нада визуализировать приблизительно так: Здесь я нарисовал план помещения и будущую точку доступа var canvas = document.querySelector("#myCanvas"); var context = canvas.getContext('2d'); //------------------------------------- определяем координаты курсора, //для передвижения нашей точки доступа var canvasPos = getPosition(canvas); var mouseX = 100; var mouseY = 100; function getPosition(el) { var xPosition = 0; var yPosition = 0; while (el) { xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft); yPosition += (el.offsetTop - el.scrollTop + el.clientTop); el = el.offsetParent; } return { x: xPosition, y: yPosition }; } function setMousePosition(e) { mouseX = e.clientX - canvasPos.x; mouseY = e.clientY - canvasPos.y; } canvas.onmousedown = function move() { canvas.addEventListener("mousemove", setMousePosition, false); }; canvas.onmouseup = function() { canvas.removeEventListener("mousemove", setMousePosition, false); }; //-------------------------------------- создаю функцию для рисованния //плана помещения var img = new Image(); var imageData; img.src = "https://s31.postimg.cc/w37y6uza3/plan1.png"; function imageOnLoad() { context.drawImage(img, 0, 0); //console.log(context.getImageData(0,0, img.width, img.height)); } //------------------------------------- function update() { // рисую план, и точку доступа var circleRadius = 10; context.clearRect(0, 0, canvas.width, canvas.height); imageOnLoad(); context.beginPath(); context.arc(mouseX, mouseY, circleRadius, 0, 2 * Math.PI, true); context.fillStyle = 'red'; context.fill(); context.closePath(); requestAnimationFrame(update); } update(); А здесь пробовал реализовать смену цвета, только не кругом а квадратами просто для наглядности (работает только в одну сторону) var canvas = document.querySelector("#myCanvas"); var context = canvas.getContext('2d'); var canvasPos = getPosition(canvas); var mouseX = 100; var mouseY = 100; //-------------------------------- определяем координаты курсора, для передвижения function getPosition(el) { var xPosition = 0; var yPosition = 0; while (el) { xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft); yPosition += (el.offsetTop - el.scrollTop + el.clientTop); el = el.offsetParent; } return { x: xPosition, y: yPosition }; } function setMousePosition(e) { mouseX = e.clientX - canvasPos.x; mouseY = e.clientY - canvasPos.y; } canvas.onmousedown = function move () { canvas.addEventListener("mousemove", setMousePosition, false); }; canvas.onmouseup = function () { canvas.removeEventListener("mousemove", setMousePosition, false); }; //----------------------------------- let colorObj = { //создаю объект с цветами 100: [255, 51, 53, 255], 90: [255, 51, 52, 255], 80: [255, 51, 51, 255], 70: [255, 255, 53, 255], 60: [255, 255, 52, 255], 50: [255, 255, 51, 255], 40: [113, 255, 53, 255], 30: [113, 255, 52, 255], 20: [113, 255, 51, 255], 10: [51, 150, 255, 255], 0: [51, 255, 243, 255] }; function update() { context.clearRect(0, 0, canvas.width, canvas.height); //----------------------- рисую линию-стену context.beginPath(); context.lineWidth = 2; context.moveTo(300 ,100); context.lineTo(300 ,300); context.stroke(); //----------------------- //------------------------ рисую набор разноцветных квадратов context.beginPath(); context.fillStyle = 'rgb(' + colorObj[100][0] + ',' + colorObj[100][1] + ',' + colorObj[100][2] + ',' + colorObj[100][3] + ')'; context.fillRect(mouseX,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[90][0] + ',' + colorObj[90][1] + ',' + colorObj[90][2] + ',' + colorObj[90][3] + ')'; context.fillRect(mouseX + 10 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[80][0] + ',' + colorObj[80][1] + ',' + colorObj[80][2] + ',' + colorObj[80][3] + ')'; context.fillRect(mouseX + 20 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[70][0] + ',' + colorObj[70][1] + ',' + colorObj[70][2] + ',' + colorObj[70][3] + ')'; context.fillRect(mouseX + 30 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[60][0] + ',' + colorObj[60][1] + ',' + colorObj[60][2] + ',' + colorObj[60][3] + ')'; context.fillRect(mouseX + 40 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[50][0] + ',' + colorObj[50][1] + ',' + colorObj[50][2] + ',' + colorObj[50][3] + ')'; context.fillRect(mouseX + 50 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[40][0] + ',' + colorObj[40][1] + ',' + colorObj[40][2] + ',' + colorObj[40][3] + ')'; context.fillRect(mouseX + 60 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[30][0] + ',' + colorObj[30][1] + ',' + colorObj[30][2] + ',' + colorObj[30][3] + ')'; context.fillRect(mouseX + 70 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[20][0] + ',' + colorObj[20][1] + ',' + colorObj[20][2] + ',' + colorObj[20][3] + ')'; context.fillRect(mouseX + 80 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[10][0] + ',' + colorObj[10][1] + ',' + colorObj[10][2] + ',' + colorObj[10][3] + ')'; context.fillRect(mouseX + 90 ,mouseY,10,10); context.closePath(); context.beginPath(); context.fillStyle = 'rgb(' + colorObj[0][0] + ',' + colorObj[0][1] + ',' + colorObj[0][2] + ',' + colorObj[0][3] + ')'; context.fillRect(mouseX + 100 ,mouseY,10,10); context.closePath(); // ---------------------------------------------------------------------- var imgData = context.getImageData(300,100,2,200);// узаню цвета пикселей в данной области for (let i=0;iОтветы
Ответ 1
const canvas = document.querySelector("#myCanvas"); const context = canvas.getContext('2d'); //------------------------------------- определяем координаты курсора, для передвижения нашей точки доступа const canvasPos = getPosition(canvas); let mouseX = 100; let mouseY = 100; function getPosition(el) { var xPosition = 0; var yPosition = 0; while (el) { xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft); yPosition += (el.offsetTop - el.scrollTop + el.clientTop); el = el.offsetParent; } return { x: xPosition, y: yPosition }; } function setMousePosition(e) { mouseX = e.clientX - canvasPos.x; mouseY = e.clientY - canvasPos.y; } canvas.onmousedown = () => canvas.addEventListener("mousemove", setMousePosition, false); canvas.onmouseup = () => canvas.removeEventListener("mousemove", setMousePosition, false); // Стенки должны лежать в таком виде, в котором их можно посчитать, картинка не подойдёт. // Можете попробовать читать её попиксельно, но вопрос не об этом, так что. const walls = [ //x, y, w, h [50, 50, 1, 100], [115, 80, 1, 40], [125, 90, 1, 20], [150, 50, 1, 100], [50, 170, 100, 1], ]; // От начала к концу идут цвета от самого мощного сигнала до самого слабого. // Один круг отображает падение сигнала == (100/длинну этого массива)% const colors = [ 'black', '#ff0000', '#ff0000', '#ff3300', '#ff6600', '#ff9900', '#ffcc00', '#ffff00', '#ccff00', '#99ff00', '#66ff33', '#33ff66', '#00ffcc', '#00ffff', ]; // Вспомогательные функции и константа const EPS = 1e-9; const det = (a, b, c, d) => a * d - b * c; // детерминант const between = (a, b, c) => Math.min(a,b) <= c + EPS && c <= Math.max(a,b) + EPS; // проверяет лежит ли c между b и a const intersect_1 = (a, b, c, d) => Math.max(a,c) <= Math.min(b,d);// проверяет, пересекаются ли a-b и c-d // Функция получает на входе координаты двух отрезков, а на выходе bool - пересекаются они или нет. function intersection(x11, y11, x12, y12, x21, y21, x22, y22){ // Упорядочим координаты if(x21 > x22) [x21, x22] = [x22, x21]; if(y21 > x22) [y21, y22] = [y22, y21]; // Это я стырил. // Тут вычисляются параметры прямой вида Ax+By+C = 0 для обоих отрезков const A1 = y11-y12; const B1 = x12-x11; const C1 = -A1*x11 - B1*y11; const A2 = y21-y22; const B2 = x22-x21; const C2 = -A2*x21 - B2*y21; // Магия аналитической геометрии var zn = det (A1, B1, A2, B2); if (zn != 0) { const x = -det(C1, B1, C2, B2) / zn; const y = -det(A1, C1, A2, C2) / zn; return between (x11, x12, x) && between (y11, y12, y) && between (x21, x22, x) && between (y21, y22, y); }else return det (A1, C1, A2, C2) == 0 && det (B1, C1, B2, C2) == 0 && intersect_1 (x11, x12, x21, x22) && intersect_1 (y11, y12, y21, y22); // математика, царица наук. } //------------------------------------- // рисую план, и точку доступа (function update() { context.clearRect(0, 0, canvas.width, canvas.height); // Рисуем стенки: context.fillStyle = 'black'; walls.forEach(wall => context.fillRect(...wall)); // Рисуем точку: context.fillStyle = 'red'; context.beginPath(); context.arc(mouseX, mouseY, 8, 0, 2 * Math.PI, true); context.fill(); context.closePath(); // А теперь самое интересное. // Будем рисовать круги маленькими дугами размера const dA = .05; // Потери на одной стенке - 4 * (100/colors.length) % const signal_down = 4; // Цикл кругов for(let i = 1; i <= colors.length; i++){ // Цикл дуг i-ого круга for(let alpha = 0; alpha < Math.PI*2; alpha += dA){ // Координаты конца радиуса от точки к началу дуги const radX = mouseX + 10*i*Math.cos(alpha); const radY = mouseY + 10*i*Math.sin(alpha); // Считаем, сколько между нами и точкой стенок. // Для каждой стенки проверяем, пересекается ли она с радиусом. const wallcount = walls.filter(wall => intersection( // Это отрезок - стенка wall[0], wall[1], wall[0]+wall[2], wall[1]+wall[3], // Это отрезок - радиус окружности mouseX, mouseY, radX, radY )).length; // Ищем цвет для получившейся мощности. Чем ближе к концу colors тем ниже мощность const color = colors[i - 1 + wallcount*signal_down]; // Если сигнал еще не пропал совсем - рисуем. if(color){ context.beginPath(); context.strokeStyle = color; context.arc(mouseX, mouseY, i*10, alpha, alpha + dA); context.stroke(); context.closePath(); } } } requestAnimationFrame(update); })();
Комментариев нет:
Отправить комментарий