You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
7.7 KiB

1 year ago
  1. /*!
  2. * Farbtastic: jQuery color picker plug-in v1.3u
  3. * https://github.com/mattfarina/farbtastic
  4. *
  5. * Licensed under the GPL license:
  6. * http://www.gnu.org/licenses/gpl.html
  7. */
  8. /**
  9. * Modified for WordPress: replaced deprecated jQuery methods.
  10. * See https://core.trac.wordpress.org/ticket/57946.
  11. */
  12. (function($) {
  13. $.fn.farbtastic = function (options) {
  14. $.farbtastic(this, options);
  15. return this;
  16. };
  17. $.farbtastic = function (container, callback) {
  18. var container = $(container).get(0);
  19. return container.farbtastic || (container.farbtastic = new $._farbtastic(container, callback));
  20. };
  21. $._farbtastic = function (container, callback) {
  22. // Store farbtastic object
  23. var fb = this;
  24. // Insert markup
  25. $(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
  26. var e = $('.farbtastic', container);
  27. fb.wheel = $('.wheel', container).get(0);
  28. // Dimensions
  29. fb.radius = 84;
  30. fb.square = 100;
  31. fb.width = 194;
  32. // Fix background PNGs in IE6
  33. if (navigator.appVersion.match(/MSIE [0-6]\./)) {
  34. $('*', e).each(function () {
  35. if (this.currentStyle.backgroundImage != 'none') {
  36. var image = this.currentStyle.backgroundImage;
  37. image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
  38. $(this).css({
  39. 'backgroundImage': 'none',
  40. 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
  41. });
  42. }
  43. });
  44. }
  45. /**
  46. * Link to the given element(s) or callback.
  47. */
  48. fb.linkTo = function (callback) {
  49. // Unbind previous nodes
  50. if (typeof fb.callback == 'object') {
  51. $(fb.callback).off('keyup', fb.updateValue);
  52. }
  53. // Reset color
  54. fb.color = null;
  55. // Bind callback or elements
  56. if (typeof callback == 'function') {
  57. fb.callback = callback;
  58. }
  59. else if (typeof callback == 'object' || typeof callback == 'string') {
  60. fb.callback = $(callback);
  61. fb.callback.on('keyup', fb.updateValue);
  62. if (fb.callback.get(0).value) {
  63. fb.setColor(fb.callback.get(0).value);
  64. }
  65. }
  66. return this;
  67. };
  68. fb.updateValue = function (event) {
  69. if (this.value && this.value != fb.color) {
  70. fb.setColor(this.value);
  71. }
  72. };
  73. /**
  74. * Change color with HTML syntax #123456
  75. */
  76. fb.setColor = function (color) {
  77. var unpack = fb.unpack(color);
  78. if (fb.color != color && unpack) {
  79. fb.color = color;
  80. fb.rgb = unpack;
  81. fb.hsl = fb.RGBToHSL(fb.rgb);
  82. fb.updateDisplay();
  83. }
  84. return this;
  85. };
  86. /**
  87. * Change color with HSL triplet [0..1, 0..1, 0..1]
  88. */
  89. fb.setHSL = function (hsl) {
  90. fb.hsl = hsl;
  91. fb.rgb = fb.HSLToRGB(hsl);
  92. fb.color = fb.pack(fb.rgb);
  93. fb.updateDisplay();
  94. return this;
  95. };
  96. /////////////////////////////////////////////////////
  97. /**
  98. * Retrieve the coordinates of the given event relative to the center
  99. * of the widget.
  100. */
  101. fb.widgetCoords = function (event) {
  102. var offset = $(fb.wheel).offset();
  103. return { x: (event.pageX - offset.left) - fb.width / 2, y: (event.pageY - offset.top) - fb.width / 2 };
  104. };
  105. /**
  106. * Mousedown handler
  107. */
  108. fb.mousedown = function (event) {
  109. // Capture mouse
  110. if (!document.dragging) {
  111. $(document).on('mousemove', fb.mousemove).on('mouseup', fb.mouseup);
  112. document.dragging = true;
  113. }
  114. // Check which area is being dragged
  115. var pos = fb.widgetCoords(event);
  116. fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
  117. // Process
  118. fb.mousemove(event);
  119. return false;
  120. };
  121. /**
  122. * Mousemove handler
  123. */
  124. fb.mousemove = function (event) {
  125. // Get coordinates relative to color picker center
  126. var pos = fb.widgetCoords(event);
  127. // Set new HSL parameters
  128. if (fb.circleDrag) {
  129. var hue = Math.atan2(pos.x, -pos.y) / 6.28;
  130. if (hue < 0) hue += 1;
  131. fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
  132. }
  133. else {
  134. var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
  135. var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
  136. fb.setHSL([fb.hsl[0], sat, lum]);
  137. }
  138. return false;
  139. };
  140. /**
  141. * Mouseup handler
  142. */
  143. fb.mouseup = function () {
  144. // Uncapture mouse
  145. $(document).off('mousemove', fb.mousemove);
  146. $(document).off('mouseup', fb.mouseup);
  147. document.dragging = false;
  148. };
  149. /**
  150. * Update the markers and styles
  151. */
  152. fb.updateDisplay = function () {
  153. // Markers
  154. var angle = fb.hsl[0] * 6.28;
  155. $('.h-marker', e).css({
  156. left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
  157. top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
  158. });
  159. $('.sl-marker', e).css({
  160. left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
  161. top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
  162. });
  163. // Saturation/Luminance gradient
  164. $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
  165. // Linked elements or callback
  166. if (typeof fb.callback == 'object') {
  167. // Set background/foreground color
  168. $(fb.callback).css({
  169. backgroundColor: fb.color,
  170. color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
  171. });
  172. // Change linked value
  173. $(fb.callback).each(function() {
  174. if (this.value && this.value != fb.color) {
  175. this.value = fb.color;
  176. }
  177. });
  178. }
  179. else if (typeof fb.callback == 'function') {
  180. fb.callback.call(fb, fb.color);
  181. }
  182. };
  183. /* Various color utility functions */
  184. fb.pack = function (rgb) {
  185. var r = Math.round(rgb[0] * 255);
  186. var g = Math.round(rgb[1] * 255);
  187. var b = Math.round(rgb[2] * 255);
  188. return '#' + (r < 16 ? '0' : '') + r.toString(16) +
  189. (g < 16 ? '0' : '') + g.toString(16) +
  190. (b < 16 ? '0' : '') + b.toString(16);
  191. };
  192. fb.unpack = function (color) {
  193. if (color.length == 7) {
  194. return [parseInt('0x' + color.substring(1, 3)) / 255,
  195. parseInt('0x' + color.substring(3, 5)) / 255,
  196. parseInt('0x' + color.substring(5, 7)) / 255];
  197. }
  198. else if (color.length == 4) {
  199. return [parseInt('0x' + color.substring(1, 2)) / 15,
  200. parseInt('0x' + color.substring(2, 3)) / 15,
  201. parseInt('0x' + color.substring(3, 4)) / 15];
  202. }
  203. };
  204. fb.HSLToRGB = function (hsl) {
  205. var m1, m2, r, g, b;
  206. var h = hsl[0], s = hsl[1], l = hsl[2];
  207. m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
  208. m1 = l * 2 - m2;
  209. return [this.hueToRGB(m1, m2, h+0.33333),
  210. this.hueToRGB(m1, m2, h),
  211. this.hueToRGB(m1, m2, h-0.33333)];
  212. };
  213. fb.hueToRGB = function (m1, m2, h) {
  214. h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
  215. if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
  216. if (h * 2 < 1) return m2;
  217. if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
  218. return m1;
  219. };
  220. fb.RGBToHSL = function (rgb) {
  221. var min, max, delta, h, s, l;
  222. var r = rgb[0], g = rgb[1], b = rgb[2];
  223. min = Math.min(r, Math.min(g, b));
  224. max = Math.max(r, Math.max(g, b));
  225. delta = max - min;
  226. l = (min + max) / 2;
  227. s = 0;
  228. if (l > 0 && l < 1) {
  229. s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
  230. }
  231. h = 0;
  232. if (delta > 0) {
  233. if (max == r && max != g) h += (g - b) / delta;
  234. if (max == g && max != b) h += (2 + (b - r) / delta);
  235. if (max == b && max != r) h += (4 + (r - g) / delta);
  236. h /= 6;
  237. }
  238. return [h, s, l];
  239. };
  240. // Install mousedown handler (the others are set on the document on-demand)
  241. $('*', e).on('mousedown', fb.mousedown);
  242. // Init color
  243. fb.setColor('#000000');
  244. // Set linked elements/callback
  245. if (callback) {
  246. fb.linkTo(callback);
  247. }
  248. };
  249. })(jQuery);