1

使用Raphaël 库,您可以创建集合,它们是包含 Raphaël 元素的类数组对象,并且可以在调用元素方法时隐式循环这些元素。问题在于,尽管集合类似于数组,但并非原型中的所有函数Array都可用于 Raphaël 集合,包括Array.concat(). 如何将两个 Raphaël 集合连接成一个新集合?我不想修改任何一个原始集。

4

1 回答 1

1

好吧,我想出了一个办法。秘诀在于 Raphaël 集有一个未记录的属性,称为items,它是该集所包含的 Raphaël 元素的普通数组。

Raphaël 集确实有一些类似于Array.splice()方法的东西,它用于从数组中删除和插入元素。的语法Array.splice()anArray.splice(startingIndex, numberOfItemsToRemove, itemToInsert[, anotherItemToInsert...]). 该函数创建一个空集合,它们只是splice将两个现有集合中的项目放入新集合中。在这种情况下,两者startingIndexnumberOfItemsToRemove都应该是0因为一个新集合有一个lengthof 0,这意味着唯一的索引是0并且你不可能删除多个0元素。

下面的函数利用了 JavaScript 的function.apply()on 方法splice()(如splice.apply())。apply()接受两个参数:分配给this函数内部关键字的值和成为函数参数的数组。我们可以创建一个数组apply()作为参数传递给splice(). 该数组中的前两项是startingIndexnumberOfItemsToRemove,因此它们都将设置为0。所有后续参数都是要插入到新集合中的项目。我们可以用 初始化这个数组[0, 0],它是一个真正的数组,它确实concat()方法。我们现在要做的就是concat()每个集合的元素,我们可以从item集合的属性中获取到[0, 0],创建一个参数数组,这些参数将传递给splice()新的空集的方法。

function concatSets(paper, setA, setB){
    var newSet = paper.set(); // Creates a new, empty set
    newSet.splice.apply(newSet, [0, 0].concat(setA.items, setB.items));
    return newSet;
}

下面的函数可以根据需要连接任意数量的集合;只需传入一个集合数组作为第二个参数,并将纸对象作为第一个参数。如果arrayOfSets.length == 1,则该函数只是创建该集合的副本。

function concatManySets(paper, arrayOfSets){
    var i, newSet, argsToPass;
    argsToPass = [0, 0]; // The first two parameters of a normal call to Array.splice()
    newSet = paper.set(); // Creates a new, empty set
    for(i = 0; i < arrayOfSets.length; i++){
        argsToPass = argsToPass.concat(arrayOfSets[i].items);
    }
    newSet.splice.apply(newSet, argsToPass);
    return newSet;
}
于 2013-07-27T01:30:18.533 回答