如何在保持单个元素不透明度状态的同时将一堆 Raphael 对象的不透明度设置为一个对象?我不能在不影响每个单独元素的情况下在集合上制作动画,所以我如何创建一个对象来处理 - 如果这有助于回答,我正在以 jQuery 思维方式思考。
2 回答
适用于任意数量的元素、任意数量的更改和任意数量的集合的通用解决方案是使用它根据附加到单个元素的值和为集合中的每个元素计算和存储正确的不透明度级别集。.customAttributes
例如(在演示中,多次单击以查看三个圆圈的不透明度以一种方式更改,而单击的单个圆圈则以另一种方式更改):
http://jsbin.com/oxeyih/9/edit
使用类似这样的东西,它本质上将此功能添加到此 Raphael 论文实例中的所有现有和未来的集合和元素中:
// apply this using .attr or .animate to sets or each in a set
// to set the opacity of the set as a whole, maintaining relative opacity
paper.customAttributes.setOpacity = function( setOpacity ){
// elemOpacity might not be set yet
if (typeof this.attr('elemOpacity') == 'undefined') {
this.attr('elemOpacity', this.attr('opacity'));
}
return {opacity: setOpacity * this.attr('elemOpacity')};
}
// apply this using .attr or .animate to indiviual elements
// to set that element's opacity, factoring in the opacity of the set
paper.customAttributes.elemOpacity = function( elemOpacity ){
// setOpacity might not be set yet; setting it could create infinite loop
var setOpacity = this.attr('setOpacity');
setOpacity = typeof setOpacity == 'undefined' ? 1 : setOpacity;
return {opacity: setOpacity * elemOpacity };
}
如果任一自定义属性低于 0.0 或高于 1.0,您的代码可能会出错,您可能需要添加某种验证。
任何时候你设置一个元素的不透明度,使用animate({elemOpacity: xx}, time);
(或.attr()
)它会考虑到集合的不透明度,并且任何时候你想设置一个集合的不透明度,调用animate({setOpacity: xx}, time);
一个集合,它会考虑每个元素的考虑到不透明度。
在某些具有复杂集合的情况下,与其对许多在许多浏览器中可能会很慢的元素进行动画处理,不如在性能上更好,并且更简单,只需在顶部添加一个覆盖层......如果有问题的元素可以安全发送.toBack()
,您无需进一步与他们互动(点击、悬停)。
只需添加一个覆盖矩形,设置为匹配容器元素的继承颜色(这是一种动态获取继承背景颜色的方法),然后将其发送到 set .toBack()
,并为该覆盖的不透明度设置动画。
如果你保留全局变量,那么你可以这样做。看演示。
var p = new Raphael(10,10, 500, 500);
var x = 0.5;
var r = p.rect(20, 20, 100, 80, 5).attr({fill: 'red', opacity: x}),
c = p.circle(200, 200, 80).attr({fill: 'orange'}),
s = p.set(r, c);
s.click(function() {
s[0].attr({opacity: x - 0.3});
s[1].attr({opacity: 0.3});
});