如何使Raphael填充图案随元素一起移动? (背景图片相对于元素的位置) [英] How to make a Raphael fill pattern move with the element? (background image position relative to the element)
问题描述
如何为Raphael元素提供随元素移动而移动的填充,就像position: absolute;
HTML元素的CSS background-image
如何相对于其移动的位置保持相同的位置?
How can I give a Raphael element a fill that moves as the element moves, like how the CSS background-image
of a position: absolute;
HTML element would keep the same position relative to its location as it moved?
这是一个示例演示:如何使Raphael元素(三角形路径)的背景图像图案在拖动时的行为与HTML元素(方形div)相同?
Here's an example demo: how can I make the background image pattern of the Raphael element (the triangular path) behave the same while dragged as the HTML element (the square div)?
此问题与 如何使用偏光眼镜模拟器在Raphael.js/IE中固定"模式? -我想使他们试图避免的IE特定行为在所有浏览器中始终如一地发生(包括IE8).
This question is essentially the opposite of How to make a pattern "fixed" in Raphael.js / IE? with the polarised glasses simulator - I want to make the IE-specific behaviour they were trying to avoid happen consistently, in all browsers (including IE8).
正如在另一个问题中详细说明的那样,仅在IE8(VML)中,Raphael元素的行为符合我的要求;但这甚至是不稳定的:诸如在paper
元素上调用setSize
或重新定义填充(本质上是任何迫使重绘的内容)之类的事情都会导致其切换到其他行为.
As detailed in that other question, in IE8 (VML) only, the Raphael element behaves how I want; but even this is erratic: various things like calling setSize
on the paper
element or re-defining the fill (essentially, anything forcing a redraw) cause it to switch to the other behaviour.
对于纯SVG,有一个与此相似的问题,但在撰写本文时没有任何好的答案,而且肯定没有一个对拉斐尔有效.
There's a question similar to this for pure SVG, but without any good answers at time of writing, and certainly none that work for Raphael.
编辑2 :看着SVG模式下发生的情况,似乎每个Raphael变换也会自动对svg <pattern>
元素执行相同的矩阵变换.我认为这是导致我要避免的行为的原因-我认为patternContentUnits
和patternUnits
是无关的.这里似乎有一个未解决的问题(在行this.pattern && updatePosition(this);
旁边突出显示了clip-rect的相同问题)- https://github.com/DmitryBaranovskiy/raphael/issues/638
Edit 2: Watching what happens in SVG mode, it seems that every Raphael transform also automatically does the same matrix transform to the svg <pattern>
element. I think this is what causing the behaviour I'm trying to avoid - I think patternContentUnits
and patternUnits
are unrelated. There's an unresolved issue that seems related here (highlighting the same problem with clip-rect, next to the line this.pattern && updatePosition(this);
) - https://github.com/DmitryBaranovskiy/raphael/issues/638
因此,一种可能性可能是定义应用自定义属性的转换为元素,而不将其也应用于模式.听起来很困难-可能需要破解Raphael或复制很多Raphael转换代码.希望还有其他方法.而上帝会帮助我们在VML ...
So one possibility might be to define a custom attribute that applies a transform to the element without also applying it to the pattern. Sounds difficult - might require hacking Raphael or duplicating lots of Raphael transform code. Hopefully there's some other way. And god help us making this work in VML...
一些潜在的相关信息,不仅仅是路径填充会出现此问题.用paper.image()
创建的Raphael image
元素在SVG模式下不会出现此问题,但是有一个非常相似的问题,在IE8 VML模式下确实很糟糕. 这里是一个演示 的演示,该演示使图像元素移动了几种方式,并且这是一个并行的比较,显示了它们在非IE中如何完美运行而在IE中都失败:
Edit 3: Some potentially relevant information, it's not just path fills that have this problem. Raphael image
elements created with paper.image()
don't have this problem in SVG mode but have a very similar problem that is really bad in IE8 VML mode. Here's a demo of several ways to make image elements move, and here's a side-by-side comparison showing how they all work flawlessly in non-IE and all fail in IE:
推荐答案
我最近偶然发现了一个类似的问题.我在任何地方都找不到可行的解决方案,所以我想出了自己的解决方案.我使用@ user568458的答案作为起点.首先,我像这样更改了updatePosition函数:
I recently stumbled on a similar problem. I couldn't find a working solution anywhere, so I came up with my own. I used the answer by @user568458 as a starting point. First I changed the updatePosition function like so:
updatePosition = function (o) {
if(!o.data("relativeFill")) { //data is a custom store for user's properties
var bbox = o.getBBox(1);
$(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"});
}
},
我还更改了setFillAndStroke
函数的fill
大小写,如下所示:
I also changed the fill
case of setFillAndStroke
function like so:
var relativeFill = o.data("relativeFill"),
isURL = Str(value).match(R._ISURL);
if (isURL) {
el = $("pattern");
var ig = $("image");
el.id = R.createUUID();
$(el, {x: 0, y: 0, patternUnits: relativeFill ? "objectBoundingBox" : "userSpaceOnUse", height: 1, width: 1});
$(ig, {x: 0, y: 0, "xlink:href": isURL[1]});
el.appendChild(ig);
(function (el) {
R._preload(isURL[1], function () {
var w = this.offsetWidth,
h = this.offsetHeight,
bbox = o.getBBox();
$(el, {width: 1, height: 1});
$(ig, {width: relativeFill ? bbox.width : w, height: relativeFill ? bbox.height : h});
o.paper.safari();
});
})(el);
o.paper.defs.appendChild(el);
$(node, {fill: "url(#" + el.id + ")"});
o.pattern = el;
o.pattern && updatePosition(o);
break;
}
然后,每当要使用它时,都必须设置yourElement.data({ relativeFill: true })
Then whenever you want to use it you have to set yourElement.data({ relativeFill: true })
这是一个具有相对重复填充的工作示例: https://codepen.io/mmazur/pen/Gmebrj?editors = 0010
Here's a working example with relative and repeated fill: https://codepen.io/mmazur/pen/Gmebrj?editors=0010
我同意@ user568458,此解决方案非常难看,可能会在以后的Raphael更新中停止工作.但是,拉斐尔(Laphael)最近变化不大,所以我可以承担这个风险.
I agree with @user568458, this solution is very ugly and might stop working with a future Raphael update. However, Raphael hasn't been changing much lately so I'm fine with taking this risk.
修复了此处描述的错误:图片svg圈子使用url填充模式时模糊
Fixed a bug described here: Image blurry when using url fill pattern for svg circle
这篇关于如何使Raphael填充图案随元素一起移动? (背景图片相对于元素的位置)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!