Thursday, October 19, 2017

ng-include of inline SVG does not display gradient except in Chrome

I have setup an NG-INCLUDE which loads an SVG file that has classes “hover_color_change” so that the correct polygons can have their fill attribute updated:

<div class="prod-illustration-div col s12 m8">
   <div class="prod-svg-wrapper" ng-include="'/img/illustrations/illustration_' + productIdObj.illustration + '.svg'" onload="defaultFill(productIdObj.colors)">
    </div>
</div>

I then have color swatches which trigger the $scope.hoverColorText() which calls the updateSVGFill() method to display the SVG fill matching the hover color and creates a shading of gradient so it’s not a solid color.

Here is live link – WORKS IN CHROME

In Chrome it works, however, in Safari, FF, Edge, it does not. I referenced this suggested answer which suggests referencing the ID attribute, which I believe I am already doing:

    $scope.defaultFill = function (colors) {
        if (colors) {
            var defaultColor = colors[Object.keys(colors)[0]];
            createGradient($('svg')[0], 'MyGradient', [
                { offset: '10%', 'stop-color': createShade(defaultColor, 0.2) },
                { offset: '100%', 'stop-color': defaultColor }
            ]);
            updateSvgFill();
            return true;
        }
    };

    $scope.hoverColor = ' ';
    $scope.hoverColorText = function (selectedHover) {
        if (selectedHover.hex) {
            $scope.hoverColor = selectedHover.color;
            updateGradient(selectedHover.hex);
        }
    };

    function updateGradient(color) {
        $('linearGradient#MyGradient #stop-0').attr('stop-color', createShade(color, 0.2));
        $('linearGradient#MyGradient #stop-1').attr('stop-color', color);
    }


    function createGradient(svg, id, stops) {
        var svgNS = svg.namespaceURI;
        var grad = document.createElementNS(svgNS, 'linearGradient');
        grad.setAttribute('id', id);
        for (var i = 0; i < stops.length; i++) {
            var attrs = stops[i];
            var stop = document.createElementNS(svgNS, 'stop');
            stop.id = 'stop-' + i;
            for (var attr in attrs) {
                if (attrs.hasOwnProperty(attr)) stop.setAttribute(attr, attrs[attr]);
            }
            grad.appendChild(stop);
        }

        var defs = svg.querySelector('defs') || svg.insertBefore(document.createElementNS(svgNS, 'defs'), svg.firstChild);
        return defs.appendChild(grad);
    }

    function createShade(color, percent) {
        var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
        return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
    }

    function updateSvgFill(hex) {
        $('.hover_color_change').attr('fill', 'url(#MyGradient)');
    }

So: am I including this SVG asset correctly with an NG-Include?

Naturally, if I remove fill changes work fine on hover.

Source: AngularJS



from Angular Questions https://angularquestions.com/2017/10/19/ng-include-of-inline-svg-lineargradient-does-not-display-gradient-except-in-chrome/
via @lzomedia #developer #freelance #web #lzomedia.com

No comments:

Post a Comment