CSS (jQuery SVG छवि प्रतिस्थापन) का उपयोग करके SVG छवि का रंग कैसे बदलें?


437

यह एक आत्म क्यू एंड ए कोड का एक आसान टुकड़ा है, जिसके साथ मैं आया था।

वर्तमान में, एसवीजी छवि को एम्बेड करने का एक आसान तरीका नहीं है और फिर सीवीजी तत्वों तक सीएसएस के माध्यम से पहुंच है। जेएस एसवीजी फ्रेमवर्क का उपयोग करने के विभिन्न तरीके हैं, लेकिन वे अत्यधिक जटिल हैं यदि आप जो भी कर रहे हैं वह रोलओवर राज्य के साथ एक सरल आइकन बना रहा है।

तो यहाँ है कि मैं क्या साथ आया था, जो मुझे लगता है कि एक वेबसाइट पर एसवीजी फ़ाइलों का उपयोग करने का सबसे आसान तरीका है। यह शुरुआती टेक्स्ट-टू-इमेज रिप्लेसमेंट विधियों से इसकी अवधारणा लेता है, लेकिन जहां तक ​​मुझे पता है एसवीजी के लिए कभी नहीं किया गया है।

ये है प्रश्न:

मैं एक एसवीजी को कैसे एम्बेड करूं और जेएस-एसवीजी ढांचे का उपयोग किए बिना सीएसएस में अपना रंग बदलूं?


1
दुर्भाग्य से img टैग IE में svg फ़ाइलों के साथ काम नहीं करता है, इसलिए ध्यान रखें कि। IE एम्बेड टैग पहचानते हैं। वैसे भी, अच्छा काम!

2
Svg के लिए, आपको "fill" css प्रॉपर्टी का उपयोग करना चाहिए। छवियों के लिए "फिल्टर" का उपयोग करना उचित है। "फ़िल्टर" वास्तव में दोनों के लिए काम करता है लेकिन वेक्टर ग्राफिक के लिए उस काम को करना अनावश्यक है।
सामी बेनचरिफ़

जवाबों:


536

सबसे पहले, अपने HTML में एक SVG ग्राफिक एम्बेड करने के लिए IMG टैग का उपयोग करें। मैंने ग्राफिक बनाने के लिए Adobe Illustrator का उपयोग किया।

<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>

यह वैसा ही है जैसे आप एक सामान्य छवि को कैसे एम्बेड करेंगे। ध्यान दें कि आपको svg का एक वर्ग होने के लिए IMG सेट करने की आवश्यकता है। The सोशल-लिंक ’वर्ग केवल उदाहरण के लिए है। आईडी की आवश्यकता नहीं है, लेकिन उपयोगी है।

फिर इस jQuery कोड (एक अलग फ़ाइल या HEAD में इनलाइन) का उपयोग करें।

    /**
     * Replace all SVG images with inline SVG
     */
        jQuery('img.svg').each(function(){
            var $img = jQuery(this);
            var imgID = $img.attr('id');
            var imgClass = $img.attr('class');
            var imgURL = $img.attr('src');

            jQuery.get(imgURL, function(data) {
                // Get the SVG tag, ignore the rest
                var $svg = jQuery(data).find('svg');

                // Add replaced image's ID to the new SVG
                if(typeof imgID !== 'undefined') {
                    $svg = $svg.attr('id', imgID);
                }
                // Add replaced image's classes to the new SVG
                if(typeof imgClass !== 'undefined') {
                    $svg = $svg.attr('class', imgClass+' replaced-svg');
                }

                // Remove any invalid XML tags as per http://validator.w3.org
                $svg = $svg.removeAttr('xmlns:a');

                // Replace image with new SVG
                $img.replaceWith($svg);

            }, 'xml');

        });

उपरोक्त कोड क्या है, सभी IMG वर्ग 'svg' के साथ देखें और इसे लिंक किए गए फ़ाइल से इनलाइन SVG से बदलें। बड़े पैमाने पर लाभ यह है कि यह आपको एसवीजी के रंग को बदलने के लिए सीएसएस का उपयोग करने की अनुमति देता है, जैसे:

svg:hover path {
    fill: red;
}

मैंने जिस jQuery कोड को लिखा था, वह मूल चित्र आईडी और कक्षाओं में भी था। तो यह सीएसएस भी काम करता है:

#facebook-logo:hover path {
    fill: red;
}

या:

.social-link:hover path {
    fill: red;
}

