watermark.js 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Copyright [2022] [https://www.xiaonuo.vip]
  3. * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
  4. * 1.请不要删除和修改根目录下的LICENSE文件。
  5. * 2.请不要删除和修改Snowy源码头部的版权声明。
  6. * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
  7. * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
  8. * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  9. * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  10. */
  11. import tool from '@/utils/tool'
  12. export const watermark = {
  13. set: function (text1, text2) {
  14. const canvas = document.createElement('canvas')
  15. canvas.width = 150
  16. canvas.height = 120
  17. canvas.style.display = 'none'
  18. const shuiyin = canvas.getContext('2d')
  19. // 控制文字的旋转角度和上下位置
  20. shuiyin.rotate((-20 * Math.PI) / 180)
  21. shuiyin.translate(-50, 20)
  22. //文字颜色
  23. shuiyin.fillStyle = '#f5f5f5'
  24. //文字样式
  25. shuiyin.font = '100 16px Microsoft JhengHei '
  26. shuiyin.fillText(text1, canvas.width / 3, canvas.height / 2)
  27. shuiyin.fillText(text2, canvas.width / 3, canvas.height / 2 + 20)
  28. /* 新建一个用于填充canvas水印的标签,之所以没有直接在body上添加,
  29. 是因为z-index对个别内容影响,才考虑的不用body */
  30. const watermark = document.createElement('div')
  31. const styleStr = `
  32. position:fixed;
  33. top:0;
  34. left:0;
  35. width:100vw;
  36. height:100vh;
  37. z-index:99999;
  38. pointer-events:none;
  39. background-repeat:repeat;
  40. mix-blend-mode: multiply;
  41. background-image:url('${canvas.toDataURL('image/png')}')`
  42. watermark.setAttribute('style', styleStr)
  43. watermark.classList.add('watermark')
  44. document.body.appendChild(watermark)
  45. //此方法是防止用户通过控制台修改样式去除水印效果
  46. /* MutationObserver 是一个可以监听DOM结构变化的接口。 */
  47. const observer = new MutationObserver(() => {
  48. // 此处根据用户登录状态,判断是否终止监听,避免用户退出后登录页面仍然有水印
  49. if (!tool.data.get('TOKEN')) {
  50. this.close()
  51. observer.disconnect()
  52. }
  53. const wmInstance = document.body.querySelector('.watermark')
  54. if (!wmInstance || wmInstance.getAttribute('style') !== styleStr) {
  55. //如果标签在,只修改了属性,重新赋值属性
  56. if (wmInstance) {
  57. // 避免一直触发
  58. // observer.disconnect();
  59. wmInstance.setAttribute('style', styleStr)
  60. } else {
  61. /* 此处根据用户登录状态,判断是否终止监听,避免用户退出后登录页面仍然有水印 */
  62. if (tool.data.get('TOKEN')) {
  63. //标签被移除,重新添加标签
  64. document.body.appendChild(watermark)
  65. } else {
  66. observer.disconnect()
  67. }
  68. }
  69. }
  70. })
  71. observer.observe(document.body, {
  72. attributes: true,
  73. subtree: true,
  74. childList: true
  75. })
  76. },
  77. close: function () {
  78. /* 关闭页面的水印,即要移除水印标签 */
  79. let watermark = document.body.querySelector('.watermark')
  80. if (watermark) {
  81. document.body.removeChild(watermark)
  82. }
  83. }
  84. }
  85. // 使用方法
  86. // import { watermark } from '@/utils/watermark'
  87. // 添加水印
  88. // watermark.set('Snowy','xiaonuo.vip')
  89. // 移除水印,传 null 移除水印
  90. // watermark.close()