如何使Raphael填充图案随元素一起移动? (背景图片相对于元素的位置) [英] How to make a Raphael fill pattern move with the element? (background image position relative to the element)

查看:106
本文介绍了如何使Raphael填充图案随元素一起移动? (背景图片相对于元素的位置)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何为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>元素执行相同的矩阵变换.我认为这是导致我要避免的行为的原因-我认为patternContentUnitspatternUnits是无关的.这里似乎有一个未解决的问题(在行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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