javascript - 所有元素 ID 的 TweenMax 重用函数

标签 javascript gsap

我正在使用我发现的 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 类的 ID 而不是只指定一个 ID 有点迷茫。以下代码仅以第一个元素 ID 为目标,但我需要它以单击的任何元素 ID 为目标。

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

我显然可以复制将元素 ID 更改为每个按钮的脚本,但这意味着,我敢肯定,当必须有一种方法来定位所有代码并稍加修改时,代码的重复是荒谬的。感谢您的帮助/指导!

** 更新 ** 这是一个fiddle这样您就可以看到我的问题。谢谢。

最佳答案

我已经尝试根据我的理解来解决你的问题。看看这个 jsFiddle .

解释如下:

  • ID 对于元素应该始终是唯一的。
  • 您的 js-ripple-btn ID 已更改为类。
  • 我们需要一种方法来获取对已单击按钮的引用,以便我们可以播放相应的动画。
  • 我们通过使用 buttonsindex 变量将它们一直传递到您的 animations 来解决这个问题。

片段:

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

希望这对您有所帮助。

关于javascript - 所有元素 ID 的 TweenMax 重用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36076875/

相关文章:

javascript - 递归js函数简化列表结果

javascript - 帮助我减少简单 jQuery 函数中的代码重复

javascript - Google LineChart 图例和网格线

javascript - GreenSock 动画未按预期工作

javascript - 使用 eval() 会增加内存消耗吗?

javascript - ExtJs 4 ViewPort 与带有边框布局的面板 - 使用哪个以及为什么?

javascript - 使用 ThreeJS 网格的 Tweenmax 比例

javascript - 特定 anchor 标签的平滑滚动不适用于所有 anchor 标签

javascript - javascript中的圆形动画,greensock tweenlite

javascript - 第一个 TweenLite 旋转不被渲染