Reputation: 5235
I would like to increase group of elements size when hover it.
I have used transform: scale()
CSS property but when I hover object is moving from it's original position
p {
font-family: Lato;
}
#stops>g:hover {
transform: scale(14);
cursor: pointer;
}
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 775.43 469.98">
<defs>
<style>.cls-1{fill:none;stroke-width:5px;}.cls-1,.cls-2{stroke:#a15256;}.cls-2{fill:#fff;}.cls-3{isolation:isolate;font-size:42.79px;font-family:ArialMT, Arial;}</style>
</defs>
<title>line</title>
<path id="path7" class="cls-1" d="M202,67.72,329.33,215.86" transform="translate(-200.1 -66.09)" />
<path id="path8" class="cls-1" d="M329.35,215.87,449,355" transform="translate(-200.1 -66.09)" />
<path id="path9" class="cls-1" d="M449,355c41.53,51.11,96.22,63.08,117.9,69.28" transform="translate(-200.1 -66.09)" />
<path id="path10" class="cls-1" d="M566.86,424.29C655.43,460.48,977.38,391.48,973,536" transform="translate(-200.1 -66.09)" />
<g id="stops">
<g id="g3670">
<circle class="cls-2" cx="129.24" cy="149.78" r="13.58" />
<text id="text3668" class="cls-3" transform="translate(120.84 114.12)">Station1</text>
</g>
<g id="g3700">
<circle class="cls-2" cx="248.91" cy="288.93" r="13.58" />
<text id="text3698" class="cls-3" transform="translate(284.5 239)">Station2</text>
</g>
<g id="g3750">
<circle class="cls-2" cx="366.75" cy="358.2" r="13.58" />
<text id="text3748" class="cls-3" transform="translate(134.96 379.59)">Station3</text>
</g>
</g>
</svg>
Expected behaviour
I would like to increase text size and station circle ( and fill it ) without changing their position.
It could be done with css, but if I could have recommendation of libraries because I would make animations on the subway line ( trains circulations ) that would be great
Upvotes: 0
Views: 2268
Reputation: 33064
In the next demo I'm removing the transformation from the text and I'm adding x
and y
attributes. The transformation happens when you mouse over the circle. In order to transform the text as well I'm using this selector: #stops g circle:hover + text
Alternatively instead of transformation for the text you could have changed the font size.
text{
font-family: Lato;
font-size:16px;
}
#stops g circle:hover {
transform: scale(2);
transform-origin: 50% 50%;
transform-box: fill-box;
cursor: pointer;
}
#stops g circle:hover + text{
transform: scale(2);
transform-origin: 0% 50%;
transform-box: fill-box;
cursor: pointer;
pointer-events:none;
}
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 775.43 469.98">
<defs>
<style>.cls-1{fill:none;stroke-width:5px;}.cls-1,.cls-2{stroke:#a15256;}.cls-2{fill:#fff;}.cls-3{isolation:isolate;font-size:42.79px;font-family:ArialMT, Arial;}</style>
</defs>
<title>line</title>
<path id="path7" class="cls-1" d="M202,67.72,329.33,215.86" transform="translate(-200.1 -66.09)" />
<path id="path8" class="cls-1" d="M329.35,215.87,449,355" transform="translate(-200.1 -66.09)" />
<path id="path9" class="cls-1" d="M449,355c41.53,51.11,96.22,63.08,117.9,69.28" transform="translate(-200.1 -66.09)" />
<path id="path10" class="cls-1" d="M566.86,424.29C655.43,460.48,977.38,391.48,973,536" transform="translate(-200.1 -66.09)" />
<g id="stops">
<g id="g3670">
<circle class="cls-2" cx="129.24" cy="149.78" r="13.58" />
<text id="text3668" class="cls-3" x="145" y="149.78" >Station1</text>
</g>
<g id="g3700">
<circle class="cls-2" cx="248.91" cy="288.93" r="13.58" />
<text id="text3698" class="cls-3" x="270" y="288.93">Station2</text>
</g>
<g id="g3750">
<circle class="cls-2" cx="366.75" cy="358.2" r="13.58" />
<text id="text3748" class="cls-3" x="385" y="358.2">Station3</text>
</g>
</g>
</svg>
The OP is commenting that
The hover should be on g g:hover not g circle:hover
In this case I'm adding a rectangle to the g element. The rectangle is as big as the g's bounding box. Everything in the g element except the rect has pointer-events:none
. The transformation happens around the center of the circle.
text{
font-family: Lato;
font-size:16px;
}
g * {pointer-events:none;}
g rect{pointer-events:all;}
#stops g{transform: scale(1);}
#stops g:hover {
transform: scale(2);
transform-origin: 129.24px 149.78px;
cursor: pointer;
}
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 775.43 469.98">
<defs>
<style>.cls-1{fill:none;stroke-width:5px;}.cls-1,.cls-2{stroke:#a15256;}.cls-2{fill:#fff;}.cls-3{isolation:isolate;font-size:42.79px;font-family:ArialMT, Arial;}</style>
</defs>
<title>line</title>
<path id="path7" class="cls-1" d="M202,67.72,329.33,215.86" transform="translate(-200.1 -66.09)" />
<path id="path8" class="cls-1" d="M329.35,215.87,449,355" transform="translate(-200.1 -66.09)" />
<path id="path9" class="cls-1" d="M449,355c41.53,51.11,96.22,63.08,117.9,69.28" transform="translate(-200.1 -66.09)" />
<path id="path10" class="cls-1" d="M566.86,424.29C655.43,460.48,977.38,391.48,973,536" transform="translate(-200.1 -66.09)" />
<g id="stops">
<g id="g3670">
<rect x="115" y="110" width="187" height="52" fill="none" />
<circle class="cls-2" cx="129.24" cy="149.78" r="13.58" />
<text id="text3668" class="cls-3" x="145" y="149.78" >Station1</text>
</g>
</g>
</svg>
In order to calculate the <g>
's bounding box you can use javascript and the method getBBox()
.
In order to better understand what happens please add a fill to the <rect>
You can keep the text transformation if this is what you want.
the OP is commenting:
Can you make an example with three dots please ?
Next comes the example. In this case I'm using Javascript to set the size of the rects and the value for the transform-origin
of every group. If you need only the markup you can copy it from the inspector.
Since the OP commented that they would like to keep the text transformation in this example the text keeps the transformation instead of the x
and y
attributes.
let stops = document.querySelector("#stops");
// all the g elements in the stops
let gs = stops.querySelectorAll("g");
// for each g in the gs
gs.forEach(g=>{
// the rectangle in this g element
let thisRect = g.querySelector("rect");
// the circle in this g element
let thisCircle = g.querySelector("circle");
// the coords of the circle's center used for the transform-origin
let x = thisCircle.getAttribute("cx");
let y = thisCircle.getAttribute("cy");
// the bounding box of the group
let bb = g.getBBox();
// set the rect's attributes
thisRect.setAttributeNS(null, "x", bb.x);
thisRect.setAttributeNS(null, "y", bb.y);
thisRect.setAttributeNS(null, "width", bb.width);
thisRect.setAttributeNS(null, "height", bb.height);
// set the value for the transform-origin for this group
g.style.transformOrigin = `${x}px ${y}px`;
})
text{
font-family: Lato;
font-size:16px;
}
g * {pointer-events:none;}
g rect{pointer-events:all;}
#stops g{transform: scale(1);cursor: pointer;}
#stops g:hover {
transform: scale(2);
}
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 775.43 469.98">
<defs>
<style>.cls-1{fill:none;stroke-width:5px;}.cls-1,.cls-2{stroke:#a15256;}.cls-2{fill:#fff;}.cls-3{isolation:isolate;font-size:42.79px;font-family:ArialMT, Arial;}</style>
</defs>
<title>line</title>
<path id="path7" class="cls-1" d="M202,67.72,329.33,215.86" transform="translate(-200.1 -66.09)" />
<path id="path8" class="cls-1" d="M329.35,215.87,449,355" transform="translate(-200.1 -66.09)" />
<path id="path9" class="cls-1" d="M449,355c41.53,51.11,96.22,63.08,117.9,69.28" transform="translate(-200.1 -66.09)" />
<path id="path10" class="cls-1" d="M566.86,424.29C655.43,460.48,977.38,391.48,973,536" transform="translate(-200.1 -66.09)" />
<g id="stops">
<g id="g3670">
<rect fill="none"/>
<circle class="cls-2" cx="129.24" cy="149.78" r="13.58" />
<text id="text3668" class="cls-3" transform="translate(145 160)">Station1</text>
</g>
<g id="g3700">
<rect fill="none"/>
<circle class="cls-2" cx="248.91" cy="288.93" r="13.58" />
<text id="text3698" class="cls-3" transform="translate(270 300)">Station2</text>
</g>
<g id="g3750">
<rect fill="none"/>
<circle class="cls-2" cx="366.75" cy="358.2" r="13.58" />
<text id="text3748" class="cls-3" transform="translate(200 400)">Station3</text>
</g>
</g>
</svg>
Upvotes: 3