Если допустимо (а) использовать JavaScript и (б) указать положение каждого немасштабирующего элемента с помощью transform="translate(…,…)"
либо на самом элементе, либо в группе переноса (как вы сделали), то вы можете использовать мой код unscaling:
http://phrogz.net/svg/libraries/SVGPanUnscale.js
Как вы можете видеть в демонстрации, он отменяет все преобразования, кроме перевода (включая масштабирование, поворот и наклон), сохраняя элементы в том месте, где они должны быть.
См. Также эту демонстрацию, которая позволяет масштабировать и панорамировать графику с помощью SVGPan , сохраняя при этом некоторые элементы разметки в неизменном виде:
http://phrogz.net/svg/scale-independent-elements.svg
Вот весь код, который вам нужен:
// Copyright 2012 © Gavin Kistner, !@phrogz.net
// License: http://phrogz.net/JS/_ReuseLicense.txt
// Removes all transforms applied above an element.
// Apply a translation to the element to have it remain at a local position
function unscale(el){
var svg = el.ownerSVGElement;
var xf = el.scaleIndependentXForm;
if (!xf){
// Keep a single transform matrix in the stack for fighting transformations
// Be sure to apply this transform after existing transforms (translate)
xf = el.scaleIndependentXForm = svg.createSVGTransform();
el.transform.baseVal.appendItem(xf);
}
var m = svg.getTransformToElement(el.parentNode);
m.e = m.f = 0; // Ignore (preserve) any translations done up to this point
xf.setMatrix(m);
}
Вот демонстрационный код, если JSFiddle не работает:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:x="http://www.w3.org/1999/xlink"
font-size="36">
<g transform="matrix(1 0 0 1 0 0)">
<g transform="translate(100 50)"><text x="0" y="1em">A!</text></g>
<g transform="translate(200 150)"><text x="0" y="1em">B!</text></g>
<g transform="translate(150 75)"><text x="0" y="1em">C!</text></g>
</g>
<script x:href="http://phrogz.net/svg/libraries/SVGPanUnscale.js"></script>
<script>
var root = document.querySelector('g'),
text = document.querySelectorAll('text'),
xf = root.transform.baseVal.getItem(0);
// Keep scaling, spinning, and sliding the outer graphic
// but "unscale" each text element afterwards.
setInterval(function(){
var m = xf.matrix.scale(0.99).translate(10,0).rotate(1);
xf.setMatrix(m);
[].forEach.call(text,unscale);
},100);
</script>
</svg>