आप इसका एक उदाहरण यहां देख सकते हैं: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

हमारे पास एक और अधिक जटिल संस्करण है जिसमें यहां कैशिंग शामिल है: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90


6
यह कभी-कभी सफारी (उदाहरण के लिए) में काम नहीं कर सकता है, यह सुनिश्चित करने के लिए कि लौटाए गए डेटा पढ़ने योग्य हैं, });$ .get का रीमेक}, 'xml');
जोआन

29
आप शायद चयनकर्ता को भी बदल सकते हैं img[src$=".svg"]और svgवर्ग की आवश्यकता को समाप्त कर सकते हैं ।
केसी चू

2
@LeonGaban मुझे नहीं लगता कि पृष्ठभूमि छवि के भरण को लक्षित करने का एक तरीका है। यह सुपर उपयोगी होगा यदि आप हालांकि!
बेकर

3
थोड़ा देर से, @LeonGaban, लेकिन इसे करने का एक बेहतर तरीका संभवत: भरने की विशेषता को पूरी तरह से हटा दिया जाएगा, और माता-पिता svg में एक भरने के लिए CSS फ़ाइल पर भरोसा करना होगा। $('#ico_company path').removeAttr('fill')। तब आप #ico_company { fill: #ccc }अपनी CSS फ़ाइल में कर सकते थे
bioball

2
@Soaku यह आसान होगा कि jQuery के सभी रास्तों को एक जैसा किया जाए क्योंकि फ़ॉन्ट रंग कुछ ऐसा कर रहा है जैसे `var color = $ img.closest ('p')। Css ('color'); $ svg.find ('पथ')। Attr ('fill', color); `लेकिन मुझे लगता है कि यह सीएसएस के लिए बेहतर काम है।
ड्रू बेकर

56

अंदाज

svg path {
    fill: #000;
}

लिपि

$(document).ready(function() {
    $('img[src$=".svg"]').each(function() {
        var $img = jQuery(this);
        var imgURL = $img.attr('src');
        var attributes = $img.prop("attributes");

        $.get(imgURL, function(data) {
            // Get the SVG tag, ignore the rest
            var $svg = jQuery(data).find('svg');

            // Remove any invalid XML tags
            $svg = $svg.removeAttr('xmlns:a');

            // Loop through IMG attributes and apply on SVG
            $.each(attributes, function() {
                $svg.attr(this.name, this.value);
            });

            // Replace IMG with SVG
            $img.replaceWith($svg);
        }, 'xml');
    });
});

1
यदि आपके पास चौड़ाई अटर नहीं है, तो यह केवल एक गलत संख्या के साथ बनाता है। width="170.667"मेरे मामले में
stallingOne

2
यह सही नहीं है क्योंकि यह पिछले img आयामों को खो देता है।
रिचीह

हैलो मान लें कि मेरे पास अलग-अलग रंग के साथ अलग-अलग svg हैं। इस विधि का उपयोग करते हुए, मेरे सभी svg रंग पहले svg के समान हो जाते हैं जो लूप किए जा रहे हैं। किसी भी विचार कैसे मैं इस के आसपास पैंतरेबाज़ी कर सकते हैं ताकि प्रत्येक रंग पहले की तरह ही रहे?
tnkh

1
ध्यान दें कि यदि आपका svg गैर- pathआकृतियों से भी बना है (जैसे rect) आपको उन्हें css में भी संभालना होगा
Mugen

33

अब आप अधिकांश आधुनिक ब्राउज़रों (एज सहित, लेकिन IE11 नहीं) में CSS filterसंपत्ति का उपयोग कर सकते हैं । यह एसवीजी छवियों के साथ-साथ अन्य तत्वों पर काम करता है। आप रंगों का उपयोग या संशोधित कर सकते हैं , हालांकि वे आपको अलग-अलग रंगों को स्वतंत्र रूप से संशोधित करने की अनुमति नहीं देते हैं। मैं एक आइकन के "अक्षम" संस्करण (जहां मूल संतृप्त रंग के साथ एक SVG चित्र है) दिखाने के लिए निम्न CSS वर्ग का उपयोग करता हूं:hue-rotateinvert

.disabled {
    opacity: 0.4;
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
}

यह इसे अधिकांश ब्राउज़रों में हल्का ग्रे बनाता है। IE में (और शायद ओपेरा मिनी, जिसे मैंने परीक्षण नहीं किया है) यह अस्पष्टता संपत्ति द्वारा फीका है, जो अभी भी बहुत अच्छा लग रहा है, हालांकि यह ग्रे नहीं है।

