<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>transform</title>
<style media="screen">
svg {
background-color: #fcfcfc;
display: block;
margin: 20px auto;
border: 1px solid #cccccc;
}
#transform {
width: 300px;
}
</style>
</head>
<body>
<fieldset>
<legend>设置</legend>
<label>分组:
<select id="groupSel">
<option value="a">a</option>
<option value="b" selected>└─b</option>
<option value="c"> └─c</option>
<option value="d">└─d</option>
</select>
</label>
<label>变换:
<input type="text" id="cmdInput" placeholder="t 50 50 r 30 s 0.5" />
<output id="propOutput"></output>
</label>
</fieldset>
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="600" viewBox="-200.5 -100.5 1000 600">
<defs>
<g id="coord">
<line x1="0" y1="0" x2="300" y2="0" />
<line x1="0" y1="0" x2="0" y2="300" />
<circle cx="0" cy="0" r="2" />
<circle cx="100" cy="0" r="2" />
<circle cx="200" cy="0" r="2" />
<circle cx="300" cy="0" r="2" />
<circle cx="0" cy="200" r="2" />
<circle cx="0" cy="100" r="2" />
<circle cx="0" cy="300" r="2" />
</g>
</defs>
<text fill="black" x="-55" y="5">Group</text>
<use xlink:href="#coord" stroke="black" fill="black" />
<g id="a" stroke="red" fill="red">
<text x="5" y="20">a</text>
<use xlink:href="#coord" />
<g id="b" stroke="blue" fill="blue">
<text x="5" y="20">b</text>
<use xlink:href="#coord" />
<g id="c" stroke="green" fill="green">
<text x="5" y="20">c</text>
<use xlink:href="#coord" />
</g>
</g>
<g id="d" stroke="orange" fill="orange">
<text x="5" y="20">d</text>
<use xlink:href="#coord" />
</g>
</g>
</svg>
<script>
const currGroup = () => document.getElementById(groupSel.value);
// 把命令转换为 transform 属性
// 't 10 10 r 30 s 1.3' => 'translate(10, 10) rotate(30) scale(1.3)'
const cmd2prop = cmd => {
const cmdHash = {
't': 'translate(',
'r': 'rotate(',
's': 'scale(',
'm': 'matrix('
};
const cmds = (cmd || '').split(' ');
let prop = '';
let cmdK, cmdType;
while (cmdK = cmds.shift()) {
if (cmdHash[cmdK]) {
if (cmdType == 'number') {
prop += ') ';
}
prop += cmdHash[cmdK];
cmdType = 'command';
} else {
if (cmdType == 'number') {
prop += ', ';
}
prop += cmdK;
cmdType = 'number';
}
}
if (prop.length) {
prop += ')';
}
return prop;
}
// 切换 svg 分组
groupSel.onchange = function () {
const cmd = currGroup().cmd || '';
cmdInput.value = cmd;
propOutput.textContent = cmd2prop(cmd);
};
// 输入 transform 命令
cmdInput.oninput = function () {
const cmd = cmdInput.value;
const prop = cmd2prop(cmd);
currGroup().cmd = cmd;
propOutput.textContent = prop;
try {
currGroup().setAttribute('transform', prop);
} catch (error) {
console.warn(error);
}
};
</script>
</body>
</html>
Tips: 参考 techird 老师主讲的课程 《走进SVG 之 SVG 坐标变换》