@Drew Baker a donné une excellente solution pour résoudre le problème. Le code fonctionne correctement. Cependant, ceux qui utilisent AngularJs peuvent trouver beaucoup de dépendance à jQuery. Par conséquent, j'ai pensé que c'était une bonne idée de coller pour les utilisateurs d'AngularJS, un code suivant la solution de @Drew Baker.
Version AngularJs du même code
1. Html Utilisez la balise ci-dessous dans votre fichier html :
<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>
2. Directive : ce sera la directive dont vous aurez besoin pour reconnaître la balise :
'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. CSS :
.any-class-you-wish{
border: 1px solid red;
height: 300px;
width: 120px
}
4. Test unitaire avec karma-jasmine :
'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]);
});
});
2 votes
Malheureusement, la balise img ne fonctionne pas avec les fichiers svg dans IE, il faut donc en tenir compte. IE reconnaît les balises embed. Quoi qu'il en soit, bon travail !
3 votes
Pour les svg, vous devez utiliser la propriété css "fill". Pour les images, il est approprié d'utiliser "filter". En fait, "Filter" fonctionne pour les deux, mais il est inutile de faire tout ce travail pour un graphique vectoriel.