यहाँ ट्वोमोजी घंटी आइकन के लिए चार अलग-अलग सीएसएस वर्गों के साथ एक उदाहरण दिया गया है : मूल (पीला), उपरोक्त "विकलांग" वर्ग, hue-rotate(हरा), और invert(नीला)।


यदि आप आइकन फोंट बनाना नहीं चाहते हैं तो सिर्फ यह देखा जा सकता है कि इन्वर्ट अच्छा समाधान है। मैंने अपनी वेबसाइट के हेडर में css कलर प्रॉपर्टी के अनुसार आइकन बदलने के लिए इस jQuery कोड का इस्तेमाल किया (ध्यान दें कि मैं सफेद png आइकन का उपयोग कर रहा हूं):if ($('.w3-top img').css("color") == "rgb(0, 0, 0)") { $('.w3-top img').css("filter", "invert(100%)"); $('.w3-top img').css("-webkit-filter", "invert(100%)"); };
RedClover

महान दृष्टिकोण। लक्ष्य चिह्न रंग जोड़ने के लिए मेरे SVG xml को संपादित किया और फिर इसे ग्रे करने के लिए एक .icon- अक्षम वर्ग का उपयोग किया।
सुशीग्य

ध्यान दें कि पुराने
एक्सप्लोर

25

वैकल्पिक रूप से आप CSS का उपयोग कर सकते हैं mask, दिया गया ब्राउज़र समर्थन अच्छा नहीं है, लेकिन आप कमबैक का उपयोग कर सकते हैं

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}

14
एमडीएन निर्दिष्ट करता है कि -webkit-maskइसका उपयोग किसी भी उत्पादन वेबसाइट पर नहीं किया जाना चाहिए।
vaindil

1
vishal

शायद यह कहना प्रासंगिक है कि अब, चार साल बाद, यह समाधान सभी प्रमुख ब्राउज़रों में काम कर रहा है। बस यहाँ परीक्षण किया गया है और यह 100% ठीक है।
डैनियल लेमेस

23

यदि आप अपने पृष्ठ में फ़ाइलें (PHP शामिल या अपनी पसंद के सीएमएस के माध्यम से शामिल कर सकते हैं), आप एसवीजी कोड जोड़ सकते हैं और इसे अपने पृष्ठ में शामिल कर सकते हैं। यह SVG सोर्स को पेज में पेस्ट करने जैसा ही काम करता है, लेकिन पेज मार्कअप क्लीनर बनाता है।

लाभ यह है कि आप अपने एसवीजी के कुछ हिस्सों को होवर के लिए सीएसएस के माध्यम से लक्षित कर सकते हैं - कोई जावास्क्रिप्ट की आवश्यकता नहीं है।

http://codepen.io/chriscoyier/pen/evcBu

आपको बस एक सीएसएस नियम का उपयोग करना होगा:

#pathidorclass:hover { fill: #303 !important; }

ध्यान दें कि !importantभरने के रंग को ओवरराइड करने के लिए बिट आवश्यक है।


3
AngularJS का उपयोग करने वालों के लिए:<div ng-include="'svg.svg'"></div>
मिकेल

एक बहुत सुंदर समाधान नहीं है, हालांकि एक डेटाबेस में svg डेटा भंडारण। गलत नहीं है, लेकिन टेम्पलेट या अन्य संपत्ति का उपयोग करने के बजाय एक एपीआई या सीएमएस से xml / html / svg DOM डेटा को पंप करना गलत लगता है।
क्रिश्चोकी

इस योगदान के लिए धन्यवाद ... सबसे उन्नत साइटों आज घोंसला svg डेटा गतिविधि के सभी प्रकार के लिए अनुमति देने के लिए, इस जवाब के बिना मुझे लगता है कि नहीं होता!
webMan

इसके अतिरिक्त, यदि आपके एसवीजी में पारदर्शी क्षेत्र हैं, तो ये मँडरा नहीं होगा और आपको "आकर्षक हॉवर" का अनुभव हो सकता है। इसे ठीक करने के लिए, बस एक आवरण तत्व (एक <a>, यदि यह सुविधाजनक है) जोड़ें और फिर इसे CSS नियम में जोड़ें। #pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }या यहाँ तक कि एसवीजी पथ के मूल होवर को भी समाप्त कर दें क्योंकि आप इसे अभी भी रैपर तत्व के माध्यम से लक्षित कर रहे हैं।
नील मुनरो

