Функция повторного использования TweenMax для всех идентификаторов элементов
Я использую скрипт Tweenmax, который я нашел, чтобы создать волновой эффект на некоторых кнопках. У меня есть HTML следующим образом:
<label for="slider_1" id="js-ripple-btn" class="button styl-material">
Home
<svg class="ripple-obj" id="js-ripple"><use height="100" width="100" xlink:href="#ripply-scott" class="js-ripple"></use></svg>
</label>
<label for="slider_2" id="js-ripple-btn2" class="button styl-material">
Catalogue
<svg class="ripple-obj" id="js-ripple2"><use height="100" width="100" xlink:href="#ripply-scott" class="js-ripple2"></use></svg>
</label>
...
Я немного заблудился, как заставить скрипт прослушивать любой из идентификаторов, которые имеют класс js-ripple, а не указывать только один. Следующий код предназначается только для первого идентификатора элемента, но мне нужно, чтобы он предназначался для любого идентификатора элемента, по которому щелкают.
var ripplyScott = (function() {
var circle = document.getElementById('js-ripple'),
ripple = document.querySelectorAll('.js-ripple');
function rippleAnimation(event, timing) {
var tl = new TimelineMax();
x = event.offsetX,
y = event.offsetY,
w = event.target.offsetWidth,
h = event.target.offsetHeight,
offsetX = Math.abs( (w / 2) - x ),
offsetY = Math.abs( (h / 2) - y ),
deltaX = (w / 2) + offsetX,
deltaY = (h / 2) + offsetY,
scale_ratio = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
console.log('x is:' + x);
console.log('y is:' + y);
console.log('offsetX is:' + offsetX);
console.log('offsetY is:' + offsetY);
console.log('deltaX is:' + deltaX);
console.log('deltaY is:' + deltaY);
console.log('width is:' + w);
console.log('height is:' + h);
console.log('scale ratio is:' + scale_ratio);
tl.fromTo(ripple, timing, {
x: x,
y: y,
transformOrigin: '50% 50%',
scale: 0,
opacity: 1,
ease: Linear.easeIn
},{
scale: scale_ratio,
opacity: 0
});
return tl;
}
return {
init: function(target, timing) {
var button = document.getElementById(target);
button.addEventListener('click', function(event) {
rippleAnimation.call(this, event, timing);
});
}
};
})();
ripplyScott.init('js-ripple-btn', 0.75);
Очевидно, я могу дублировать скрипт, меняя идентификатор элемента для каждой кнопки, но это, я уверен, смешное повторение кода, когда должен быть способ нацеливания на всех с небольшой модификацией. Помощь / руководство приветствуется спасибо!
** Обновление ** Вот скрипка, так что вы можете увидеть мою проблему. Благодарю.
2 ответа
Я попытался решить вашу проблему, основываясь на моем понимании. Посмотрите на это jsFiddle.
Вот объяснение:
- Идентификаторы всегда должны быть уникальными для элементов.
- Ваш
js-ripple-btn
Идентификатор был изменен на класс. - Нам нужен был способ получить ссылку на нажатую кнопку, чтобы мы могли воспроизвести соответствующую анимацию.
- Мы решили это с помощью
index
переменная от кнопок, передавая их вплоть до вашей анимации.
Snippet:
var ripplyScott = (function() {
var circle = document.getElementById('js-ripple');
var ripple = document.querySelectorAll('.js-ripple');
function rippleAnimation(event, timing, index) {
var tl = new TimelineMax();
var x = event.offsetX;
var y = event.offsetY;
var w = event.target.offsetWidth;
var h = event.target.offsetHeight;
var offsetX = Math.abs((w / 2) - x);
var offsetY = Math.abs((h / 2) - y);
var deltaX = (w / 2) + offsetX;
var deltaY = (h / 2) + offsetY;
var scale_ratio = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
tl.fromTo(ripple[index], timing, {
x: x,
y: y,
transformOrigin: '50% 50%',
scale: 0,
opacity: 1,
ease: Linear.easeIn
}, {
scale: scale_ratio,
opacity: 0
});
return tl;
}
return {
init: function(target, timing) {
var buttons = document.getElementsByClassName(target);
var numButtons = buttons.length;
for (var i = 0; i < numButtons; i += 1) {
(function(index) {
buttons[index].addEventListener('click', function(event) {
rippleAnimation.call(this, event, timing, index);
});
}(i));
}
}
};
})();
ripplyScott.init('js-ripple-btn', 0.75);
label {
border-radius: 0;
display: block;
background: #ccc;
margin: 5px 0;
cursor: pointer;
color: #333;
width: 200px;
padding: 0;
font-size: 15px;
border: 1px solid #333;
text-align: center;
height: 70px;
line-height: 70px;
overflow: hidden;
}
.button {
padding: 1.5em 3em;
margin: 0;
position: relative;
display: inline-block;
overflow: hidden;
}
.button.styl-material {
transition: 200ms background cubic-bezier(0.4, 0, 0.2, 1);
}
.button.styl-material:hover,
.button.styl-material:focus {
outline: none;
}
.ripple-obj,
.ripple-obj2 {
height: 100%;
pointer-events: none;
position: absolute;
top: 0;
left: 0;
z-index: 0;
width: 100%;
fill: #AD1457;
}
.ripple-obj use,
.ripple-obj2 use {
opacity: 0;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js"></script>
<label class="button styl-material js-ripple-btn" for="slider_1">Home
<svg class="ripple-obj" id="js-ripple">
<use class="js-ripple" height="100" width="100" xlink:href="#ripply-scott">
</use>
</svg>
</label>
<label class="button styl-material js-ripple-btn" for="slider_2">Catalogue
<svg class="ripple-obj" id="js-ripple2">
<use class="js-ripple" height="100" width="100" xlink:href="#ripply-scott">
</use>
</svg>
</label>
<!-- Firefox Button Fix -->
<div aria-hidden="true" style="height: 0; width: 0; position: absolute; visibility: hidden;">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialgradient id="gradient">
<stop offset="0" stop-color="#0868BB"></stop>
<stop offset="0.25" stop-color="#0075D8"></stop>
<stop offset="0.35" stop-color="#0868BB"></stop>
<stop offset="0.5" stop-color="#0075D8"></stop>
<stop offset="0.6" stop-color="#0868BB"></stop>
<stop offset="0.85" stop-color="#0075D8"></stop>
<stop offset="1" stop-color="#0868BB"></stop>
</radialgradient>
</defs>
<symbol id="ripply-scott" viewbox="0 0 100 100">
<circle cx="1" cy="1" fill="url(#gradient)" id="ripple-shape" r="1"></circle>
</symbol>
</svg>
</div>
<!-- / FF button fix -->
Надеюсь это поможет.
Вы можете добавить onClick
на ваши кнопки, чтобы захватить их идентификатор, а затем запустить ripplyScott.init
передавая идентификатор нажатой кнопки, чтобы target
,
<label class="button styl-material" for="slider_1" id="js-ripple-btn" onClick="myClick(this.id)">
var elementId;
function myClick(id) {
elementId = id;
ripplyScott.init(id, 0.75);
}
return {
init: function(target, timing) {
rippleAnimation.call(target, event, timing);
}
};
И объявите ваш пульсации вар как:
var ripple = document.getElementById(elementId).childNodes[1].childNodes[1];