javascript 使用 Snap.svg 选择多个路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20190752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 17:59:14  来源:igfitidea点击:

Select multiple paths with Snap.svg

svgraphaeljavascriptsnap.svg

提问by Marcatectura

Background: I'm using snap.svg to animate paths in an inline svg, and I'm trying to animate several paths in one function.

背景:我正在使用 snap.svg 为内联 svg 中的路径设置动画,并且我试图在一个函数中为多个路径设置动画。

Problem: using the code below, I'm only able to select a single path in one grab function. In the code below, I've used multiple selectors, but the animation only affects rect#rect-one. How can I select multiple paths in Snap.svg?

问题:使用下面的代码,我只能在一个抓取功能中选择一条路径。在下面的代码中,我使用了多个选择器,但动画只影响 rect#rect-one。如何在 Snap.svg 中选择多个路径?

Thanks for the help!

谢谢您的帮助!

HTML/Inline SVG:

HTML/内联 SVG

<a id="one">link</a>

<svg>
<rect  id="rect-one" fill="#231F20" width="39" height="14"/>
<rect id="rect-two" x="54" fill="#231F20" width="39" height="14"/>
<rect id="rect-three" x="104" fill="#231F20" width="39" height="14"/>
</svg>

Snap:

捕捉

window.onload = function () {
    var grabLink = Snap.select('body a#one'),
        grabPathRectangles = Snap.select('#rect-one, #rect-two, #rect-three');

    function colorPathRectangles(){
        grabPathRectangles.animate({fill: 'red'}, 100, mina.ease);
    } 
    function resumePathRectangles(){
        grabPathRectangles.animate({fill: 'green'}, 100, mina.ease);
    }   
    grabLink.hover(colorPathRectangles, resumePathRectangles);  
};

回答by Ian

I think the problem is that you can't apply animations to a set (edit: possible now), so you would have to apply it to each element. For this you could use the forEach command, so...

我认为问题在于您无法将动画应用于集合(编辑:现在可能),因此您必须将其应用于每个元素。为此,您可以使用 forEach 命令,因此...

 grabPathRectangles.forEach( function(elem,i) {
        elem.animate({fill: 'red'}, 1000, mina.ease);
  });

Jsfiddle here... http://jsfiddle.net/DZ4wZ/3/

Jsfiddle在这里... http://jsfiddle.net/DZ4wZ/3/

Or I suspect you could put them into a group and animate the group as one if that makes more sense. Here is an example http://jsfiddle.net/DZ4wZ/5/however, I had to remove the original fill.

或者我怀疑您可以将它们放在一个组中并将该组作为一个整体进行动画处理,如果这更有意义的话。这是一个示例http://jsfiddle.net/DZ4wZ/5/但是,我不得不删除原始填充。

Edit: Looks like you can apply animations to a set now, I think this feature didn't used to work, or was buggy, so not historically used. So you may want to make sure you have the latest version of Snap if using it.

编辑:看起来你现在可以将动画应用到一个集合中,我认为这个功能过去不工作,或者有问题,所以历史上没有使用过。因此,如果使用 Snap,您可能需要确保拥有最新版本的 Snap。

回答by KyleMit

@Ian's answer is unfortunately incorrect, although his fiddle silently fixed the actual issue.

不幸的是,@Ian 的回答是不正确的,尽管他的小提琴默默地解决了实际问题。

The problem is that you have used Snap.selectinstead of Snap.selectAllto query for multiple elements. Select will only ever bring back the first instance that satisfies the selector, whereas selectAll will grab all of them and return as a set or array of Element objects. That's why only a single element was responding to the animation.

问题是您使用Snap.select而不是Snap.selectAll查询多个元素。Select 只会带回满足选择器的第一个实例,而 selectAll 将获取所有它们并作为 Element 对象的集合或数组返回。这就是为什么只有一个元素响应动画的原因。

Further, you definitely can call animateon a set of elements simultaneous, so there's no need to complicate things with an additional for loop.

此外,您绝对可以同时调用animate一组元素,因此无需使用额外的 for 循环使事情复杂化。

From the docs on Set.animate():

从文档开始Set.animate()

Animates each element in set in sync.

同步动画中的每个元素。

Here's a working demo using Stack Snippets.

这是一个使用 Stack Snippets 的工作演示。

It starts by logging the different outputs of select and SelectAll

它首先记录 select 和 SelectAll 的不同输出

console.log("select:    ", Snap.select(   '#rect-1, #rect-2, #rect-3'));
console.log("selectAll: ", Snap.selectAll('#rect-1, #rect-2, #rect-3'));

var grabLink = Snap.select('#one'),
    grabPathRectangles = Snap.selectAll('#rect-1, #rect-2, #rect-3');

function colorPathRectangles(){
  grabPathRectangles.animate({fill: 'red'}, 1000, mina.ease);
} 
function resumePathRectangles(){
  grabPathRectangles.animate({fill: 'green'}, 1000, mina.ease);
}   

grabLink.hover(colorPathRectangles, resumePathRectangles);  
a#one {
  display: block;
  border: 1px solid blue;
  margin-bottom: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>

<a id="one">Hover Me</a>

<svg>
  <rect id="rect-1" fill="#231F20" width="39" height="14"/>
  <rect id="rect-2" fill="#231F20" width="39" height="14" x="54" />
  <rect id="rect-3" fill="#231F20" width="39" height="14" x="104" />
</svg>