18

@ ड्रे बेकर ने समस्या को हल करने के लिए एक शानदार समाधान दिया। कोड ठीक से काम करता है। हालाँकि, जो लोग AngularJs का उपयोग करते हैं, उन्हें jQuery पर बहुत अधिक निर्भरता मिल सकती है। नतीजतन, मुझे लगा कि @Drew बेकर के समाधान के बाद कोड को AngularJS उपयोगकर्ताओं के लिए पेस्ट करना एक अच्छा विचार है।

समान कोड का AngularJs तरीका

1. Html : आप HTML फ़ाइल में bellow टैग का उपयोग करें:

<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>

2. निर्देश : यह वह निर्देश होगा जिसे आपको टैग को पहचानने की आवश्यकता होगी:

'use strict';
angular.module('myApp')
  .directive('svgImage', ['$http', function($http) {
    return {
      restrict: 'E',
      link: function(scope, element) {
        var imgURL = element.attr('src');
        // if you want to use ng-include, then
        // instead of the above line write the bellow:
        // var imgURL = element.attr('ng-include');
        var request = $http.get(
          imgURL,
          {'Content-Type': 'application/xml'}
        );

        scope.manipulateImgNode = function(data, elem){
          var $svg = angular.element(data)[4];
          var imgClass = elem.attr('class');
          if(typeof(imgClass) !== 'undefined') {
            var classes = imgClass.split(' ');
            for(var i = 0; i < classes.length; ++i){
              $svg.classList.add(classes[i]);
            }
          }
          $svg.removeAttribute('xmlns:a');
          return $svg;
        };

        request.success(function(data){
          element.replaceWith(scope.manipulateImgNode(data, element));
        });
      }
    };
  }]);

3. सीएसएस :

.any-class-you-wish{
    border: 1px solid red;
    height: 300px;
    width:  120px
}

4. कर्म-चमेली के साथ इकाई-परीक्षण :

'use strict';

describe('Directive: svgImage', function() {

  var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data;

  beforeEach(function() {
    module('myApp');

    inject(function($injector) {
      $rootScope = $injector.get('$rootScope');
      $compile = $injector.get('$compile');
      $httpBackend = $injector.get('$httpBackend');
      apiUrl = $injector.get('apiUrl');
    });

    scope = $rootScope.$new();
    element = angular.element('<svg-image src="/icons/icon-man.svg" class="svg"></svg-image>');
    element = $compile(element)(scope);

    spyOn(scope, 'manipulateImgNode').andCallThrough();
    $httpBackend.whenGET(apiUrl + 'me').respond(200, {});

    data = '<?xml version="1.0" encoding="utf-8"?>' +
      '<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->' +
      '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' +
      '<!-- Obj -->' +
      '<!-- Obj -->' +
      '<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' +
      'width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">' +
        '<g>' +
          '<path fill="#F4A902" d=""/>' +
          '<path fill="#F4A902" d=""/>' +
        '</g>' +
      '</svg>';
    $httpBackend.expectGET('/icons/icon-man.svg').respond(200, data);
  });

  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  it('should call manipulateImgNode atleast once', function () {
    $httpBackend.flush();
    expect(scope.manipulateImgNode.callCount).toBe(1);
  });

  it('should return correct result', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    expect(result).toBeDefined();
  });

  it('should define classes', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    var classList = ["svg"];
    expect(result.classList[0]).toBe(classList[0]);
  });
});

1
आपका समाधान काम नहीं करता है, हो सकता है<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent

@guillaumevincent अगर आप इसका उपयोग करना चाहते हैं, ng-includeतो बस इस लाइन var imgURL = element.attr('src');को बदलकरvar imgURL = element.attr('ng-include');
Max

यह एक बहुत ही आसान समाधान है, लेकिन इसे अति प्रयोग में सावधानी बरतें क्योंकि यह प्रदर्शन को काफी कठिन बना सकता है - IE 5 साझाकरण आइकन का एक सेट जिसे एक लेख सूची या इस तरह से कुछ दोहराया जाता है।
स्केन्फ़ा

1
IE में आपके कोड में कोई समस्या है। आप if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }विभाजन के बजाय और लूप के लिए उपयोग कर सकते हैं ।
रॉबर्ट बोकोरी

