img color change jquery css svg

change - ¿Cómo cambiar el color de la imagen SVG usando CSS(reemplazo de imagen jQuery SVG)?



change color svg image css (17)

@Drew Baker dio una gran solución para resolver el problema. El código funciona correctamente. Sin embargo, aquellos que usan AngularJs pueden encontrar mucha dependencia en jQuery. En consecuencia, pensé que es una buena idea pegar para usuarios de AngularJS, un código que sigue a la solución de @Drew Baker.

AngularJs forma del mismo código.

1. Html : use la etiqueta de abajo en su archivo html:

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

2. Directiva : esta será la directiva que deberá reconocer la etiqueta:

''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. Prueba de unidad con karma-jazmín :

''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]); }); });

Este es un auto de preguntas y respuestas de una pieza de código útil que se me ocurrió.

Actualmente, no hay una manera fácil de incrustar una imagen SVG y luego tener acceso a los elementos SVG a través de CSS. Existen varios métodos para usar marcos JS SVG, pero son demasiado complicados si lo único que está haciendo es crear un icono simple con un estado de rollover.

Así que aquí es lo que se me ocurrió, que creo que es la forma más fácil de usar archivos SVG en un sitio web. Toma su concepto de los primeros métodos de reemplazo de texto a imagen, pero por lo que sé, nunca se ha hecho para los SVG.

Esta es la pregunta:

¿Cómo puedo incrustar un SVG y cambiar su color en CSS sin usar un marco JS-SVG?


Ahora puede utilizar la propiedad de filter CSS en la mayoría de los navegadores modernos (incluido Edge, pero no IE11). Funciona en imágenes SVG, así como otros elementos. Puede usar el tono-rotar o invertir para modificar los colores, aunque no le permiten modificar diferentes colores de forma independiente. Utilizo la siguiente clase de CSS para mostrar una versión "deshabilitada" de un icono (donde el original es una imagen SVG con color saturado):

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

Esto hace que sea gris claro en la mayoría de los navegadores. En IE (y probablemente en Opera Mini, que no he probado), la propiedad de opacidad se desvanece notablemente, lo que todavía se ve bastante bien, aunque no es gris.

Aquí hay un ejemplo con cuatro clases CSS diferentes para el Twemoji campana Twemoji : original (amarillo), la clase "deshabilitada" anterior, hue-rotate (verde) e invert (azul).

.twa-bell { background-image: url("https://twemoji.maxcdn.com/svg/1f514.svg"); display: inline-block; background-repeat: no-repeat; background-position: center center; height: 3em; width: 3em; margin: 0 0.15em 0 0.3em; vertical-align: -0.3em; background-size: 3em 3em; } .grey-out { opacity: 0.4; filter: grayscale(100%); -webkit-filter: grayscale(100%); } .hue-rotate { filter: hue-rotate(90deg); -webkit-filter: hue-rotate(90deg); } .invert { filter: invert(100%); -webkit-filter: invert(100%); }

<!DOCTYPE html> <html> <head> </head> <body> <span class="twa-bell"></span> <span class="twa-bell grey-out"></span> <span class="twa-bell hue-rotate"></span> <span class="twa-bell invert"></span> </body> </html>


Alternativamente, podría usar la mask CSS, el soporte para el navegador no es bueno, pero podría usar un respaldo.

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


Aquí hay un código sin marco, solo js puro:

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) })


Aquí hay una versión para knockout.js basada en la respuesta aceptada:

Importante: en realidad requiere jQuery también para el reemplazo, pero pensé que podría ser útil para algunos.

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''); } };

Luego simplemente aplica data-bind="svgConvert: true" a tu etiqueta img.

Esta solución reemplaza completamente la etiqueta img con un SVG y no se respetarán los enlaces adicionales.


Como SVG es básicamente un código, solo necesitas contenidos. Usé PHP para obtener contenido, pero puedes usar lo que quieras.

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

Luego, imprimí el contenido "como está" dentro de un contenedor div

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

Para establecer finalmente la regla para los hijos SVG del contenedor en CSS

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

Obtuve estos resultados con un icono de material SVG:

  1. Mozilla Firefox 59.0.2 (64 bits) Linux

  1. Google Chrome66.0.3359.181 (Build oficial) (64 bits) Linux

  1. Opera 53.0.2907.37 Linux


En primer lugar, use una etiqueta IMG en su HTML para incrustar un gráfico SVG. Utilicé Adobe Illustrator para hacer el gráfico.

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

Esto es así como incrustar una imagen normal. Tenga en cuenta que debe configurar la IMG para que tenga una clase de svg. La clase de ''enlace social'' es solo por ejemplo, bien. La identificación no es necesaria, pero es útil.

