-2

My goal is to mask each individual image in a portfolio using svg.js to generate the image mask. I am working with svg.js and a cargo.collective theme.

I wrote some js to generate the <svg> tag and wrap a set of images individually, this works fine however <img> tags do not render inside of <svg></svg>

To get around this problem I am using svg.js to generate a seperate <image> tag. This is where my problem lies - I can't seem to get transfer the source in <img> to the new <image> tag created in svg.js My best efforts returned [object Object] in the <image> href.

I would like to get the images to render inside the <svg> tags so i can apply the mask to them irrespective of what image is actually in the container.

HTML

<svg class="thumb_image" id="drawing" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image id="SvgjsImage1005" width="0" height="0"></image>
  <image class="imgclip" src="http://payload280.cargocollective.com/1/16/516926/7919591/prt_275x242_1403202556_2x.jpg" width="275" height="242" data-hi-res="http://payload280.cargocollective.com/1/16/516926/7919591/prt_275x242_1403202556_2x.jpg"></image>
  <defs id="SvgjsDefs1000">
    <polygon id="SvgjsPolygon1006" points="0,0 275,50 0,270" fill="#f2f0ce" stroke-width="0"></polygon>
  </defs>
</svg>

Portfolio with svg masked images

Community
  • 1
  • 1
tijanicharles
  • 183
  • 3
  • 17
  • 1
    Please make a jsFiddle so we can understand the problem better. From my understanding you will have a `` element on your page and you want to convert it to a `` element in an SVG. The way to do that is get the `src` from the image, remove the `` element, and then create an ``element in the SVG with `draw.image('/path/to/image.jpg')`. Also, look at utilizing for instance the Chrome debugger to inspect what data you are trying to insert in your `href` as that is not a string. But start with a fiddle to illustrate your example. – Nils Aug 22 '14 at 06:38
  • Thanks for the advice on that, here is my [js fiddle](http://jsfiddle.net/tijanicharles/tduzgd3g/1/) I have to warn it's a little dicey in the rendition of the code. The template I am working with is a handlebars.js template that generates the html code I have added a screenshot to show what it should look like as opposed to what I have in jsfiddle. With that being said, the code is exactly the same and achieves the result in my screenshot. Thanks again for the help. – tijanicharles Aug 22 '14 at 15:39
  • I opened the fiddle and I will not bother looking at it. It is to much junk in there to go through. If you don't put in time to make a reasonable question you will not get any good answers. – Nils Aug 26 '14 at 05:37
  • Ok, [here's](http://jsfiddle.net/tijanicharles/tduzgd3g/5/) an update to the code. I've removed all the non relevant pieces of information. – tijanicharles Aug 28 '14 at 15:59
  • I updated the screenshot to better explain what I am trying to do. – tijanicharles Aug 28 '14 at 16:16
  • As you can see I have successfully embedded a new image into the svg tag and clipped it with a polygon. The issue now is that it appends only 1 src to each image instead of iterating though all the project images. – tijanicharles Aug 28 '14 at 16:20

2 Answers2

1

svg <image> tags have an xlink:href attribute which points to the image data rather than a src attribute.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
0

I hope I understand what you want to do, but the fiddle example you give is bad. There is an plugin in svg.js which lets you absorb existing SVG:s in svg.js, https://github.com/wout/svg.absorb.jshttps://github.com/wout/svg.absorb.js. You need to use that in your example. However, your svg is so simple so it might be better to create it from scratch. So instead of including broken SVG:s to your dom, you can generate an javascript array on the server side and use that to generate your SVG:s.

var imageSrc = ['http://placekitten.com/g/200/300', 'http://placekitten.com/g/200/300'];

//get SVG target
var target = $("#target");

// Create SVG:s
imageSrc.forEach(function (src) {
    // create a wrapper div for the SVG element
    var svgWrapper = $('<div>').appendTo(target);

    // Create the SVG, please note that we need the native DOM node
    // That is why [0] is used
    var draw = SVG(svgWrapper[0]).size(300, 200);

    // draw the image
    var image = draw.image(src);

    //polygon image mask
    var polygon = draw.polygon('0,0 275,50 0,270').fill('#f2f0ce').stroke({
        width: 0
    });

    // create the mask
    image.maskWith(polygon);
});

Example: http://jsfiddle.net/h9ydmt80/

If you are generating the page on server side and you don't need to continue to manipulate the SVG:s I would just generate the SVG:s there. In that case they would look like this.

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="0" height="0" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <mask id="mask">
            <polygon points="0,0 275,50 0,270" fill="#f2f0ce" stroke-width="0"></polygon>
        </mask>
    </defs>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="200" xmlns:xlink="http://www.w3.org/1999/xlink">
    <image xlink:href="http://placekitten.com/g/200/300" width="200" height="300" mask="url(#mask)"></image>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="200" xmlns:xlink="http://www.w3.org/1999/xlink">
    <image xlink:href="http://placekitten.com/g/200/300" width="200" height="300" mask="url(#mask)"></image>
</svg>

The first SVG is not visible, and only contains the mask, the two last SVG:s only contains the image and a reference to the mask in the first SVG.

Example: http://jsfiddle.net/ayw8w9ak/2/

Please note that it is not src attribute in SVG:s, it's xlink:href like in the example above.

Nils
  • 2,041
  • 1
  • 15
  • 20
  • Thanks for that in-depth answer Nils, It was a little difficult explaining the concept behind what I was trying to do clearly so I appreciate the input from everyone. I ended up writing most of the script that got it to work and your answer will certainly help me optimize it. I'll post a link to the site in a couple of days. – tijanicharles Sep 12 '14 at 01:22
  • Thought I'd share a link so you can see how it turned out. Thanks again for the help guys! http://regardless.co – tijanicharles Feb 04 '16 at 09:22