2
अद्भुत कार्य! लेकिन निश्चित छवि के लिए आपको svg ( angular.element(data)[0];) के पहले तत्व को पकड़ना होगा और इसे IE उपयोग के साथ काम करना होगा if ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }। इसके अलावा आप cache: trueविकल्पों में जोड़ना चाह सकते हैं $http.getअन्यथा आपका पृष्ठ बहुत धीमा हो सकता है।
लीओ

16

मुझे लगता है कि आप इसे सीएसएस के साथ पूरा करना चाहते हैं, लेकिन सिर्फ एक अनुस्मारक के मामले में यह एक छोटी, सरल छवि है - आप इसे नोटपैड ++ में हमेशा खोल सकते हैं और पथ / जो भी भर सकते हैं उसे बदल सकते हैं:

<path style="fill:#010002;" d="M394.854,205.444c9.218-15.461,19.102-30.181,14.258-49.527
    ...
    C412.843,226.163,402.511,211.451,394.854,205.444z"/>

यह बदसूरत स्क्रिप्ट का एक टन बचा सकता है। क्षमा करें यदि यह ऑफ-बेस है, लेकिन कभी-कभी सरल समाधानों को अनदेखा किया जा सकता है।

... यहां तक ​​कि इस सवाल के लिए कोड के कुछ स्निपेट्स की तुलना में कई एसवीजी चित्रों की स्वैपिंग आकार में छोटी हो सकती है।


7

मैंने एंगुलरजेएस के साथ इस मुद्दे को हल करने के लिए एक निर्देश लिखा। यह यहाँ उपलब्ध है - ngReusableSvg

यह प्रदान किए जाने के बाद SVG तत्व को बदल देता है, और इसे एक divतत्व के अंदर रखता है , जिससे इसका CSS आसानी से परिवर्तनशील हो जाता है। यह विभिन्न आकारों / रंगों का उपयोग करके विभिन्न स्थानों में एक ही एसवीजी फ़ाइल का उपयोग करने में मदद करता है।

उपयोग सरल है:

<object oa-reusable-svg
        data="my_icon.svg"
        type="image/svg+xml"
        class="svg-class"
        height="30"  // given to prevent UI glitches at switch time
        width="30">
</object>

उसके बाद, आप आसानी से कर सकते हैं:

.svg-class svg {
    fill: red; // whichever color you want
}

नमस्ते, इस समाधान प्रदान करने के लिए धन्यवाद। मैंने इसे आज़माया है और इसकी पैदावार करता है: <div ng-click = "eventHandler ()" ng-class = "classEventHandler ()" style = "height: 30px; width: 30px; float: left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[ऑब्जेक्ट SVGSVGElement]] </ div> html में यह तब डालता है [[ऑब्जेक्ट SVGSVGElement]]। क्या आप जानते हैं कि समस्या क्या है? एक और सवाल, क्या इसका प्रदर्शन पर बड़ा प्रभाव पड़ता है या मैं इसे एक पेज पर कई svg पर उपयोग कर सकता हूं? और अंत में, यह अभी भी कोणीय 1.3 (बोवर) पर है।
छोड़ना

कोणीय के किस संस्करण का उपयोग कर रहे हैं? आपके मुद्दे का सामना नहीं किया है .. शायद यह एसवीजी के साथ कुछ है? प्रदर्शन-वार स्विच अपेक्षाकृत भारी है, मैंने इसे 10 की तरह खुद इस्तेमाल किया है और यह ठीक था। मुझे लगता है कि यह राशि / आकार पर निर्भर करता है, इसलिए इसके साथ परीक्षण और प्रयोग करें। बोवर के साथ क्या समस्या है? क्या आप एक अलग संस्करण का उपयोग कर रहे हैं और एक संघर्ष है?
ओमरी अहरों

5

TL / DR: यहां जाएं-> https://codepen.io/sosuke/pen/Pjoqqp

स्पष्टीकरण:

मैं मान रहा हूँ कि आपके पास html कुछ इस तरह है:

<img src="/img/source.svg" class="myClass">

निश्चित रूप से फिल्टर मार्ग, यानी। आपका svg काला या सफेद होने की संभावना है। आप इसे पाने के लिए एक फ़िल्टर लागू कर सकते हैं जो भी रंग आप चाहते हैं, उदाहरण के लिए, मेरे पास एक काला svg है जिसे मैं टकसाल हरा चाहता हूं। मैं पहले इसे सफेद होने के लिए उल्टा करता हूं (जो तकनीकी रूप से सभी आरजीबी रंग पूर्ण पर है) फिर ह्यू संतृप्ति आदि के साथ खेलते हैं।

