0

For a SVG path I am combining a background filling with a filter containing an image which may be scaled and translated.

Here is the full code for a function which cares for amending a list of pathes which may contain images:

if (slots.image.length < 1) {
    return;
}

jQuery.each(slots.image, function (index, slot) {
    var imageSlot = slot.slotRef;
    var svg = slot.svg;

    var svgRoot = svg.root();
    var defsElements = jQuery('defs', svgRoot);
    var defs = defsElements.length > 0 ? defsElements.first() : svg.defs('customDefinitions');

    imageSlot.parent().show();
    imageSlot.show().attr('class', '');

    var sectionNumber = (index+1);
    var customImage = settings.customImages[sectionNumber];

    var bgColour = customImage.bgColour;
    imageSlot.css('fill', bgColour);

    var scale = customImage.scale;
    var moveX = customImage.moveX;
    var moveY = customImage.moveY;

    if (sectionNumber == getActiveImageArea()) {
        jQuery('#showScale').text(scale + '%');
        jQuery('#showMoveX').text(moveX);
        jQuery('#showMoveY').text(moveY);
    }

    if (customImage.file == '' || customImage.file == 'none') {
        return true; // continue;
    }

    var imageFile = customImage.file;
    var imageWidth = customImage.width;
    var imageHeight = customImage.height;

    jQuery('#customImage' + sectionNumber + 'Filter').remove();
    var filter = svg.filter(defs, 'customImage' + sectionNumber + 'Filter',
        0, 0, scale + '%', scale + '%',
        {
            filterUnits: 'objectBoundingBox'
        }
    );

    // add the image
    var outputSlot = 'customImage' + sectionNumber;
    svg.filters.image(filter, outputSlot, imageFile);
    // move it
    svg.filters.offset(filter, 'movedImage' + sectionNumber, outputSlot, moveX, moveY);
    // combine image with path for clipping
    svg.filters.composite(filter, 'clip' + sectionNumber, 'in', 'movedImage' + sectionNumber, 'SourceGraphic');
    // mix both images
    svg.filters.blend(filter, '', 'normal', 'clip' + sectionNumber, 'SourceGraphic');

    imageSlot.attr('filter', 'url(#customImage' + sectionNumber + 'Filter)');
});

There remains one problem with this: if the image is scaled down the background is scaled down, too. The same happens when the image is moved. This can cause that the background does not cover the whole path anymore.

Is it possible that only the image is scaled and translated while the background is always applied to the whole path?

3
  • Please post your code Commented Mar 30, 2016 at 3:06
  • Added the code above.
    – Guite
    Commented Mar 30, 2016 at 5:16
  • Maybe a possible way to go is duplicating the path: one time in the background with the background colour filling, and another one on top of it containing the image filter and a transparent background. Is this reasonable? Other ideas?
    – Guite
    Commented Apr 4, 2016 at 13:50

1 Answer 1

0

The problem cause is that I scaled the whole filter. Better is using the preserveAspectRatio attribute like described here: Crop to fit an svg pattern

Not the answer you're looking for? Browse other questions tagged or ask your own question.