如何在 Raphael.js / IE 中“固定”模式?

Posted

技术标签:

【中文标题】如何在 Raphael.js / IE 中“固定”模式?【英文标题】:How to make a pattern "fixed" in Raphael.js / IE? 【发布时间】:2012-04-05 03:54:14 【问题描述】:

我正在制作一个小工具来说明偏光镜片的好处。基本上,用户将镜头(Raphael.js 路径)拖到令人眼花缭乱的场景(容器 DIV 的 CSS 背景)上并“透视”镜头。这是js代码:

var rsr = Raphael("playmask", 720,540);
// Lens path
var path_f = rsr.path("M0,73.293c0.024-39.605,17.289-53.697,35.302-61.34C53.315,4.312,99.052-0.012,119.011,0 c38.56,0.021,43.239,11.164,43.229,29.9c-0.002,3.45-0.76,28.632-16.349,58.949c-10.332,20.092-28.434,60.424-76.452,60.396 C29.821,149.223-0.022,112.898,0,73.293 M200.594,29.922c0.011-18.734,4.699-29.871,43.262-29.851 c19.96,0.013,65.691,4.39,83.695,12.052c18.005,7.662,35.254,21.772,35.231,61.379c-0.023,39.606-29.909,75.896-69.526,75.872 c-48.02-0.027-66.076-40.377-76.384-60.484C201.32,58.557,200.594,33.373,200.594,29.922");

path_f.attr("stroke-width":2, fill:'url(img/polarized.jpg)' );

var move = function(dx,dy)
    this.translate( dx-this.ox, dy-this.oy );
    this.ox = dx;
    this.oy = dy;
,
start = function()
    this.ox = 0;
    this.oy = 0;
,
end = function()   
;

path_f.drag(move,start,end);

#playmask div 有这个 CSS(只是“非极化”背景图像和大小):

#playmask
    height:540px;
    width:720px;
    background: url(img/unpolarized.jpg);

我坚持的是:

Chrome/Firefox 一如既往地表现不错:镜头形状显示出来,并且在拖动镜头时填充图像看起来“固定”(见第一张图片); IE 版本 7、8、9 可以工作,但(令人惊讶!)它们的行为方式不同:填充图像“粘”在镜头形状上(参见第二张图片)。

我在这里要问的是:我能否让 IE9/8/7 以类似的方式运行,即在拖动镜头时保持填充图像固定?如果有,怎么做?

火狐截图:

IE9截图:

编辑 使用 Modernizr 检测浏览器功能,我注意到这种奇怪的行为似乎与 IE 的 "no-smil" 功能有关。 我发现 IE9 的一个奇怪行为...背景没有“粘”,但是如果我拖动蒙版,选择一些文本并按下鼠标右键,它会刷新“极化”背景到正确的位置!!

编辑 2(2012 年 5 月 21 日) 尚无解决方案 :( 但更准确地说,它与 "no-smil" 功能没有任何关系; 而且,在 IE9 上重现错误的正确方法是拖动玻璃,在页面的其余部分选择一些文本,然后滚动弹出的加速器图标(其中带有箭头的蓝色图标)。 bg 在正确的位置神奇地“刷新”。

重要修改 3(2012 年 8 月 28 日)

您可以在this jsfiddle (http://jsfiddle.net/q4rXm/17/) 中找到所有内容

【问题讨论】:

+1 解释问题的方式。 @rajkamal 非常感谢 :) 请记住,IE 使用 VML 而不是 SVG,您可能已经知道这一点,但我认为值得一提,因为它有助于调查 我同意,写得很好的问题。 +1。希望得到很好的答案.. 如果一切都失败了,Dimitry Baronovsky(Raphael 的作者)将知道其原因和可能的解决方案。我听过他关于 IE 中动画的演讲之一——以及正确渲染它需要哪些古怪的垫片。这可能是类似的情况。一切顺利。 【参考方案1】:

Raphael 在 IE 中创建的 VML 元素有一些类似的问题,尤其是在尝试将元素浮动到其他元素之上时,等等。

VML 元素有时似乎会出现在 DOM 中奇怪的位置,并且带有奇怪的 CSS 值,例如“position: static”,您会在其中期望“position: absolute”或“position: fixed”。我会仔细检查这些 CSS 值,并确保这些元素位于您认为它们在 DOM 中的位置。

我还让 Raphael 将 IE 中容器的位置值重置为“位置:静态”。在这种情况下,我不得不在我的样式表中添加一行来强制它返回。在您的情况下,您可以尝试:

#playmask 
  position: absolute!important;

围绕这些 VML 元素的流程似乎发生了奇怪的事情......

【讨论】:

谢谢,但不幸的是,这并没有改变 IE9 上的任何内容。其实这个问题与#playmask无关,而与path_f拉斐尔路径元素有关。【参考方案2】:

这与元素的定位有关。

尝试为#playmask 指定绝对值,并为其父项指定位置:相对

我记得以前和拉斐尔一起玩时遇到过类似的事情。只发生在IE,我以为是Raphael的bug,后来发现是定位问题。

【讨论】:

【参考方案3】:

对于所有那些说 IE9 只能处理 VML 而不能处理 SVG 的答案。不对。 IE9 在一定程度上具有原生 SVG 支持。 OP您是否尝试过使用剪贴蒙版而不是拖动填充来执行此操作?我的理解是更改剪贴蒙版路径的位置应该正确“显示”图片的正确部分。希望在此之后为背景添加静态图像不会太难。

【讨论】:

【参考方案4】:

这似乎是 IE 中的重绘错误。一种解决方法是通过添加

来重置填充图像
path_f.attr(fill:'url(http://www.fotoshack.us/fotos/58480536599_97943820.jpg)');

翻译后。 See fiddle here。这在 IE9 中可以正常工作,只是有点迟钝,但也许您可以找到一种更便宜的强制重绘方法。未在较旧的 IE 中测试。此外,它会导致在 Opera 和 Chrome 中闪烁,因此您需要检测 IE,因此只有在 IE 中运行时才重置填充。


编辑: 更好的选择是reset the size of the canvas:

group_a.translate( dx-this.ox, dy-this.oy );
rsr.setSize(720,540);

这不会导致在其他浏览器中闪烁,因此无需进行 IE 检测。

【讨论】:

IE8 太奇怪了。对我来说,只需两次声明填充属性 - 即使在转换之后,实际上只是在自身之后复制和粘贴行 - 会导致此处所需的效果。 另外值得一提的是,setSize() 方法在 IE8 中不起作用。人们经常使用 Raphael 来兼容 IE8。但是,使用 element.attr('fill', element.attr('fill') ); 重置填充确实有效。

以上是关于如何在 Raphael.js / IE 中“固定”模式?的主要内容,如果未能解决你的问题,请参考以下文章

Raphael JS 中的 Rect 在所有边上的笔画宽度不同

raphael.js的使用

Raphael js 文本定位:将文本居中在一个圆圈中

Raphael JS:如何从 Dom 对象(Element.node)中获取 Raphael 元素?

raphael.js 如何将 id 添加到路径

如何从 svg 中的所有点知道路径的 m 或 M 点?(使用 raphael.js)