捕获SVG元素圈上的更改,并通过js在其他位置更改属性 [英] Catch changes on SVG element circle and change attributes elsewhere via js

查看:118
本文介绍了捕获SVG元素圈上的更改,并通过js在其他位置更改属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在HTML文档中有一个嵌入式SVG. (SVG)圆使用<animate>进行动画处理.我试图找到一种方法,仅在圆上水平移动时才将某种事件侦听器放置在该圆上.

I have an embedded SVG in an HTML document. An (SVG) circle is animated using <animate>. I was trying to find a way to put some kind of event listener on that circle only when it moves horizontally.

(水平)移动后,我想找到圆形的x坐标,并为圆形的相对位置设置第三个(外部)矩形形状宽度.第三个矩形就像一个进度条,用于跟踪圆的水平进度.

Upon being moved (horizontally), I'd like to find the x-coordinates of the circle shape and set a third (outside) rect shape width to the relative position of the circle. This third rect would be like a progress bar tracking the horizontal progress of the circle.

是否通过触发某种事件来移动SVG圆(顺便说一句,该圆在SVG g组内部),我可以设置一个侦听器,以便随后更改进度条类型的width属性?

Does the SVG circle (by the way, the circle is inside an SVG g-group) being moved by trigger some kind of event I can set a listener so that then I can change the width attribute of the sort of progress bar?

我认为,如果<animate>或移动/更改的元素触发某种事件,我可以尝试捕获它,然后更改条形图的宽度.

I have thought that if either the <animate> or the element moved/changed triggers some kind of event I could try to catch it and then change the width on the bar.

我发现在矩形上使用独立"动画效果不是很好,因为当圆向上移动时,增长的速度非常不同.我没有使用canvas元素,因为我试图保持可伸缩性和形状语义. (我宁愿使用javascript解决方案,但也希望使用其他方法.)

I have found that it is not much good use an "independent" animate on the rect as the pace of growth is very different when the circle moves upwards. I am not using the canvas element because I am trying to keep the scalability and the shapes semantics. (I would rather prefer a javascript solution but I would be grateful for other approaches.)

分析服务人员对品尼非常感兴趣,并且(我认为)很有帮助.我是SVG的新手,可能会误解了某些内容.正是出于这个原因,我包含了代码.

EDIT after answer: The anser have ben very much to the piint and (I think) helpful. I am very new to SVG and I may have misinterpreted something. Fot that reason I am including code.

我尝试执行您的建议,但似乎没有成功.应用于圆的.cx.animVal.value似乎无法为我提供所需的东西.我将包含代码的切碎版本,该版本应沿水平移动的路径移动球;两个矩形(inBar和outBar)应该跟踪水平位移,水平位移或多或少以与球相同的速度水平增长.为了确保setInterval正常工作并正确收集位置,已在行oBall..animVal和oball..baseVal中添加了一行.在FF 21.0中,animVal沿位移没有变化.我是否正确理解您的建议?这里遵循代码(包括标头等,尤其是我在SVG中是菜鸟):

I have tried to implement your recommendations and I seem to have been unsuccessful. .cx.animVal.value applied to the circle does not seem to get me what I need. I will include a chopped version of my code which should move a ball along a path which itself is being moved horizontally; two rects (inBar and outBar) should be tracking the horizontal displacement growing horizontally more or less at the same rate as the ball. In order to make sure setInterval works and the position is correctly gathered, a line has been added to list oBall..animVal and oball..baseVal. In FF 21.0, there is no change for animVal along the displacement. Have I understood your suggestions correctly? here follow the code (including headers etc. as I am a noob in SVG in particular):

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
    <head><title>Motion</title>
    <script>function beginAnim(anim,sPos){anim.beginElement();}</script>
    </head>
    <body>
    <div id="here">
    <button onclick="beginAnim(document.getElementById('anim'),'out');">START</button>
    </div>
    <div style="height:350px;">
    <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <script type="text/ecmascript">
    <![CDATA[
      function trckngBars(){
        oDiv=document.getElementById('here');
        var oBall=document.getElementById('ball');
        var oBar=[document.getElementById('inBar'),document.getElementById('outBar')];
        idTimer=self.setInterval(function(){updtBars(oBall,oBar);},100);
      }
      function updtBars(oBall,oBar){
        var xCoor=String(oBall.cx.animVal.value);
        oDiv.innerHTML+='==>'+oBall.cx.animVal.value+'..'+oBall.cx.baseVal.value;
        oBar[0].setAttribute("width",xCoor);
        oBar[1].setAttribute("width",xCoor);
      }
    // ]]>
    </script>
    <defs>
    <path id="throw" d="M0,0 q 80,-55 200,20" style="fill: none; stroke: blue;" />
    </defs>
    <g>
      <g>
        <rect x="2" y="50" width="400" height="110" style="fill: yellow; stroke: black;"></rect>
      </g>
      <g>
        <!-- show the path along which the circle will move -->
        <use id="throw_path" visibility="hidden" xlink:href="#throw" x="50" y="130" />
        <circle id="ball" cx="50" cy="130" r="10" style="fill: red; stroke: black;">
          <animateMotion id="ball_anim" begin="anim.begin+1s" dur="6s" fill="freeze" onbegin="trckngBars();" onend="window.clearInterval(idTimer);">
            <mpath xlink:href="#throw" />
          </animateMotion>
        </circle>
        <rect id="inBar" x="50" y="205" width="20" height="30" style="fill: purple;stroke-linecap: butt;">
    <!-- <animate attributeType="XML" attributeName="width" from="0" to="200" begin="ball_anim.begin" dur="6s" fill="freeze" /> -->
</rect>
      </g>
      <animateTransform id="anim" attributeType="XML" attributeName="transform" type="translate" from="0" to="200" begin="indefinite" dur="10s" fill="freeze" />
    </g>
    <rect id="outBar" x="50" y="235" width="10" height="30" style="fill: orange;stroke-linecap: butt;">
    <!-- <animate attributeType="XML" attributeName="width" from="0" to="400" begin="anim.begin+1s" dur="10s" fill="freeze" /> -->
</rect>
    </svg> 
    </div>
    </body>
    </html>

如果代码运行了,显然,正在移动的#ball的animVal仍保持在相同的x坐标(50)处.

If the code is run, it seems that animVal for the moving #ball remains at the same x-coordinat (50) while clearly it is moving.

推荐答案

动画

An event is fired when animations begin, end or repeat but not (as you want) whenever there is a change of animation value.

由于动画是确定性的,尽管您可以在圆形动画开始几秒钟后就开始矩形形状动画.

As animations are deterministic though you can just start the rect shape animation so many seconds after the circle animation starts.

var cx = myCircle.cx.animVal.value;

会在需要时为您提供动画值,只要这是您要设置动画的属性即可.

will give you the animated value if you need it, provided that's the attribute you're animating.

您使用的是animateMotion,而不是单独设置cx和cy属性的动画.我认为获取变换的圆位置的唯一方法是调用getBBox.

You're using animateMotion rather than animating the cx and cy attributes on their own though. I'm think the only way to get the circle position post that transform is to call getBBox.

这篇关于捕获SVG元素圈上的更改,并通过js在其他位置更改属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