watermark.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* global Watermark */
  2. layui.define(['jquery', 'element'], function(exports) {
  3. var $=layui.$;
  4. var _parentEle;
  5. var _wmContainer;
  6. var _wmObserver;
  7. var _wmParentObserver;
  8. var _resizeHandler;
  9. var _windowsWidth = window.outerWidth;
  10. var _windowsHeight = window.outerHeight;
  11. var _left = 0;
  12. var _top = 0;
  13. /**
  14. * Create DOM of watermark's container
  15. * @param {Watermark} watermark
  16. */
  17. var _createContainer = function (watermark) {
  18. watermark._container = document.createElement('div');
  19. watermark._container.classList.add('cell-watermark-container');
  20. watermark._container.style.cssText = 'display: block; pointer-events: none;';
  21. watermark._container.setAttribute('aria-hidden', true);
  22. _parentEle = document.querySelector(watermark.options.appendTo) || document.body;
  23. //获取页面最大宽度
  24. _windowsWidth = Math.min(_parentEle.scrollWidth, _parentEle.clientWidth);
  25. //获取页面最大高度
  26. _windowsHeight = Math.min(_parentEle.scrollHeight, _parentEle.clientHeight);
  27. _parentEle.appendChild(watermark._container);
  28. };
  29. /**
  30. * Create watermark's DOM
  31. * @param {Watermark} watermark
  32. * @param {Object} options
  33. */
  34. var _createWatermark = function (watermark, options) {
  35. options.rowSpacing = options.rowSpacing || 60;
  36. options.colSpacing = options.colSpacing || 30;
  37. options.width = options.width || 150;
  38. options.height = options.height || 20;
  39. let rows = parseInt(_windowsHeight / (options.height + options.rowSpacing));
  40. let cols = parseInt(_windowsWidth / (options.width + options.colSpacing));
  41. let offsetLeft =_left+ (_windowsWidth - options.width * cols - options.colSpacing * (cols - 1)) / 2;
  42. let offsetTop = _top+(_windowsHeight - options.height * rows - options.rowSpacing * (rows - 1)) / 2;
  43. let watermarkBase = document.createElement('div');
  44. watermarkBase.classList.add('cell-watermark');
  45. watermarkBase.style.cssText =
  46. 'transform: rotate(15deg); opacity: 0.1; font-size: 0.85rem; text-align: center;' +
  47. 'position: absolute; user-select: none; word-break: break-all; overflow: hidden; z-index: 999999;';
  48. for (let row = 0; row < rows; row++) {
  49. let top = offsetTop + (options.rowSpacing + options.height) * row;
  50. let tempCols = cols;
  51. row % 2 !== 0 && tempCols++;
  52. for (let col = 0; col < tempCols; col++) {
  53. let left = offsetLeft + (options.colSpacing + options.width) * col;
  54. tempCols !== cols && (left -= (options.colSpacing + options.width) / 2);
  55. let watermarkEle = watermarkBase.cloneNode();
  56. watermarkEle.style.cssText += `left: ${left}px; top: ${top}px; width: ${options.width}px; height: ${options.height}px`;
  57. watermarkEle.style.transform = `rotate(${options.rotate}deg)`;
  58. watermarkEle.style.opacity = options.opacity;
  59. watermarkEle.style.fontSize = `${options.fontSize}rem`;
  60. watermarkEle.style.fontFamily = options.fontFamily;
  61. watermarkEle.innerHTML = options.content;
  62. watermark._container.appendChild(watermarkEle);
  63. }
  64. }
  65. //Backup for recover the watermark's container when the its DOM is removed
  66. _wmContainer = watermark._container;
  67. };
  68. /**
  69. * Rerender watermark
  70. * @param {Watermark} watermark
  71. * @param {Object} options
  72. */
  73. var _render = function (watermark, options) {
  74. _wmObserver.disconnect();
  75. watermark._container.innerHTML = '';
  76. _createWatermark(watermark, options);
  77. _wmObserver.observe(watermark._container, {
  78. attributes: true,
  79. childList: true,
  80. characterData: true,
  81. subtree: true
  82. });
  83. };
  84. /**
  85. * Observe watermark and watermark's parentNode mutations
  86. * @param {Watermark} watermark
  87. */
  88. var _addObserve = function (watermark) {
  89. //Observe watermark element and its child element
  90. _wmObserver = new MutationObserver(function (mutations, observer) {
  91. _render(watermark, watermark.options);
  92. });
  93. _wmObserver.observe(watermark._container, {
  94. attributes: true,
  95. childList: true,
  96. characterData: true,
  97. subtree: true
  98. });
  99. //Observe parent element, recreate if the element is deleted
  100. _wmParentObserver = new MutationObserver(function (mutations) {
  101. for (let m of mutations) {
  102. if (
  103. m.type === 'childList' &&
  104. m.removedNodes.length > 0 &&
  105. document.querySelectorAll('.cell-watermark-container').length === 0
  106. ) {
  107. _parentEle.appendChild(_wmContainer);
  108. }
  109. }
  110. });
  111. _wmParentObserver.observe(watermark._container.parentNode, {
  112. childList: true,
  113. subtree: true
  114. });
  115. };
  116. /**
  117. * Window's resize listener
  118. * @param {Watermark} watermark
  119. */
  120. var _addResizeListener = function (watermark) {
  121. _resizeHandler = function () {
  122. //获取页面最大宽度
  123. var _windowsWidth_n = Math.max(_parentEle.scrollWidth, _parentEle.clientWidth);
  124. //获取页面最大高度
  125. var _windowsHeight_n = Math.max(_parentEle.scrollHeight, _parentEle.clientHeight);
  126. /*if (window.outerHeight !== _windowsHeight || window.outerWidth !== _windowsWidth) {
  127. _windowsHeight = window.outerHeight;
  128. _windowsWidth = window.outerWidth;
  129. _render(watermark, watermark.options);
  130. }*/
  131. if (_windowsHeight_n !== _windowsHeight || _windowsWidth_n !== _windowsWidth) {
  132. _windowsHeight = _windowsHeight_n;
  133. _windowsWidth = _windowsWidth_n;
  134. _render(watermark, watermark.options);
  135. }
  136. };
  137. window.addEventListener('resize', _resizeHandler);
  138. };
  139. /**
  140. * Watermark.
  141. * Create watermark for webpage and automatic adjust when windows resize.
  142. * @param {Object} options
  143. * @param {String} [options.content] watermark's text
  144. * @param {String} [options.appendTo='body'] parent of watermark's container
  145. * @param {Number} [options.width=150] watermark's width. unit: px
  146. * @param {Number} [options.height=20] watermark's height. unit: px
  147. * @param {Number} [options.rowSpacing=60] row spacing of watermarks. unit: px
  148. * @param {Number} [options.colSpacing=30] col spacing of watermarks. unit: px
  149. * @param {Number} [options.rotate=15] watermark's tangent angle. unit: deg
  150. * @param {Number} [options.opacity=0.1] watermark's transparency
  151. * @param {Number} [options.fontSize=0.85] watermark's fontSize. unit: rem
  152. * @param {Number} [options.fontFamily='inherit'] watermark's fontFamily.
  153. * @namespace Watermark
  154. * @class Watermark
  155. * @version 1.0.3
  156. * @author @Lruihao https://lruihao.cn
  157. */
  158. function Watermark(options = {}) {
  159. var _proto = Watermark.prototype;
  160. this.options = options;
  161. _createContainer(this);
  162. _createWatermark(this, this.options);
  163. _addObserve(this);
  164. _addResizeListener(this);
  165. /**
  166. * Upload watermark's text content
  167. * @param {String} content watermark's text
  168. */
  169. _proto.upload = function (content) {
  170. if (!content) {
  171. return;
  172. }
  173. _wmParentObserver.disconnect();
  174. _wmObserver.disconnect();
  175. this.options.content = content;
  176. for (const watermark of this._container.querySelectorAll('.cell-watermark')) {
  177. watermark.innerHTML = content;
  178. }
  179. _wmParentObserver.observe(this._container.parentNode, {
  180. childList: true,
  181. subtree: true
  182. });
  183. _wmObserver.observe(this._container, {
  184. attributes: true,
  185. childList: true,
  186. characterData: true,
  187. subtree: true
  188. });
  189. };
  190. /**
  191. * Rerender watermark
  192. * @param {Object} options
  193. */
  194. _proto.render = function (options = {}) {
  195. _render(this, Object.assign(this.options, options));
  196. };
  197. /**
  198. * Force destroy watermark
  199. */
  200. _proto.destroy = function () {
  201. _wmObserver.disconnect();
  202. _wmParentObserver.disconnect();
  203. window.removeEventListener('resize', _resizeHandler);
  204. this._container.parentNode.removeChild(this._container);
  205. };
  206. }
  207. exports("watermark",Watermark);
  208. })