How can I rotate this SVG element correctly?
Consider transform-box:fill-box;
then make the origin bottom center
and increase the viewbox a little to avoid the cut. I have also moved the rotation to the polygon and kept the translation on the g
element.
$('#percent').on('change', function() {
$('#triangle').css('transform', 'rotate(' + percentToDegrees($(this).val()) + 'deg)')
})
function percentToDegrees(percent) {
var degrees = -90;
var inc = 1.8;
return degrees += (percent * inc);
}
#triangle {
transform-origin:center bottom;
transform-box:fill-box;
}
input {
display: block;
margin: 50px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg width="100%" height="177px" viewBox="0 0 385 185" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" transform="translate(-15.000000, -224.000000)">
<g id="Group" transform="translate(15.000000, 220.000000)">
<g id="guage">
<path d="M84.8041871,178.856781 L84.8041871,179.169281 L25,179.169281 L25,178.669281 C25,119.519295 57.1931907,67.8894771 105.011512,40.3501901 L135,92.2989954 C105.009619,109.483749 84.8041871,141.810321 84.8041871,178.856781 Z" id="red" fill="#BD3632"></path>
<path d="M235.050803,92.4864742 C205.21439,75.1028089 167.169843,73.7652453 135.133157,92.2884751 L134.862916,92.4447251 L105,40.6455806 L105.432385,40.3955806 C156.58355,10.8205878 217.307001,12.8896752 265,40.5376689 L235.050803,92.4864742 L235.050803,92.4864742 Z" id="yellow" fill="#EEAF30"></path>
<path d="M235,92.2989954 L264.988488,40.3501901 C312.806809,67.8894771 345,119.519295 345,178.669281 L345,179.169281 L285.195813,179.169281 L285.195813,178.856781 C285.195813,141.810321 264.990381,109.483749 235,92.2989954 L235,92.2989954 Z" id="green" fill="#008542"></path>
<text id="100%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" line-spacing="15" fill="#000000">
<tspan x="350" y="180">100%</tspan>
</text>
<text id="50%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" fill="#000000">
<tspan x="171" y="14">50%</tspan>
</text>
<text id="0%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" fill="#000000">
<tspan x="0" y="178">0%</tspan>
</text>
</g>
<g id="needle" transform="translate(175.000000, 18.000000)">
<polygon id="triangle" fill="#3C3C3B" points="10 0 15 162 5 162"></polygon>
</g>
</g>
</g>
</g>
</svg>
<input type="range" id="percent" value="50" min="0" max="100">
The easiest is probably to do it all with SVG, simply setting your element's transform
attribute instead of its css style
.
All you need is to set the second and third values of the rotate(angle, origin_x, origin_y)
SVG transform method.
$('#percent').on('input', function() {
$('#needle').attr('transform', 'translate(175, 19) ' +
'rotate(' + percentToDegrees($(this).val()) + ', 10, 162)')
})
function percentToDegrees(percent) {
var degrees = -90;
var inc = 1.8;
return degrees += (percent * inc);
}
input {
display: block;
margin: 50px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg width="100%" height="177px" viewBox="0 0 385 177" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" transform="translate(-15.000000, -224.000000)">
<g id="Group" transform="translate(15.000000, 220.000000)">
<g id="guage">
<path d="M84.8041871,178.856781 L84.8041871,179.169281 L25,179.169281 L25,178.669281 C25,119.519295 57.1931907,67.8894771 105.011512,40.3501901 L135,92.2989954 C105.009619,109.483749 84.8041871,141.810321 84.8041871,178.856781 Z" id="red" fill="#BD3632"></path>
<path d="M235.050803,92.4864742 C205.21439,75.1028089 167.169843,73.7652453 135.133157,92.2884751 L134.862916,92.4447251 L105,40.6455806 L105.432385,40.3955806 C156.58355,10.8205878 217.307001,12.8896752 265,40.5376689 L235.050803,92.4864742 L235.050803,92.4864742 Z" id="yellow" fill="#EEAF30"></path>
<path d="M235,92.2989954 L264.988488,40.3501901 C312.806809,67.8894771 345,119.519295 345,178.669281 L345,179.169281 L285.195813,179.169281 L285.195813,178.856781 C285.195813,141.810321 264.990381,109.483749 235,92.2989954 L235,92.2989954 Z" id="green" fill="#008542"></path>
<text id="100%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" line-spacing="15" fill="#000000">
<tspan x="350" y="180">100%</tspan>
</text>
<text id="50%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" fill="#000000">
<tspan x="171" y="14">50%</tspan>
</text>
<text id="0%" font-family="Omnes-Regular, Omnes" font-size="15" font-weight="normal" fill="#000000">
<tspan x="0" y="178">0%</tspan>
</text>
</g>
<g id="needle" transform="translate(175.000000, 19.000000)">
<polygon id="Triangle" fill="#3C3C3B" points="10 0 15 162 5 162"></polygon>
</g>
</g>
</g>
</g>
</svg>
<input type="range" id="percent" value="50" min="0" max="100">
You'll even win in browser compat ;-)
And note that this could be all simplified to:
$('#percent').on('input', function() {
$('#Triangle')
.attr('transform', 'rotate(' + percentToDegrees($(this).val()) + ', 10, 162)')
})
function percentToDegrees(percent) {
var degrees = -90;
var inc = 1.8;
return degrees += (percent * inc);
}
input {
display: block;
margin: 50px auto;
}
#Page-1 text {
font-family: Omnes-Regular, Omnes;
font-size: 15px;
font-weight: normal;
fill: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg width="100%" height="177px" viewBox="0 0 385 177" version="1.1">
<g id="Page-1" stroke="none" fill="none" transform="translate(0, -4)">
<g id="guage">
<path d="M84.8041871,178.856781 L84.8041871,179.169281 L25,179.169281 L25,178.669281 C25,119.519295 57.1931907,67.8894771 105.011512,40.3501901 L135,92.2989954 C105.009619,109.483749 84.8041871,141.810321 84.8041871,178.856781 Z" id="red" fill="#BD3632"></path>
<path d="M235.050803,92.4864742 C205.21439,75.1028089 167.169843,73.7652453 135.133157,92.2884751 L134.862916,92.4447251 L105,40.6455806 L105.432385,40.3955806 C156.58355,10.8205878 217.307001,12.8896752 265,40.5376689 L235.050803,92.4864742 L235.050803,92.4864742 Z" id="yellow" fill="#EEAF30"></path>
<path d="M235,92.2989954 L264.988488,40.3501901 C312.806809,67.8894771 345,119.519295 345,178.669281 L345,179.169281 L285.195813,179.169281 L285.195813,178.856781 C285.195813,141.810321 264.990381,109.483749 235,92.2989954 L235,92.2989954 Z" id="green" fill="#008542"></path>
<text id="100%" line-spacing="15">
<tspan x="350" y="180">100%</tspan>
</text>
<text id="50%">
<tspan x="171" y="14">50%</tspan>
</text>
<text id="0%">
<tspan x="0" y="178">0%</tspan>
</text>
</g>
<g id="needle" transform="translate(175.000000, 19.000000)">
<polygon id="Triangle" fill="#3C3C3B" points="10 0 15 162 5 162"></polygon>
</g>
</g>
</svg>
<input type="range" id="percent" value="50" min="0" max="100">