function eating(Num) {
console.info("entered eating", Num);
bodyEating = Num;
for (let i = 0; i < Num; i++) {
BODYEATING[0].background = "black";
}
console.info(BODYEATING[0]);
//e.preventDefault();
}
<div class = "container text-center">
<img src = "https://media.geeksforgeeks.org/wp-content/uploads/unique-rectangles-formed-using-n-unit-squares.png" usemap = "#image-map">
<map id = "map" name = "image-map">
<area target = "_self" alt = "1" title = "1" onclick = "eating(1)" coords = "21,385,24,309,100,309,101,385" shape = "poly">
<area target = "_self" alt = "2" title = "2" onclick = "eating(2)" coords = "102,305,23,304,23,228,101,227" shape = "poly">
<area target = "_self" alt = "3" title = "3" onclick = "eating(3)" coords = "103,225,26,228,25,149,99,151" shape = "poly">
<area target = "_self" alt = "4" title = "4" onclick = "eating(4)" coords = "103,147,102,65,25,70,23,147" shape = "poly">
</map>
</div>
У меня есть что-то вроде 5 изображений, каждое изображение представляет собой стопку из 10 квадратов. Я хочу, чтобы для каждого изображения, когда пользователь щелкает, например, изображение на квадрате 3, тогда я получу в своем коде, что пользователь нажал на квадрат 3, а также квадраты с 1 по 3 будут иметь фоновый цвет применяемый.
Я выполнил первую задачу, создав карту изображений. Тем не менее, я не могу поставить цель раскраски, и я много искал ее. Кто-нибудь может помочь?
также добавьте чертеж предполагаемого макета. Я понятия не имею, что вы имеете в виду под: a pile of 10 squares
, squares from 1 -3
Я добавил файлы html и javascript
Я хочу раскрасить квадраты. Например, когда я нажимаю на квадрат 3, я хочу раскрасить квадраты 1, 2 и 3.
Изображения всегда квадратные? Если это так, было бы проще сделать это с помощью простых позиционированных элементов HTML, элементов SVG или элемента Canvas.
Как так. Можете ли вы объяснить больше?
Это не всегда квадраты. Мне также нужно будет работать с многоугольниками
Я попытался изменить изображение на прозрачное, но также не была применена окраска.
Карты изображений <area> на самом деле не имеют визуального присутствия, поэтому их нельзя раскрасить. Я бы предложил сделать ваши изображения SVG; Формы SVG, такие как квадраты и многоугольники, можно легко перекрасить.
Если вы знаете, что размер/позиция будут статическими, вы можете вручную расположить элемент map
и изменить размер каждого area
так, чтобы он соответствовал:
function eating(Num) {
const squares = document.querySelectorAll('area');
console.info("entered eating", Num);
for (let i = 0; i < squares.length; i++) {
if (i < Num) {
squares[i].style.background = "black";
} else {
squares[i].style.background = "transparent";
}
}
}
.container {
position: relative;
}
map {
display: grid;
gap: 1px;
position: absolute;
top: 68px;
left: 22.5px;
}
area {
width: 79px;
height: 79px;
top: 0;
}
<div class = "container text-center">
<img src = "https://media.geeksforgeeks.org/wp-content/uploads/unique-rectangles-formed-using-n-unit-squares.png" usemap = "#image-map">
<map id = "map" name = "image-map">
<area target = "_self" alt = "1" title = "1" onclick = "eating(1)" coords = "21,385,24,309,100,309,101,385" shape = "poly">
<area target = "_self" alt = "2" title = "2" onclick = "eating(2)" coords = "102,305,23,304,23,228,101,227" shape = "poly">
<area target = "_self" alt = "3" title = "3" onclick = "eating(3)" coords = "103,225,26,228,25,149,99,151" shape = "poly">
<area target = "_self" alt = "4" title = "4" onclick = "eating(4)" coords = "103,147,102,65,25,70,23,147" shape = "poly">
</map>
</div>
Однако я бы не рекомендовал этот метод, поскольку он не является масштабируемым, многоразовым или, на мой взгляд, не лучшим.
Я не понимаю, что именно это решит? Моя проблема в том, что я не могу раскрасить кучу квадратов. Тем не менее, они кликабельны, и я могу получить в своем коде, на какой квадрат щелкнул пользователь.
Это окрашивает их, щелкните любой квадрат в левой колонке, и к ним будет применен фоновый цвет.
Вот, например, если я нажал на квадрат 3, квадраты с 1 по 3 окрашены в черный цвет. Есть ли способ сделать так, чтобы если пользователь снова нажал на 2, то квадраты только от 1 до 2 были окрашены?
Отлично. Спасибо. Однако когда я применяю этот код к полигонам, он не работает. Он окрашивает квадраты? Вы можете помочь?
Я хочу, чтобы он окрашивал именно ту область, которая у меня есть на карте изображения, независимо от ее формы?
Как я уже сказал, это решение не масштабируется, и использовать его с другими формами будет либо очень сложно, либо невозможно. Как сказал @AKX в комментариях, вам лучше использовать другой подход.
Какие еще решения вы рекомендуете?
Лично я бы выбрал отдельные <svg>
элементы, но это только мои предпочтения.
Вот альтернатива с использованием встроенного SVG с фоновым изображением и полигональными элементами спереди. Обработчик handleSVGClick
находится на самом элементе SVG, чтобы упростить управление с меньшим количеством повторений.
function handleSVGClick(event) {
if (event.target.tagName === "polygon") {
event.target.style.fill = `hsl(${Math.random() * 360}, 90%, 60%)`;
}
}
polygon {
stroke-width: 2px;
stroke: #333;
fill: transparent;
}
<svg width = "564" height = "409" onclick = "handleSVGClick(event)">
<image
href = "https://media.geeksforgeeks.org/wp-content/uploads/unique-rectangles-formed-using-n-unit-squares.png"
width = "564"
height = "409"
/>
<polygon title = "1" points = "21,385 24,309 100,309 101,385" />
<polygon title = "2" points = "102,305 23,304 23,228 101,227" />
<polygon title = "3" points = "103,225 26,228 25,149 99,151" />
<polygon title = "4" points = "103,147 102,65 25,70 23,147" />
</svg>
Скажите, как вы отметили каждый квадрат?
<polygon title = "1" points = "21,385 24,309 100,309 101,385" /> эта часть
Кроме того, математика, которую вы сделали здесь hsl(${Math.random() * 360}, 90%, 60%)
, заключается в том, чтобы просто генерировать случайный цвет или у него есть другое применение?
Это просто для красивых цветов, да. Вы можете найти документацию по полигонам SVG по адресу developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon
Есть ли способ определить, на какой полигон я нажал?
Я получаю event.target,.tagName = "image
Вы можете дать каждому полигону идентификатор. Многоугольники также должны быть заполнены прозрачным цветом, как в моем примере, чтобы на них можно было кликать. В противном случае вы перейдете к изображению.
Почему, когда я добавляю к изображению более одного полигона, появляется только первый?
Не видя вашего кода, невозможно понять, почему.
Откуда вы взяли этот номер = "points = "21,385 24,309 100,309 101,385"" Я знаю, что это значит, но как вы его получили, есть ли инструмент или что-то в этом роде?
например, в том же коде, который вы написали ранее, если бы это были координаты, появляются только два полигона <polygon title = "1" points = "24,68,98,68,99,144,23,144" /> <polygon title = "2" points = "98,150,25,150,24,222,101,225" /> <polygon title = "3" points = "103,225 26,228 25,149 99,151" /> <polygon title = "4" points = "103,147 102,65 25,70 23,147" />
Это те же координаты, что и у вас, только с пробелом между каждой парой x/y (т. е. x, y, x, y, x, y равно x, y x, y x, y)
Как я могу сделать форму многоугольника более гладкой? особенно, когда у меня есть более пышные формы, такие как банан, например
да, но это делает его все еще острым. Есть ли способ сделать его гладким. Если часть фигуры изогнута, я не хочу, чтобы изогнутая часть была полна краев. Есть ли способ сделать это?
В этом случае вы можете использовать элемент <path>. Они также могут описывать кривые.
Когда я делал многоугольники, я использовал онлайн-генератор карт изображений, чтобы определить координаты многоугольника на изображении, которое у меня есть. Что я могу использовать для определения пути к имеющемуся у меня изображению?
Вы можете использовать эл. г. Inkscape, редактор SVG, для рисования контуров/многоугольников поверх вашего изображения. Затем вы можете сохранить SVG и открыть его в текстовом редакторе, чтобы извлечь нужный путь.
Ну, чтобы область была кликабельной, у них должен быть атрибут href. (по крайней мере, в Firefox). Поскольку они скрыты, их сложно стилизовать в разных браузерах. Поэтому я пошел другим путем и создал элементы в той же позиции, что и области, и стилизовал их при каждом щелчке по области.
Эти наложения — просто доказательство концепции, но, поскольку я работаю здесь с процентами, это может работать, даже если изображение уменьшено.
Также я бы рекомендовал делать все это, когда Javascript определенно поддерживается, а также предложить удалить элемент области, если вы не хотите, чтобы пользователи повторно щелкали по ним во второй раз. дайте мне знать, если есть что-то еще, что вы хотели бы, чтобы я настроил здесь:
function eating(Num) {
console.info("entered eating", Num);
if (Num == 4) { // testcode
document.querySelector("#overlay"+Num).style.display = "block";
}
// remove area from map
}
(function init() {
var container = document.querySelector('.container');
container.classList.add("js")
})()
img {
max-width: 100%;
}
.overlay {
display: none;
}
.container {
display: inline-block; /* container same width as image */
width: auto;
outline: 2px solid red;
}
.container.js {
position: relative;
}
.container.js .overlay {
position: absolute;
top: 16.8%; left: 4.3%;
width: 13.5%; height: 18.5%;
background: black;
z-index: 1;
}
<div class = "container text-center">
<span class = "overlay" id = "overlay4"></span>
<img src = "https://media.geeksforgeeks.org/wp-content/uploads/unique-rectangles-formed-using-n-unit-squares.png" usemap = "#image-map">
<map id = "map" name = "image-map">
<area target = "_self" alt = "1" title = "1" href = "#" onclick = "eating(1)" coords = "21,385,24,309,100,309,101,385" shape = "poly">
<area target = "_self" alt = "2" title = "2" href = "#" onclick = "eating(2)" coords = "102,305,23,304,23,228,101,227" shape = "poly">
<area target = "_self" alt = "3" title = "3" href = "#" onclick = "eating(3)" coords = "103,225,26,228,25,149,99,151" shape = "poly">
<area target = "_self" alt = "4" title = "4" href = "#" onclick = "eating(4)" coords = "103,147,102,65,25,70,23,147" shape = "poly">
</map>
</div>
Привет, Хеба. У вас есть соответствующий код, который вы могли бы опубликовать?