filter: invert(86%) sepia(21%) saturate(761%) hue-rotate(92deg) brightness(99%) contrast(107%);

इससे भी बेहतर यह है कि आप अपने लिए फ़िल्टर में हेक्स को बदलने के लिए सिर्फ एक टूल का उपयोग कर सकते हैं: https://codepen.io/sosuke/pen/Pjoqqp


यह एक महान सीएसएस केवल समाधान है, साथ ही साथ फ़िल्टर करने के लिए हेक्स से कोडपेन बस कमाल है।
रिची गोंजालेज

4

यहां knockout.jsस्वीकृत उत्तर के आधार पर एक संस्करण दिया गया है:

महत्वपूर्ण: इसे वास्तव में प्रतिस्थापन के लिए jQuery की भी आवश्यकता होती है, लेकिन मैंने सोचा कि यह कुछ के लिए उपयोगी हो सकता है।

ko.bindingHandlers.svgConvert =
    {
        'init': function ()
        {
            return { 'controlsDescendantBindings': true };
        },

        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
        {
            var $img = $(element);
            var imgID = $img.attr('id');
            var imgClass = $img.attr('class');
            var imgURL = $img.attr('src');

            $.get(imgURL, function (data)
            {
                // Get the SVG tag, ignore the rest
                var $svg = $(data).find('svg');

                // Add replaced image's ID to the new SVG
                if (typeof imgID !== 'undefined')
                {
                    $svg = $svg.attr('id', imgID);
                }
                // Add replaced image's classes to the new SVG
                if (typeof imgClass !== 'undefined')
                {
                    $svg = $svg.attr('class', imgClass + ' replaced-svg');
                }

                // Remove any invalid XML tags as per http://validator.w3.org
                $svg = $svg.removeAttr('xmlns:a');

                // Replace image with new SVG
                $img.replaceWith($svg);

            }, 'xml');

        }
    };

तो बस data-bind="svgConvert: true"अपने img टैग पर लागू होते हैं ।

यह समाधान पूरी तरह से imgएसवीजी के साथ टैग को बदल देता है और किसी भी अतिरिक्त बाइंडिंग का सम्मान नहीं किया जाएगा।


2
यह भी खूब रही! यदि आप इसे अगले स्तर पर ले जाना चाहते हैं, तो हमारे पास एक अद्यतन संस्करण है जिसमें कैशिंग शामिल है, इसलिए एक ही एसवीजी दो बार अनुरोध नहीं किया गया है। github.com/funkhaus/style-guide/blob/master/template/js/…
ड्रू बेकर

मैं इसके बारे में थोड़ा चिंतित था लेकिन खुद को देखने का समय नहीं था। बस कुछ जल्दी की जरूरत है
सिमोन_विेवर

1
@DrewBaker वास्तव में मुझे अधिक चिंता थी कि img टैग फ़ाइल का अनुरोध करेगा और फिर getइसे फिर से अनुरोध करेगा। मैंने टैग पर srcएक data-srcविशेषता को बदलने पर विचार किया img, लेकिन यह निष्कर्ष निकाला कि आधुनिक ब्राउज़र संभवतः फ़ाइल को कैश करने के लिए पर्याप्त स्मार्ट हैं
सिमोन_वेवर

3

यहाँ कोई फ़्रेम कोड नहीं है, केवल शुद्ध js:

document.querySelectorAll('img.svg').forEach(function(element) {
            var imgID = element.getAttribute('id')
            var imgClass = element.getAttribute('class')
            var imgURL = element.getAttribute('src')

            xhr = new XMLHttpRequest()
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    var svg = xhr.responseXML.getElementsByTagName('svg')[0];

                    if(imgID != null) {
                         svg.setAttribute('id', imgID);
                    }

                    if(imgClass != null) {
                         svg.setAttribute('class', imgClass + ' replaced-svg');
                    }

                    svg.removeAttribute('xmlns:a')

                    if(!svg.hasAttribute('viewBox') && svg.hasAttribute('height') && svg.hasAttribute('width')) {
                        svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
                    }
                    element.parentElement.replaceChild(svg, element)
                }
            }
            xhr.open('GET', imgURL, true)
            xhr.send(null)
        })

3

SVGInject नामक एक ओपन सोर्स लाइब्रेरी है onloadजो इंजेक्शन को ट्रिगर करने के लिए विशेषता का उपयोग करती है । आप GitHub प्रोजेक्ट को https://github.com/iconfu/svg-inject पर पा सकते हैं

