在<svg path </object>上定位<object>

时间:2014-03-06 01:53:18

标签: svg path

我有一堆使用相同svg路径的对象,基本上是一个箭头。我想将对象放在另一个圆圈的svg路径上,这样箭头看起来就像向外“向外”。

我读了一些文章,说使用<object>为svg提供了更多控制但我无法找到如何将<object>定位到另一个svg <object>路径(圆圈)。< / p>

而不是仅仅手动旋转每个<object>我想将它们放在一条路径上,以便将来动画它们会更容易。我希望它们在翻转时从中心向外移动一点,我想通过路径而不是手动设置每个箭头的动画,动画会更容易。

我可以像这里一样沿着路径制作动画 http://demo.hongkiat.com/scalable-vector-graphics-animation/ 并通过将“跟随路径”上的路径更改为圆形,但我不想动画,只需定位....

更新:我似乎能够在网上找到一个元素到路径上的唯一东西是animationTransform或沿着路径动画的东西,但我只想沿着另一个元素(路径)定位元素,如下所示: svg circle 额外的箭头是我计划将来在翻滚时制作动画的方法......但是现在我很好奇如何定位箭头。我也没有多少,但它是一个开始,我终于工作了。任何帮助表示赞赏!

http://jsfiddle.net/74JRf/1/

我只是想,将箭头旋转成带有css3或svg的圆圈会更好吗?

2 个答案:

答案 0 :(得分:1)

您的应用程序演示了SVG的动态方面。我希望我的回答不是太冗长:)

创建你的'箭头',使它们的中心/底点位于(0,0) - 这是在将它们放在一个圆圈时使用的,以及用于onmouseover的'hilite / extend'功能。

我建议为每个黑色和灰色箭头使用多边形而不是路径。 然后放在<defs>中以创建所需的使用元素。 e.g

<defs>
<polygon id="myBlackArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80"  fill="black" />
<polygon id="myGrayArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80"  fill="silver" />
</defs>

然后,通过一些Javascript,您可以围绕中心点构建箭头:

var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
var centerX=200
var centerY=200
//---every 40 degrees around a center point--
function placeArrowsAroundCircle()
{
    for(var k=0;k<9;k++)
    {
        var rotateAngle=k*40
        var grayArrow=document.createElementNS(NS,"use")
        grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
        grayArrow.setAttribute("onmouseover", "hilite(evt)")
        grayArrow.setAttribute("onmouseout", "unhilite(evt)")
        grayArrow.setAttribute("rotateAngle", rotateAngle)
        grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(grayArrow)
    }

    for(var k=0;k<9;k++)
    {
        var rotateAngle=k*40+20
        var blackArrow=document.createElementNS(NS,"use")
        blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
        blackArrow.setAttribute("onmouseover", "hilite(evt)")
        blackArrow.setAttribute("onmouseout", "unhilite(evt)")
        blackArrow.setAttribute("rotateAngle", rotateAngle)

        blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(blackArrow)
    }
}

鼠标悬停/退出的每个箭头附加的两个功能将延伸/收缩目标箭头(箭头在y方向上缩放为1.3)。

//--onmouseover---
function hilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}

下面是一个示例,您可以将其放在.htm文档中以查看其是否有效。对IE / CH / FF

进行了测试
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<center>
<div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<defs>
<polygon id="myBlackArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80"  fill="black" />
<polygon id="myGrayArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80"  fill="silver" />
</defs>
</svg>
</div>
<button onClick=placeArrowsAroundCircle()>Place Arrows Around Circle</button>
</center>
<script id=myScript>
var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
var centerX=200
var centerY=200
//---every 40 degrees around a center point--
//---button---
function placeArrowsAroundCircle()
{
    for(var k=0;k<9;k++)
    {
        var rotateAngle=k*40
        var grayArrow=document.createElementNS(NS,"use")
        grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
        grayArrow.setAttribute("onmouseover", "hilite(evt)")
        grayArrow.setAttribute("onmouseout", "unhilite(evt)")
        grayArrow.setAttribute("rotateAngle", rotateAngle)
        grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(grayArrow)
    }

    for(var k=0;k<9;k++)
    {
        var rotateAngle=k*40+20
        var blackArrow=document.createElementNS(NS,"use")
        blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
        blackArrow.setAttribute("onmouseover", "hilite(evt)")
        blackArrow.setAttribute("onmouseout", "unhilite(evt)")
        blackArrow.setAttribute("rotateAngle", rotateAngle)

        blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(blackArrow)
    }
}
//--onmouseover---
function hilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}
</script>
</body>
</html>

答案 1 :(得分:1)

这与前一个答案类似,不同之处在于它使用导入的路径作为箭头而不是多边形。

首先,您导入的路径是 humongus ,因此它们对于我的400x400 svg来说太大了。 因此,我必须将它们缩小到适合我的svg的尺寸。我选择80px作为箭头的高度。要做到这一点,我必须得到导入路径的实际大小,我已将其放在一个元素中。我使用getBBox()执行此操作,如下所示。

