Файл: style/themes/material/js/ripples.js
Строк: 201
<?php
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
/* globals jQuery, navigator */
(function($) {
  // Detect if the browser supports transitions
  $.support.transition = (function(){
    var thisBody = document.body || document.documentElement,
        thisStyle = thisBody.style,
        support = (
          thisStyle.transition !== undefined ||
          thisStyle.WebkitTransition !== undefined ||
          thisStyle.MozTransition !== undefined ||
          thisStyle.MsTransition !== undefined ||
          thisStyle.OTransition !== undefined
        );
    return support;
  })();
  $.ripples = function(options) {
    // Default options
    var defaultOptions = {
      "target": ".btn:not(.btn-link), .card-image, .navbar a:not(.withoutripple), .nav-tabs a:not(.withoutripple), .withripple"
    };
    function isTouch() {
      return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }
    // Fade out the ripple and then destroy it
    function rippleOut(ripple) {
      // Unbind events from ripple
      ripple.off();
      // Start the out animation
      if ($.support.transition) {
        ripple.addClass("ripple-out");
      } else {
        ripple.animate({
          "opacity": 0
        }, 100, function() {
          ripple.trigger("transitionend");
        });
      }
      // This function is called when the transition "out" ends
      ripple.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
        ripple.remove();
      });
    }
    // Apply custom options
    options = $.extend(defaultOptions, options);
    $(document)
    .on("mousedown touchstart", options.target, function(e) {
      if (isTouch() && e.type == "mousedown") {
        return false;
      }
      var element = $(this);
      // If the ripple wrapper does not exists, create it
      if (!$(this).find(".ripple-wrapper").length) {
        $(this).append("<div class=ripple-wrapper></div>");
      }
      var wrapper = $(this).find(".ripple-wrapper");
      var wrapperOffset = wrapper.offset(),
          relX,
          relY;
      if (!isTouch()) {
        // Get the mouse position relative to the ripple wrapper
        relX = e.pageX - wrapperOffset.left;
        relY = e.pageY - wrapperOffset.top;
      } else {
        // Make sure the user is using only one finger and then get the touch position relative to the ripple wrapper
        e = e.originalEvent;
        if (e.touches.length === 1) {
          relX = e.touches[0].pageX - wrapperOffset.left;
          relY = e.touches[0].pageY - wrapperOffset.top;
        } else {
          return;
        }
      }
      // Meet the new ripple
      var ripple = $("<div></div>");
      // Add to it the ripple class
      ripple.addClass("ripple");
      // Position it in the right place
      ripple.css({"left": relX, "top": relY});
      // Set the background color of the ripple
      ripple.css({"background-color": window.getComputedStyle($(this)[0]).color});
      // Spawn it
      wrapper.append(ripple);
      // Make sure the ripple has the styles applied (ugly hack but it works)
      (function() { return window.getComputedStyle(ripple[0]).opacity; })();
      // Set the new size
      var size = (Math.max($(this).outerWidth(), $(this).outerHeight()) / ripple.outerWidth()) * 2.5;
      // Decide if use CSS transitions or jQuery transitions
      if ($.support.transition) {
        // Start the transition
        ripple.css({
          "-ms-transform": "scale(" + size + ")",
          "-moz-transform": "scale(" + size + ")",
          "-webkit-transform": "scale(" + size + ")",
          "transform": "scale(" + size + ")"
        });
        ripple.addClass("ripple-on");
        ripple.data("animating", "on");
        ripple.data("mousedown", "on");
      } else {
        // Start the transition
        ripple.animate({
          "width": Math.max($(this).outerWidth(), $(this).outerHeight()) * 2,
          "height": Math.max($(this).outerWidth(), $(this).outerHeight()) * 2,
          "margin-left": Math.max($(this).outerWidth(), $(this).outerHeight()) * -1,
          "margin-top": Math.max($(this).outerWidth(), $(this).outerHeight()) * -1,
          "opacity": 0.2
        }, 500, function() {
          ripple.trigger("transitionend");
        });
      }
      // This function is called when the transition "on" ends
      setTimeout(function() {
        ripple.data("animating", "off");
        if (ripple.data("mousedown") == "off") {
          rippleOut(ripple);
        }
      }, 500);
      // On mouseup or on mouseleave, set the mousedown flag to "off" and try to destroy the ripple
      element.on("mouseup mouseleave", function() {
        ripple.data("mousedown", "off");
        // If the transition "on" is finished then we can destroy the ripple with transition "out"
        if (ripple.data("animating") == "off") {
          rippleOut(ripple);
        }
      });
    });
  };
  $.fn.ripples = function() {
    $.ripples({"target": $(this)});
  };
})(jQuery);
?>