यहाँ SVGInject का उपयोग करके एक न्यूनतम उदाहरण दिया गया है:

<html>
  <head>
    <script src="svg-inject.min.js"></script>
  </head>
  <body>
    <img src="image.svg" onload="SVGInject(this)" />
  </body>
</html>

छवि लोड होने के बाद onload="SVGInject(this)इंजेक्शन को ट्रिगर करेगा और <img>तत्व को srcविशेषता में प्रदान की गई एसवीजी फ़ाइल की सामग्री से बदल दिया जाएगा ।

यह एसवीजी इंजेक्शन के साथ कई मुद्दों को हल करता है:

  1. इंजेक्शन खत्म होने तक एसवीजी छिपाए जा सकते हैं। यह महत्वपूर्ण है अगर एक शैली पहले से ही लोड समय के दौरान लागू की जाती है, जो अन्यथा एक संक्षिप्त "अस्थिर सामग्री फ्लैश" का कारण बनेगी।

  2. <img>तत्वों स्वचालित रूप से themselved इंजेक्षन। यदि आप एसवीजी को गतिशील रूप से जोड़ते हैं, तो आपको इंजेक्शन फ़ंक्शन को फिर से कॉल करने के बारे में चिंता करने की ज़रूरत नहीं है।

  3. यदि एसवीजी को एक से अधिक बार इंजेक्ट किया जाता है, तो दस्तावेज़ में एक ही आईडी होने से बचने के लिए एसवीजी में प्रत्येक आईडी में एक यादृच्छिक स्ट्रिंग जोड़ा जाता है।

SVGInject सादा जावास्क्रिप्ट है और सभी ब्राउज़रों के साथ काम करता है जो SVG का समर्थन करते हैं।

अस्वीकरण: मैं SVGInject का सह-लेखक हूं


1
मुझे यह समाधान सबसे अच्छा लगता है, क्योंकि यह गतिशील रूप से जोड़े गए एसवीजी की देखभाल करता है।
विक्कीबी

2

यदि हमारे पास ऐसी svg छवियों की अधिक संख्या है, तो हम फ़ॉन्ट-फाइलों की मदद भी ले सकते हैं। Https://glyphter.com/
जैसी साइटें हमें हमारे svgs से एक फ़ॉन्ट फ़ाइल दिला सकती हैं।


उदाहरण के लिए

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}

5
मैं व्यक्तिगत रूप से "छवियों को एक फ़ॉन्ट" तकनीक के रूप में नफरत करता हूं। यह छवियों को जोड़ना / संपादित करना कठिन बनाता है, बहुत अधिक निरर्थक मार्कअप जोड़ता है। फॉन्ट का फॉन्ट होना चाहिए, चित्र चित्र आदि होने चाहिए
ड्रू बेकर

माना। आपको वर्णों को दी गई छवियों को याद रखने / देखने की भी आवश्यकता है। लेकिन विशिष्ट मामले के लिए जहां छवियों का उपयोग आइकन / बटन / गोलियों के रूप में किया जाता है, मीडिया की तुलना में पाठ के रूप में अधिक कार्य करते हैं, फ़ॉन्ट-फाइलें भी एक विकल्प हो सकती हैं
अभिषेक बोरर

यहां तक ​​कि github आइकन github.com/blog/2112-delivering-octicons-with-svg
gagarine

2

आप इसके लिए डेटा-इमेज का उपयोग कर सकते हैं। डेटा-इमेज (डेटा-यूआरआई) का उपयोग करके आप इनलाइन की तरह एसवीजी का उपयोग कर सकते हैं।

यहाँ शुद्ध CSS और SVG का उपयोग करके रोलओवर प्रभाव है।

मुझे पता है कि यह गड़बड़ है लेकिन आप इस तरह से कर सकते हैं।

 .action-btn {
    background-size: 20px 20px;
    background-position: center center;
    background-repeat: no-repeat;
    border-width: 1px;
    border-style: solid;
    border-radius: 30px;
    height: 40px;
    width: 60px;
    display: inline-block;
 }

.delete {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#FB404B' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
     border-color:#FB404B;
     
 }
 
 .delete:hover {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#fff' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");        
     background-color: #FB404B;
    }
<a class="action-btn delete">&nbsp;</a>