Luego use este código jQuery (en un archivo separado o en línea en el 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''); });

Lo que hace el código anterior es buscar todos los IMG con la clase ''svg'' y reemplazarlos con el SVG en línea del archivo vinculado. La gran ventaja es que le permite usar CSS para cambiar el color de la SVG ahora, así:

svg:hover path { fill: red; }

El código jQuery que escribí también pasa por el ID de las imágenes originales y las clases. Así que este CSS también funciona:

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

O:

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

Puede ver un ejemplo de esto trabajando aquí: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

Tenemos una versión más complicada que incluye caché aquí: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90


Escribí una directiva para resolver este problema con AngularJS. Está disponible aquí - ngReusableSvg .

Reemplaza el elemento SVG una vez que se ha procesado, y lo coloca dentro de un elemento div , haciendo que su CSS sea fácilmente cambiable. Esto ayuda a usar el mismo archivo SVG en diferentes lugares usando diferentes tamaños / colores.

El uso es simple:

<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>

Después de eso, puedes tener fácilmente:

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


Estilo

svg path { fill: #000; }

Guión

$(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''); }); });


Hay una biblioteca de código abierto llamada SVGInject que utiliza el atributo onload para desencadenar la inyección. Puede encontrar el proyecto GitHub en https://github.com/iconfu/svg-inject

Aquí hay un ejemplo mínimo usando SVGInject:

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

Después de cargar la imagen, el onload="SVGInject(this) activará la inyección y el elemento <img> será reemplazado por el contenido del archivo SVG proporcionado en el atributo src .

Resuelve varios problemas con la inyección de SVG:

  1. Los SVG pueden ocultarse hasta que la inyección haya terminado. Esto es importante si ya se aplica un estilo durante el tiempo de carga, lo que de lo contrario causaría un breve "flash de contenido sin estilo".

  2. Los elementos <img> inyectan automáticamente. Si agrega SVG de forma dinámica, no tiene que preocuparse por volver a llamar a la función de inyección.

  3. Se agrega una cadena aleatoria a cada ID en el SVG para evitar tener la misma ID varias veces en el documento si se inyecta un SVG más de una vez.

SVGInject es un Javascript simple y funciona con todos los navegadores que admiten SVG.

Descargo de responsabilidad: soy el coautor de SVGInject


La solución seleccionada está bien si desea que jQuery procese todos los elementos svg en su DOM y su DOM sea de un tamaño razonable. Pero si su DOM es grande y decide cargar partes de su DOM dinámicamente, realmente no tiene sentido tener que volver a escanear todo el DOM solo para actualizar elementos svg. En su lugar, usa un complemento de jQuery para hacer esto:

/** * 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));

En su html, especifique un elemento svg de la siguiente manera:

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

Y aplique el plugin:

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


Me doy cuenta de que quieres lograr esto con CSS, pero solo un recordatorio en caso de que sea una imagen pequeña y simple: siempre puedes abrirla en Notepad ++ y cambiar la ruta / el relleno de cualquier elemento:

<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"/>

Podría ahorrar un montón de guiones feos. Lo siento si está fuera de la base, pero a veces las soluciones simples pueden pasarse por alto.

... incluso el intercambio de múltiples imágenes svg puede ser más pequeño que algunos de los fragmentos de código para esta pregunta.


Puedes usar data-image para eso. utilizando data-image (data-URI) puede acceder a SVG como en línea.

Aquí está el efecto de rollover usando CSS puro y SVG.

Lo sé desordenado pero puedes hacerlo de esta manera.

.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>

Puede convertir su svg a la url de datos aquí

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

Si puede incluir archivos (PHP incluir o incluir a través de su CMS de elección) en su página, puede agregar el código SVG e incluirlo en su página. Esto funciona igual que pegar la fuente SVG en la página, pero hace que el marcado de la página sea más limpio.

El beneficio es que puede apuntar partes de su SVG a través de CSS para el desplazamiento, no se requiere javascript.

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

Solo tienes que usar una regla CSS como esta:

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

Tenga en cuenta que el bit !important es necesario para anular el color de relleno.


Si se trata de un cambio estático, abra el archivo SVG en Adobe Illustrator (o cualquier editor SVG adecuado), cambie el color y guárdelo.


Si tenemos un mayor número de imágenes svg, también podemos tomar la ayuda de los archivos de fuentes.
Sitios como https://glyphter.com/ pueden obtener un archivo de fuente de nuestros svgs.

P.ej

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


para: animaciones de eventos flotantes podemos dejar los estilos dentro del archivo svg, como un

<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>

mira esto en svgshare