ripple.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. (function(){
  2. "use strict";
  3. var colour = "#FFCC00";
  4. var opacity = 0.3;
  5. var ripple_within_elements = ['input', 'button', 'a', 'p', 'span', 'div'];
  6. var ripple_without_diameter = 50;
  7. var overlays = {
  8. items: [],
  9. get: function(){
  10. var $element;
  11. for(var i = 0; i < overlays.items.length; i++){
  12. $element = overlays.items[i];
  13. if($element.transition_phase === false) {
  14. $element.transition_phase = 0;
  15. return $element;
  16. }
  17. }
  18. $element = document.createElement("div");
  19. $element.style.position = "absolute";
  20. $element.style.opacity = opacity;
  21. //$element.style.outline = "10px solid red";
  22. $element.style.pointerEvents = "none";
  23. $element.style.background = "-webkit-radial-gradient(" + colour + " 64%, rgba(0,0,0,0) 65%) no-repeat";
  24. $element.style.background = "radial-gradient(" + colour + " 64%, rgba(0,0,0,0) 65%) no-repeat";
  25. $element.style.transform = "translateZ(0)";
  26. $element.transition_phase = 0;
  27. $element.rid = overlays.items.length;
  28. $element.next_transition = overlays.next_transition_generator($element);
  29. document.body.appendChild($element);
  30. overlays.items.push($element);
  31. return $element;
  32. },
  33. next_transition_generator: function($element){
  34. return function(){
  35. $element.transition_phase++;
  36. switch($element.transition_phase){
  37. case 1:
  38. $element.style[transition] = "all 0.2s ease-in-out";
  39. $element.style.backgroundSize = $element.ripple_backgroundSize;
  40. $element.style.backgroundPosition = $element.ripple_backgroundPosition;
  41. setTimeout($element.next_transition, 0.2 * 1000); //now I know transitionend is better but it fires multiple times when multiple properties are animated, so this is simpler code and (imo) worth tiny delays
  42. break;
  43. case 2:
  44. $element.style[transition] = "opacity 0.15s ease-in-out";
  45. $element.style.opacity = 0;
  46. setTimeout($element.next_transition, 0.15 * 1000);
  47. break;
  48. case 3:
  49. overlays.recycle($element);
  50. break;
  51. }
  52. };
  53. },
  54. recycle: function($element){
  55. $element.style.display = "none";
  56. $element.style[transition] = "none";
  57. if($element.timer) clearTimeout($element.timer);
  58. $element.transition_phase = false;
  59. }
  60. };
  61. var transition = function(){
  62. var i,
  63. el = document.createElement('div'),
  64. transitions = {
  65. 'WebkitTransition':'webkitTransition',
  66. 'transition':'transition',
  67. 'OTransition':'otransition',
  68. 'MozTransition':'transition'
  69. };
  70. for (i in transitions) {
  71. if (transitions.hasOwnProperty(i) && el.style[i] !== undefined) {
  72. return transitions[i];
  73. }
  74. }
  75. }();
  76. var click = function(event){
  77. touch = event.touches ? event.touches[0] : event;
  78. if(!$(touch.target).hasClass('ripple')){
  79. return ;
  80. }
  81. var darker = 1;
  82. if($(touch.target).hasClass('ripple-brighter')){
  83. darker = 0;
  84. }
  85. colour = change_brightness($(touch.target).css('backgroundColor'), 35, darker);
  86. var $element = overlays.get(),
  87. touch,
  88. x,
  89. y;
  90. $element.style[transition] = "none";
  91. $element.style.backgroundSize = "3px 3px";
  92. $element.style.opacity = opacity;
  93. if(ripple_within_elements.indexOf(touch.target.nodeName.toLowerCase()) > -1) {
  94. x = touch.offsetX;
  95. y = touch.offsetY;
  96. var dimensions = touch.target.getBoundingClientRect();
  97. if(!x || !y){
  98. x = (touch.clientX || touch.x) - dimensions.left;
  99. y = (touch.clientY || touch.y) - dimensions.top;
  100. }
  101. $element.style.backgroundPosition = x + "px " + y + "px";
  102. $element.style.width = dimensions.width + "px";
  103. $element.style.height = dimensions.height + "px";
  104. $element.style.left = (dimensions.left) + "px";
  105. $element.style.top = (dimensions.top + document.body.scrollTop + document.documentElement.scrollTop) + "px";
  106. var computed_style = window.getComputedStyle(event.target);
  107. for (var key in computed_style) {
  108. if (key.toString().indexOf("adius") > -1) {
  109. if(computed_style[key]) {
  110. $element.style[key] = computed_style[key];
  111. }
  112. } else if(parseInt(key, 10).toString() === key && computed_style[key].indexOf("adius") > -1){
  113. $element.style[computed_style[key]] = computed_style[computed_style[key]];
  114. }
  115. }
  116. $element.style.backgroundPosition = x + "px " + y + "px";
  117. $element.ripple_backgroundPosition = (x - dimensions.width) + "px " + (y - dimensions.width) + "px";
  118. $element.ripple_backgroundSize = (dimensions.width * 2) + "px " + (dimensions.width * 2) + "px";
  119. $element.ripple_x = x;
  120. $element.ripple_y = y;
  121. $element.style.display = "block";
  122. setTimeout($element.next_transition, 20);
  123. }
  124. };
  125. if('ontouchstart' in window || 'onmsgesturechange' in window){
  126. document.addEventListener("touchstart", click, false);
  127. } else {
  128. document.addEventListener("click", click, false);
  129. }
  130. }());
  131. function change_brightness(rgb_color, percent, darker){
  132. darker = darker || 0;
  133. var parts = rgb_color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
  134. delete(parts[0]);
  135. for (var i = 1; i <= 3; ++i) {
  136. parts[i] = parseInt(parts[i]).toString(16);
  137. if (parts[i].length == 1) parts[i] = '0' + parts[i];
  138. }
  139. hex = parts.join('');
  140. // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
  141. if(hex.length == 3){
  142. hex = hex.replace(/(.)/g, '$1$1');
  143. }
  144. var r = parseInt(hex.substr(0, 2), 16),
  145. g = parseInt(hex.substr(2, 2), 16),
  146. b = parseInt(hex.substr(4, 2), 16);
  147. if(darker){
  148. return '#' +
  149. ((0|(1<<8) + r - (r) * percent / 100).toString(16)).substr(1) +
  150. ((0|(1<<8) + g - (g) * percent / 100).toString(16)).substr(1) +
  151. ((0|(1<<8) + b - (b) * percent / 100).toString(16)).substr(1);
  152. }else{
  153. return '#' +
  154. ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
  155. ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
  156. ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);
  157. }
  158. }