Изменить ход SVG на пути с помощью jQuery

Я установил свое изображение SVG в качестве фона div. Теперь я хочу менять ход конкретного пути с помощью jQuery каждые x секунд. Я видел пример ( нажмите меня), где это в основном сделано.

Это мой 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;
});

}

Итак, давайте пройдемся очень быстро:

  1. Я определил цвет обводки для начала (_currStroke = 'ffa500')
  2. Я кодирую SVG и установить его в качестве фона моей навигации
  3. Обратите внимание на путь svg: у него есть идентификатор (# 'outline_path') и стиль: style="stroke:'+_currStroke+'; transition: stroke .4s ease; opacity: 0.5"
  4. Сохранить текущий цвет обводки в переменной (currentColor)
  5. вызывать changeStrokeColor-функцию каждый changeTimeInMS - секунды
  6. сохранить возвращаемое значение changeStrokeColor в переменной (lastIndex)
  7. changeStrokeColors ожидает две переменные: текущий цвет обводки и последний индекс (возможен ли первый вызов changeStrokeColors? lastIndex еще не объявлен, но я не могу установить его в 0, например, потому что тогда он будет сбрасываться каждые x секунд)
  8. Перебирать массив цветов; если currentColor равен индексу, которым мы являемся в данный момент, пропустить его (return true) и продолжить с:
  9. поиск пути с идентификатором outline_path и измените штрих на элемент, который мы сейчас находимся в нашей итерации
  10. Также измените цвет границы навигации на этот цвет
  11. увеличить lastIndex и вернуть его

Я могу изменить цвет с изменением var _currStroke, но "сделай это каждые x секунд" вообще не работает. Обратите внимание, что я новичок в JS (и SVG). Любая помощь приветствуется.

Я сделал CodePen для иллюстрации: CodePen

1 ответ

Решение

Рабочая живая демка

Так много проблем в вашем коде,
Я постараюсь охватить их всех:

  1. Вы используете элемент HTML <nav> но в вашем коде вы пытаетесь указать какой-то идентификатор: $("#nav").css( Правильный селектор, который вы хотите, на самом деле тот, который вы уже использовали в своем коде, и это $("nav")

  2. Вы конвертируете свой SVG-элемент в base64 data-image.
    После того, как он преобразован в изображение, он больше не является живым объектом **, которым вы можете манипулировать, поэтому, в основном, вам нужно будет перестроить новое изображение с другими цветами, прежде чем использовать его. В противном случае вы можете изучить, как использовать SVG <pattern>,

  3. Вы устанавливаете недопустимые цвета в вашем массиве '32cd32' не HEX цвет, в то время как '#32cd32' является.

  4. $("outline_path") это не селектор идентификаторов, см. • 1, но в любом случае уже слишком поздно нацеливаться на него, потому что ваш SVG теперь является изображением данных base64, см. • 2.

  5. Там нет необходимости помнить lastIndex раскрасить и повторить все ваши цвета Массив внутри $.each Просто используйте указатель счетчика массива, увеличьте этот счетчик и используйте оператор напоминания% от общего числа цветов для зацикливания увеличенного счетчика: ++counter%totColors

  6. .attr('style', "stroke:'+this+'") неверная строка + конкатенация переменных. Должно быть как: .attr('style', "stroke:'"+ this +"'") где все внутри двойников это строка, а снаружи + объединенные переменные.

  7. Вам нужно будет предварительно создать все ваши изображения, чтобы предотвратить пропуски (создаваемые изображения), как только интервал начнет тикать.

  8. Вы не сможете установить transition: stroke .4s ease; к изображению. Сожалею. Возможно, вы захотите изучить некоторые другие приемы затухания изображения bg (задействовано 2 элемента). пример1 пример2 пример3

  9. Не создавайте заново ваши переменные внутри интервала. Вместо этого сделайте их глобальными.

  10. Создайте функцию, которая будет возвращать новое изображение.


Вот моя попытка перестроить все это, следуя вашей идее и исходному коду:

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);
});
Другие вопросы по тегам