//--get actual size---
var bb=importedPaths.getBBox()
var bbx=bb.x
var bby=bb.y
var bbw=bb.width
var bbh=bb.height
//---find the center point of this <g>---
var cx=bbx+.5*bbw
var cy=bby+.5*bbh

//---set desired size, i.e. scale the import--
var heightSize=80
var scale=heightSize/bbh
//---translate so it's  bottom is centered is at (0,0)
var transX=(-cx)*scale
var transY=(-cy-.5*bbh)*scale
importedPaths.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")

现在我有这个大小并且位于箭头底部以(0,0)为中心,所以我可以用它来制作符号元素。

我将重新调整大小的导入的副本作为黑色箭头和灰色箭头,并将它们放在<defs>元素中。 <defs>用于存储/隐藏用于符号的元素。

//---create your symbol objects from transformed import, by placing <g> in defs--
var blackArrow=importedPaths.cloneNode(true)
blackArrow.id="myBlackArrow"
myDefs.appendChild(blackArrow)
var grayArrow=importedPaths.cloneNode(true)
grayArrow.id="myGrayArrow"
grayArrow.setAttribute("fill","silver")
myDefs.appendChild(grayArrow)

以下是一个html文件,您可以在其中查看此操作。我已经包含了一个textarea,显示了如何创建svg。 (我在左上方留下原始箭头)。注意:在IE和Chrome中正常工作,FF不能完全呈现箭头组。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<div  style='padding:5px;background-color:gainsboro;'>OK in:IE11/CH32, but FF23 does not fully render arrow in in circle<br /></div>
<br />
<br />
<br />
<center>
<div id=svgDiv style='width:400px;height:400px;background-color:lightgreen'>
<svg id="mySVG" width="400" y="400" overflow="visible" >
<defs id="myDefs">
</defs>
<g id="importedPaths" fill="black"><path  d="M2553.826,1137.28l-2.772-1.719l29.799,1445.434l195.02,1.004l9.765-1448.729 c0,0-63.94,42.007-113.36,42.007S2553.826,1137.28,2553.826,1137.28z" /><path d="M2451.84,1058.265c0,0,171.983,75.005,216.505,75.005s188.535-75.005,188.535-75.005l-190.691-366.037 L2451.84,1058.265z" /></g>
</svg>
</div>
<button onClick=placeArrowsAroundCircle()>Place Arrows Around Circle</button><br />
  <br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
</center>

<script id=myScript>
var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
//--place this at the center of this svg---
var centerX=200
var centerY=200
//---every 30 degrees around a center point--
//---button---
function placeArrowsAroundCircle()
{
    for(var k=0;k<12;k++)
    {
        var rotateAngle=k*30
        var grayArrow=document.createElementNS(NS,"use")
        grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
        grayArrow.setAttribute("onmouseover", "hilite(evt)")
        grayArrow.setAttribute("onmouseout", "unhilite(evt)")
        grayArrow.setAttribute("rotateAngle", rotateAngle)
        grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(grayArrow)
    }
    for(var k=0;k<12;k++)
    {
        var rotateAngle=k*30+15 //--offset 15 degrees---
        var blackArrow=document.createElementNS(NS,"use")
        blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
        blackArrow.setAttribute("onmouseover", "hilite(evt)")
        blackArrow.setAttribute("onmouseout", "unhilite(evt)")
        blackArrow.setAttribute("rotateAngle", rotateAngle)
        blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
        mySVG.appendChild(blackArrow)
    }
    svgSourceValue.value=svgDiv.innerHTML
}
//--onmouseover---
function hilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
    //---IE and Chrome---
    if(evt.target.correspondingUseElement)
        var target=evt.target.correspondingUseElement
    else  //---FF---
        var target=evt.target

    var rotateAngle=target.getAttribute("rotateAngle")
    target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}

document.addEventListener("onload",init(),false)
//---adjust(transform) the imported paths so they fit this svg viewPort---
function init()
{
    //--get actual size---
    var bb=importedPaths.getBBox()
    var bbx=bb.x
    var bby=bb.y
    var bbw=bb.width
    var bbh=bb.height
    //---find the center point of this <g>---
    var cx=bbx+.5*bbw
    var cy=bby+.5*bbh

    //---set desired size, i.e. scale the import--
    var heightSize=80
    var scale=heightSize/bbh
    //---translate so it's  bottom is centered is at (0,0)
    var transX=(-cx)*scale
    var transY=(-cy-.5*bbh)*scale
    importedPaths.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")

    //---create your symbol objects from transformed import, by placing <g> in defs--
    var blackArrow=importedPaths.cloneNode(true)
    blackArrow.id="myBlackArrow"
    myDefs.appendChild(blackArrow)
    var grayArrow=importedPaths.cloneNode(true)
    grayArrow.id="myGrayArrow"
    grayArrow.setAttribute("fill","silver")
    myDefs.appendChild(grayArrow)
    //---see textarea---
    svgSourceValue.value=svgDiv.innerHTML
}
</script>
</body>
</html>