आप अपने svg को डेटा url में बदल सकते हैं

  1. https://codepen.io/elliz/full/ygvgay
  2. https://websemantics.uk/tools/svg-to-background-image-conversion/

यह जटिल एसवीजी के लिए काम नहीं करेगा जहां आप केवल कुछ रास्ते / बहुभुज / आदि चाहते हैं।
ड्रू बेकर

नहीं आप कर सकते हैं..लेकिन यह बहुत जटिल है
patelarpan

यह सिर्फ आइकन के लिए समाधान करता है
patelarpan

अगर कुछ आइकन के साथ काम करते हैं। फिर बहुत अच्छा हुआ। बूटस्ट्रैप 4 भी इस तकनीकी का उपयोग करता है
patelarpan

2

चूंकि एसवीजी मूल रूप से कोड है, आपको केवल सामग्री की आवश्यकता है। मैंने सामग्री प्राप्त करने के लिए PHP का उपयोग किया, लेकिन आप जो चाहें उपयोग कर सकते हैं।

<?php
$content    = file_get_contents($pathToSVG);
?>

फिर, मैंने एक div कंटेनर के अंदर "जैसा है" सामग्री मुद्रित की है

<div class="fill-class"><?php echo $content;?></div>

सीएसएस पर कंटेनर के एसवीजी चिल्ड्स के लिए नियम को निर्धारित करना

.fill-class > svg { 
    fill: orange;
}

मुझे यह सामग्री चिह्न SVG के साथ मिली:

  1. मोज़िला फ़ायरफ़ॉक्स 59.0.2 (64-बिट) लिनक्स

यहां छवि विवरण दर्ज करें

  1. Google Chrome66.0.3359.181 (बिल्डिकल) (64 बिट्स) लिनक्स

यहां छवि विवरण दर्ज करें

  1. ओपेरा 53.0.2907.37 लिनक्स

यहां छवि विवरण दर्ज करें


1

चयनित समाधान ठीक है यदि आप चाहते हैं कि आपके डोमेन में सभी svg तत्वों को संसाधित करने के लिए jQuery और आपका DOM उचित आकार का हो। लेकिन अगर आपका DOM बड़ा है और आप अपने DOM के कुछ हिस्सों को गतिशील रूप से लोड करने का निर्णय लेते हैं, तो यह वास्तव में svg तत्वों को अपडेट करने के लिए पूरे DOM को rescan करने के लिए कोई मतलब नहीं है। इसके बजाय, ऐसा करने के लिए jQuery प्लगइन का उपयोग करें:

/**
 * A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
 *
 * The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
 *
 * The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
 * underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
 * any styles in a style class instead.
 */
(function ($) {
    $.fn.svgLoader = function () {
        var src = $(this).attr("src");
        var width = this.attr("width");
        var height = this.attr("height");
        var cls = this.attr("class");
        var ctx = $(this);

        // Get the svg file and replace the <svg> element.
        $.ajax({
            url: src,
            cache: false
        }).done(function (html) {
            let svg = $(html);
            svg.attr("width", width);
            svg.attr("height", height);
            svg.attr("class", cls);
            var newHtml = $('<a></a>').append(svg.clone()).html();
            ctx.replaceWith(newHtml);
        });

        return this;
    };

}(jQuery));

अपने HTML में, निम्नानुसार एक svg तत्व निर्दिष्ट करें:

<svg src="images/someSvgFile.svg" height="45" width="45" class="mySVGClass"/>

और प्लगइन लागू करें:

$(".mySVGClass").svgLoader();

हां, मेरे द्वारा दिए गए कोड का उपयोग करने के लिए निश्चित रूप से अधिक कुशल तरीके हैं। यहां बताया गया है कि हम वास्तव में इसका उपयोग उत्पादन साइटों पर कैसे करते हैं। यह SVGs को कैश करता है! github.com/funkhaus/style-guide/blob/master/template/js/…
आकर्षित बेकर

1

के लिए: hover घटना एनिमेशन हम svg फ़ाइल के अंदर शैलियों को छोड़ सकते हैं, जैसे

<svg xmlns="http://www.w3.org/2000/svg">
<defs>
  <style>
  rect {
    fill:rgb(165,225,75);
    stroke:none;
    transition: 550ms ease-in-out;
    transform-origin:125px 125px;
  }
  rect:hover {
    fill:rgb(75,165,225);
    transform:rotate(360deg);
  }
  </style>
</defs>
  <rect x='50' y='50' width='150' height='150'/>
</svg>

svgshare पर यह जाँच करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.