I want to this this Fill SVG element with with a background-image with an offset, but using Raphael JS.
Displaying an rectangle with a background image without
I'd suggest drawing the image separately from the rect. If you need the stroke you can either draw a filled rect behind the image or draw the rect on top with stroke and no fill.
The image is drawn with clipping to clip out the part you want, and you can control the offset of the image either with img.translate(x,y)
or by the paper.image
params:
var img = paper.image("foo.png", 10, 10, 80, 80);
img.attr({ "clip-rect": "20,20,30,30" });
This above works only for rectangular clipping (svg itself supports arbitrary clipping via the 'clip-path' property). If you want a pattern fill, then you currently have to step outside of what raphaël provides. Easiest is probably to just extend raphaël to do that, and to provide some other fallback to the browser(s) that doesn't support svg.
SVG Web seems to have at least partial support for svg patterns if you're looking for something to work as a fallback for old browsers.
The above with clip-rect
only works for rectangles - if you need to set a background-position offset for a path
, there's a relatively easy way:
M
segment with just two co-ordinates to the start of your path string. This changes the point that is considered the path's origin, thus changing the position the image begins at.So imagine you had a triangle path defined as M0,0 50,0 25,35Z
. If you want to offset the background image left by 20px and up by 5px, append M-20,-5
to the start of the string, giving M-20,-5 M0,0 50,0 25,35Z
.
Here's a demo of exactly that:
Note that, the actual background offset will be the difference between the values you input and the top left bounding box of the path at the time the fill is applied. If you can make sure when defining the original path that this is 0,0
, then life will be easier.
If you're thinking of defining a function or custom attribute that applies background position on the fly - for example, using element.getBBox() to counteract the above issue - be aware that there's a bug in VML mode which means that in IE8 any additional M segments get scrubbed out of the path if you update the path using .attr('path')
.
Also, in SVG mode, you need to refresh the fill, which may mean you need to reapply the relative position fix.
Here's a demo of a custom attribute working for the above in everything except IE8 - click the shape to update background position - with some failed attempts to make it work in IE8... http://jsbin.com/oxuyeq/13/edit