Question:
This question has been asked many times and there are good solutions using javascript
, like this:
var shapeClick = document.getElementById("shape").addEventListener("click", changeColor);
var clicks = 0;
function changeColor(){
if (shape.style.fill == "rgb(29, 172, 249)")
{
shape.style.fill = "rgb(255, 0, 0)";
}
else {
shape.style.fill = "rgb(29, 172, 249)";
}
}
<div>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="250" height="250" viewBox="0 0 250 250"
>
<circle id="shape" class="seat" cx="120" cy="125" r="50" style="fill: #1dacf9" stroke="black" stroke-width="2" />>
</svg>
</div>
Everything works fine, with the help of scripts you can do a lot.
Attention question
How to do the same on pure SVG (SMIL)
without using javascript
and CSS
.
Just changing the color on click is easy:
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="250" height="250" viewBox="0 0 250 250"
>
<circle cx="120" cy="125" r="50" style="fill: dodgerblue; stroke:black; stroke-width:2;" >
<animate attributeName="fill" from="dodgerblue" to="red" fill="freeze" begin="svg1.click" dur="0.1s" calcMode="discrete"/>
</circle>
</svg>
But how to change the color back by clicking on the object again does not occur to me.
Answer:
if (shape.style.fill == "rgb(29, 172, 249)")
So it's better not to. And then someone will return 1DACF9
instead of rgb(29, 172, 249)
and that's it.
How to do the same on pure SVG, SMIL without using – javascript, CSS
label {
display: block;
}
#red {
display: none;
}
svg {
width: 250px;
display: block;
}
#shape {
fill: green;
stroke: black;
stroke-width: 2;
}
#red:checked + svg #shape {
fill: red;
}
<label>
<input type=checkbox id=red>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
<circle id="shape" class="seat" cx="120" cy="125" r="50" />
</svg>
</label>
where and how is the click on the element handled?
The example above resulted in a click on the entire svg
.
To fix this, you can use pointer-events
.
label {
display: block;
width: 100%;
height: 100%;
pointer-events: none;
}
#red {
display: none;
}
svg {
width: 250px;
display: block;
}
foreignObject svg {
pointer-events: none;
}
#shape {
fill: green;
stroke: black;
stroke-width: 2;
pointer-events: all;
}
#red:checked + svg #shape {
fill: red;
}
<label>
<input type=checkbox id=red>
<svg viewBox="0 0 250 250">
<circle id="shape" class="seat" cx="120" cy="125" r="50" />
</svg>
</label>
If you need to place several such objects inside one svg, you can use foreignObject
, however, it should be noted that its support by browsers is very doubtful .
label {
display: block;
width: 100%;
height: 100%;
pointer-events: none;
}
#red {
display: none;
}
svg {
width: 250px;
display: block;
}
foreignObject svg {
pointer-events: none;
}
#shape {
fill: green;
stroke: black;
stroke-width: 2;
pointer-events: all;
}
#red:checked + svg #shape {
fill: red;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
<rect x="0" y="0" width="100%" height="125" fill="silver" />
<foreignObject x="0" y="0" width="100%" height="100%">
<label xmlns="http://www.w3.org/1999/xhtml">
<input type=checkbox id=red>
<svg viewBox="0 0 250 250">
<circle id="shape" class="seat" cx="120" cy="125" r="50" />
</svg>
</label>
</foreignObject>
</svg>