請幫助我理解使用普通JavaScript操作svg元素及其變換的最佳做法。在旋轉後移動SVG元素
我理解座標系傳下來的節點和鏈接等等等等
我試圖做到的,是繼續旋轉後的元素原文翻譯。旋轉後未沿着軸線移動。
是否需要複製第一個轉換轉換並將其添加到轉換列表的末尾?
非常感謝,如果有人能夠以雄辯的方式闡明一些光。
請幫助我理解使用普通JavaScript操作svg元素及其變換的最佳做法。在旋轉後移動SVG元素
我理解座標系傳下來的節點和鏈接等等等等
我試圖做到的,是繼續旋轉後的元素原文翻譯。旋轉後未沿着軸線移動。
是否需要複製第一個轉換轉換並將其添加到轉換列表的末尾?
非常感謝,如果有人能夠以雄辯的方式闡明一些光。
最好的方法是創建一個矩陣變換,然後請求各種變換並使用consolidate()方法。下面是一個例子
<!DOCTYPE HTML>
<html>
<head>
<title>Transform Request</title>
</head>
<body onload=showSVGSource()>
<b><center>Transform Request Object + consolidate</b>
<div id=svgDiv style=background:lime;width:400px;height:400px; >
<svg id=mySVG width=400 height=400 >
<circle id=myCircle cx=0 cy=0 r=150 fill=yellow transform="translate(200,200)" />
</svg>
</div>
<br>
<button onClick=translateCircle()>translate</button>
<button onClick=scaleCircle()>scale</button>
<br>
<textarea id=svgSourceValue style=width:500px;height:100px;></textarea>
<center>
<script>
function translateCircle()
{
var objTransformRequestObj = mySVG.createSVGTransform()
//---attach new transform to element, init its transform list---
var myTransListAnim=myCircle.transform
var objTransList=myTransListAnim.baseVal
objTransformRequestObj.setTranslate(40,0)
objTransList.appendItem(objTransformRequestObj)
objTransList.consolidate()
showSVGSource()
}
function scaleCircle()
{
var objTransformRequestObj = mySVG.createSVGTransform()
//---attach new transform to element, init its transform list---
var myTransListAnim=myCircle.transform
var objTransList=myTransListAnim.baseVal
objTransformRequestObj.setScale(.5,.3)
objTransList.appendItem(objTransformRequestObj)
objTransList.consolidate()
showSVGSource()
}
function showSVGSource()
{
svgSourceValue.value=svgDiv.innerHTML
}
</script>
</body>
</html>
你實現這一目標是通過嵌套的變換方式。例如,看看下面的示例SVG。
<svg width="600" height="200">
<g>
<rect x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>
你可以申請一個轉換到<g>
和另一對<rect>
。他們將是獨立的,但將整體效果相結合。
因此,例如,如果我想將所有內容都移動到正確的位置,我可以對該組應用翻譯轉換。
<svg width="600" height="200">
<g transform="translate(200,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>
然後,如果我想旋轉到位矩形,我可以通過應用旋轉變換,就是這樣做的。
<svg width="600" height="200">
<g transform="translate(200,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="rotate(45,50,100)"/>
</g>
</svg>
然後,如果我願意,我可以移動矩形更進一步權利,更新組的變換。
<svg width="600" height="200">
<g transform="translate(400,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="rotate(45,50,100)"/>
</g>
</svg>
去想這個問題的方法是,<rect>
是在自己的小世界(「座標空間」是爲官一任:)是一無所知什麼是回事它的父元素。
所以如果我們使用我們上面學到的東西,我們可以很容易地創建你之後的那種動畫。以下動畫由三個階段組成。首先我們將矩形向右移動,然後旋轉它,然後再繼續。中間的旋轉不會影響我們再次向右移動的第三階段。
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
var tx = 0; // the animated X position
var angle = 0; // the animated angle
/*
* The first phase of the animation.
* Function to step to the right until we hit tx=200.
*/
var stepRightTo200 = function() {
setTimeout(function() {
tx += 4;
outer.setAttribute('transform', 'translate('+tx+',0)');
if (tx < 200) // schedule another step in this phase
stepRightTo200();
else // start next phase of animation
rotateTo45();
}, 32);
};
/*
* The second phase of the animation.
* Step the angle around until we hit 45 degrees.
*/
var rotateTo45 = function() {
setTimeout(function() {
angle += 1;
inner.setAttribute('transform', 'rotate('+angle+',50,100)');
if (angle < 45)
rotateTo45()
else
stepRightTo400(); // start third phase of animation
}, 32);
};
/*
* The third phase of the animation.
* Step to the right until we hit tx=400.
*/
var stepRightTo400 = function() {
setTimeout(function() {
tx += 4;
outer.setAttribute('transform', 'translate('+tx+',0)');
if (tx < 400)
stepRightTo400();
}, 32);
};
// Kick off first phase of animation
stepRightTo200();
<svg width="600" height="200">
<g id="outer">
<rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>
在上面的例子中,我已經分居了「外」轉變出到父組,但我們真的沒有這樣做。我們可以將變換操作嵌套到單個變換中。
因此,我們可以簡化上述第三SVG例如:
<svg width="600" height="200">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="translate(400,0) rotate(45,50,100)"/>
</svg>
「外」變換成爲在變換列表中的第一個。如果您需要創建一個多部分轉換,這是一個很好的方法。首先創建(或想象)一個嵌套的組結構,並將變換應用於從「外部」(左)到「內部」(右)的變換。
因此,最後,我們可以使用這個非嵌套窗體重寫我們的動畫腳本。
var inner = document.getElementById("inner");
var tx = 0; // the animated X position
var angle = 0; // the animated angle
/*
* The first phase of the animation.
* Function to step to the right until we hit tx=200.
*/
var stepRightTo200 = function() {
setTimeout(function() {
tx += 4;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (tx < 200) // schedule another step in this phase
stepRightTo200();
else // start next phase of animation
rotateTo45();
}, 32);
};
/*
* The second phase of the animation.
* Step the angle around until we hit 45 degrees.
*/
var rotateTo45 = function() {
setTimeout(function() {
angle += 1;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (angle < 45)
rotateTo45()
else
stepRightTo400(); // start third phase of animation
}, 32);
};
/*
* The third phase of the animation.
* Step to the right until we hit tx=400.
*/
var stepRightTo400 = function() {
setTimeout(function() {
tx += 4;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (tx < 400)
stepRightTo400();
}, 32);
};
// Kick off first phase of animation
stepRightTo200();
<svg width="600" height="200">
<rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/>
</svg>
希望這有助於你瞭解如何轉換工作。
神奇而且非常翔實。感謝幫助,它確實有幫助。 – daniel