Change SVG stroke on path using jQuery

I have set the SVG image as the background of the div. Now I want to change the progress of a specific path using jQuery every x seconds. I saw an example ( click me ) where this is mostly done.

This is my jQuery:

$(document).ready(function(){

  var _currStroke = 'ffa500';

  var svg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"  x="0px" y="0px" width="60px" height="60px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"> <path d="M69.527,2H29.971L2,29.971v39.558L29.971,97.5h39.558L97.5,69.527V29.972L69.527,2z M95.625,68.898L68.898,95.625H31.101  L4.375,68.898V31.516v-0.414L31.102,4.375h37.796l26.728,26.727L95.625,68.898L95.625,68.898z"/> <path d="M68.07,6.375H31.93L6.375,31.93v36.142L31.93,93.626h36.142L93.625,68.07V31.93L68.07,6.375z" id="outline_path" style="stroke:'+_currStroke+'; transition: stroke .4s ease; opacity: 0.5" /> </svg>';

  var encoded = window.btoa(svg);
  $("nav").css("background", "url(data:image/svg+xml;base64,"+encoded+")");

  /* change stroke color every x seconds (atm: 3) */
  var changingTimeInMS = 3000;
  var currentColor = $("outline_path").attr('stroke');
  setInterval(function() {    

    var lastIndex = changeStrokeColor(currentColor, lastIndex);

  }, changingTimeInMS);

});

function changeStrokeColor(currentColor, lastIndex) {

    var colors = ['32cd32',  /* limegreen */
                '00ffff',  /* cyan */
                'ffa500',  /* orange */
                'ffffff']; /* white */

    $.each(colors, function(lastIndex) {
      if(colors[lastIndex] == currentColor) {
          return true;
      }
      $("#outline_path").attr('style', "stroke:'+this+'");
      $("#nav").css('border-color', this);

      lastIndex++;
      return lastIndex;
});

}

      

So let's make it go very quickly:

  • I defined the stroke color to start with (_currStroke = 'ffa500')
  • I am coding svg and setting it as the background of my nav
  • Note the svg path: it has an id (# 'outline_path) and a style: style="stroke:'+_currStroke+'; transition: stroke .4s ease; opacity: 0.5"

  • Store the current color of the stroke in a variable (currentColor)
  • call the changeStrokeColor function every changeTimeInMS

    - seconds
  • store return value of changeStrokeColor in variable (lastIndex)
  • changeStrokeColors expects two variables: the current stroke color and the last index (maybe the first call to changeStrokeColors? lastIndex hasn't been declared yet, but I can't set it to 0, for example, because then it will be reset every x seconds)
  • Iterating through a set of colors; if currentColor is equal to the index we are currently finding, pass it ( return true

    ) and continue:
  • find the path with id outline_path

    and change the stroke to the element we are currently finding in our iteration
  • Also change the color of the navigation frame to this color
  • Increment lastIndex and return it

I can change color with var _currStroke but the "do-it-every-x-seconds" thing doesn't work at all. Please note that I am new to JS (and SVG). Any help is appreciated.

I made a CodePen to illustrate: CodePen

+3


source to share


1 answer


Working demo in real time

There are so many problems in your code,
I will try to cover them:

  • You are using an HTML element <nav>

    , but in the code you are trying to target some ID : The $("#nav").css(

    correct selector you want is actually the one you have already used in your code and it is $("nav")

  • converting your SVG element to base64 image data .
    After it is converted to an image, it is no longer a living object ** that you can manipulate, so basically you will need to rebuild the new image with different colors before using it. Otherwise, you can learn how to use SVG<pattern>

    .

  • You are setting invalid colors in your array is '32cd32'

    not a HEX color , but '#32cd32'

    -

  • $("outline_path")

    is not an identifier selector see *; 1 but anyway it's too late to hover it over so that your SVG becomes the c & bull; base64 data image . 2

  • No need to remember the color lastIndex

    and iterate over your Array colors inside again $.each

    , just use the array counter pointer, increment that counter and use the Reminder Operator% of Total Colors to increment the counter cyclically:++counter%totColors

  • .attr('style', "stroke:'+this+'")

    - invalid string + var concatenation. It should be like:, .attr('style', "stroke:'"+ this +"'")

    where everything inside the duplicates is a string, and everything outside is +

    concatenated variables.

  • You will need to pre-create all of your images to prevent empty spaces (generated image) after the spacing starts ticking.

  • You will not be able to set transition: stroke .4s ease;

    on an image. I'm sorry. You might want to learn some other tricks in bg (2 elements) fading. example1 example2 example3

  • Don't re-create variables within the interval. Make them Global instead.

  • Create a function that will return a new image.




Here's my attempt to rebuild the whole thing following your idea and source code:

var $nav = $("nav"), // Cache your selectors
  colors = [
  '#00ffff',  // cyan
  '#32cd32',  // limegreen
  '#ffa500',  // orange
  '#ffffff',  // white
  'red'
  ], 
  totColors = colors.length, // How many colors?
  counter = 0;               // Colors Array loop counter

function newSvg(co){
  var svg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"  x="0px" y="0px" width="60px" height="60px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"> <path d="M69.527,2H29.971L2,29.971v39.558L29.971,97.5h39.558L97.5,69.527V29.972L69.527,2z M95.625,68.898L68.898,95.625H31.101  L4.375,68.898V31.516v-0.414L31.102,4.375h37.796l26.728,26.727L95.625,68.898L95.625,68.898z"/> <path d="M68.07,6.375H31.93L6.375,31.93v36.142L31.93,93.626h36.142L93.625,68.07V31.93L68.07,6.375z" id="outline_path" style="stroke:'+ co +'; opacity: 0.5" /> </svg>';
  return "data:image/svg+xml;base64,"+ window.btoa(svg);
}

function changeStrokeColor() {
  var co = colors[++counter%totColors]; // Increase and Loop colors
  $nav.css({
    borderColor: co,
    background : "url("+ newSvg(co) +")"
  });
}  

for(var i=0; i<totColors; i++){ // Preload all backgrounds
  var img = new Image();
  img.src = newSvg(colors[i]);
}

$(function(){ // DOM ready
  $nav.css("background", "url("+ newSvg( colors[counter] ) +")" );
  setInterval(changeStrokeColor, 1000);
});

      

+2


source







All Articles