Изменить ход 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;
});
}
Итак, давайте пройдемся очень быстро:
- Я определил цвет обводки для начала (_currStroke = 'ffa500')
- Я кодирую SVG и установить его в качестве фона моей навигации
- Обратите внимание на путь svg: у него есть идентификатор (# 'outline_path') и стиль:
style="stroke:'+_currStroke+'; transition: stroke .4s ease; opacity: 0.5"
- Сохранить текущий цвет обводки в переменной (currentColor)
- вызывать changeStrokeColor-функцию каждый
changeTimeInMS
- секунды - сохранить возвращаемое значение changeStrokeColor в переменной (lastIndex)
- changeStrokeColors ожидает две переменные: текущий цвет обводки и последний индекс (возможен ли первый вызов changeStrokeColors? lastIndex еще не объявлен, но я не могу установить его в 0, например, потому что тогда он будет сбрасываться каждые x секунд)
- Перебирать массив цветов; если currentColor равен индексу, которым мы являемся в данный момент, пропустить его (
return true
) и продолжить с: - поиск пути с идентификатором
outline_path
и измените штрих на элемент, который мы сейчас находимся в нашей итерации - Также измените цвет границы навигации на этот цвет
- увеличить lastIndex и вернуть его
Я могу изменить цвет с изменением var _currStroke, но "сделай это каждые x секунд" вообще не работает. Обратите внимание, что я новичок в JS (и SVG). Любая помощь приветствуется.
Я сделал CodePen для иллюстрации: CodePen
1 ответ
Так много проблем в вашем коде,
Я постараюсь охватить их всех:
Вы используете элемент HTML
<nav>
но в вашем коде вы пытаетесь указать какой-то идентификатор:$("#nav").css(
Правильный селектор, который вы хотите, на самом деле тот, который вы уже использовали в своем коде, и это$("nav")
Вы конвертируете свой SVG-элемент в base64 data-image.
После того, как он преобразован в изображение, он больше не является живым объектом **, которым вы можете манипулировать, поэтому, в основном, вам нужно будет перестроить новое изображение с другими цветами, прежде чем использовать его. В противном случае вы можете изучить, как использовать SVG<pattern>
,Вы устанавливаете недопустимые цвета в вашем массиве
'32cd32'
не HEX цвет, в то время как'#32cd32'
является.$("outline_path")
это не селектор идентификаторов, см. • 1, но в любом случае уже слишком поздно нацеливаться на него, потому что ваш SVG теперь является изображением данных base64, см. • 2.Там нет необходимости помнить
lastIndex
раскрасить и повторить все ваши цвета Массив внутри$.each
Просто используйте указатель счетчика массива, увеличьте этот счетчик и используйте оператор напоминания% от общего числа цветов для зацикливания увеличенного счетчика:++counter%totColors
.attr('style', "stroke:'+this+'")
неверная строка + конкатенация переменных. Должно быть как:.attr('style', "stroke:'"+ this +"'")
где все внутри двойников это строка, а снаружи+
объединенные переменные.Вам нужно будет предварительно создать все ваши изображения, чтобы предотвратить пропуски (создаваемые изображения), как только интервал начнет тикать.
Вы не сможете установить
transition: stroke .4s ease;
к изображению. Сожалею. Возможно, вы захотите изучить некоторые другие приемы затухания изображения bg (задействовано 2 элемента). пример1 пример2 пример3Не создавайте заново ваши переменные внутри интервала. Вместо этого сделайте их глобальными.
Создайте функцию, которая будет возвращать новое изображение.
Вот моя попытка перестроить все это, следуя вашей идее и исходному коду:
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);
});