fix: 水印插件兼容微前端场景,应用唯一

This commit is contained in:
wanchun 2023-03-15 17:55:21 +08:00
parent caf630071a
commit b0ff6ee7e1
6 changed files with 69 additions and 49 deletions

View File

@ -46,6 +46,7 @@
"@fesjs/fes": "^3.0.0-rc.0",
"@fesjs/builder-webpack": "^3.0.0-rc.5",
"@fesjs/plugin-qiankun": "3.0.0-rc.0",
"@fesjs/plugin-watermark": "3.0.0-rc.0",
"vue": "^3.2.37",
"@fesjs/fes-design": "^0.7.0"
},

View File

@ -1,4 +1,4 @@
import { access as accessApi } from '@fesjs/fes';
import { access as accessApi, createWatermark } from '@fesjs/fes';
import PageLoading from '@/components/PageLoading.vue';
export const beforeRender = {
@ -10,6 +10,7 @@ export const beforeRender = {
setRole('admin');
resolve();
}, 1000);
createWatermark();
});
},
};

View File

@ -46,6 +46,7 @@
"@fesjs/fes": "^3.0.0-rc.0",
"@fesjs/builder-webpack": "^3.0.0-rc.5",
"@fesjs/plugin-qiankun": "3.0.0-rc.0",
"@fesjs/plugin-watermark": "3.0.0-rc.0",
"vue": "^3.2.37",
"@fesjs/fes-design": "^0.7.0"
},

View File

@ -8,8 +8,14 @@
}
</config>
<script>
import { onBeforeUnmount } from 'vue';
import { createWatermark, destroyWatermark } from '@fesjs/fes';
export default {
setup() {
createWatermark();
onBeforeUnmount(destroyWatermark);
return {
bigData: new Array(5 * 1024 * 1024),
};

View File

@ -30,31 +30,37 @@ function timeFormat(date, format = 'YYYY-MM-DD') {
return format.replace(/Y+|M+|D+|H+|h+|m+|s+|S+|Q/g, (str) => String(map[str]));
}
let _wmContainerMo = null; // MutationObserver
let _wmMo = null; // MutationObserver
let _wmTimer = null; // timestamp
let wmContainerObx = null; // MutationObserver
let wmObx = null; // MutationObserver
let wmTimer = null; // timestamp
let watermarkDiv = null;
// 销毁水印
export function destroyWatermark() {
// 监听器关闭
_wmMo?.disconnect();
_wmMo = null;
_wmContainerMo?.disconnect();
_wmContainerMo = null;
wmObx?.disconnect();
wmObx = null;
wmContainerObx?.disconnect();
wmContainerObx = null;
// 清除timer
if (_wmTimer) {
window.clearTimeout(_wmTimer);
_wmTimer = null;
if (wmTimer) {
window.clearTimeout(wmTimer);
wmTimer = null;
}
// 删除水印元素
let __wm = document.querySelector('.__wm');
__wm?.parentNode?.removeChild(__wm);
__wm = null;
watermarkDiv?.parentNode?.removeChild(watermarkDiv);
watermarkDiv = null;
}
function _createWatermark(param) {
function innerCreateWatermark(param) {
const { content, container, width, height, textAlign, textBaseline, fontSize, fontFamily, fillStyle, rotate, zIndex, timestamp, watch } = param;
if (!container) {
return console.warn('createWatermark配置的container不能为空');
}
destroyWatermark();
const canvas = document.createElement('canvas');
canvas.setAttribute('width', `${width}px`);
canvas.setAttribute('height', `${height}px`);
@ -67,9 +73,13 @@ function _createWatermark(param) {
ctx.translate(width / 2, height / 2);
ctx.rotate(-(Math.PI / 180) * rotate);
ctx.fillText(`${content}`, 0, 0);
timestamp && ctx.fillText(`${timeFormat(new Date(), timestamp)}`, 0, parseInt(fontSize) + 5);
if (timestamp) {
ctx.fillText(`${timeFormat(new Date(), timestamp)}`, 0, parseInt(fontSize) + 5);
}
const watermarkDiv = document.querySelector('.__wm') || document.createElement('div');
const CLASS_NAME = `wm_${Date.now()}`;
watermarkDiv = document.createElement('div');
const styleStr = `
position: ${container === document.body ? 'fixed' : 'absolute'};
user-select: none;
@ -81,9 +91,8 @@ function _createWatermark(param) {
pointer-events: none !important;
background-repeat: repeat;
background-image: url('${canvas.toDataURL()}')`;
watermarkDiv.setAttribute('style', styleStr);
watermarkDiv.classList.add('__wm');
watermarkDiv.classList.add(CLASS_NAME);
if (container.firstChild) {
container.insertBefore(watermarkDiv, container.firstChild);
@ -91,26 +100,25 @@ function _createWatermark(param) {
container.appendChild(watermarkDiv);
}
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
const MutationObserver = window.MutationObserver;
if (watch && MutationObserver) {
_wmContainerMo = new MutationObserver(() => {
const __wm = container.querySelector('.__wm');
if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
destroyWatermark();
_createWatermark(param);
wmContainerObx = new MutationObserver(() => {
if (!container.querySelector(`.${CLASS_NAME}`)) {
innerCreateWatermark(param);
}
});
_wmContainerMo.observe(container, {
wmContainerObx.observe(container, {
childList: true,
});
_wmMo = new MutationObserver(() => {
destroyWatermark();
_createWatermark(param);
wmObx = new MutationObserver(() => {
if (watermarkDiv.getAttribute('style') !== styleStr) {
innerCreateWatermark(param);
}
});
_wmMo.observe(watermarkDiv, {
wmObx.observe(watermarkDiv, {
attributes: true,
});
}
@ -125,9 +133,8 @@ function _createWatermark(param) {
timeout = 1000 * 60 * 60;
}
_wmTimer = window.setTimeout(() => {
destroyWatermark();
_createWatermark(param);
wmTimer = window.setTimeout(() => {
innerCreateWatermark(param);
}, timeout);
}
}
@ -155,10 +162,7 @@ export function createWatermark(option) {
watch: true,
};
// 为避免多次调用 createWatermark 触发重复监听,这里先执行销毁水印操作
destroyWatermark();
_createWatermark({
innerCreateWatermark({
...defaultOption,
...option,
});

View File

@ -1,18 +1,25 @@
import '@fesjs/fes';
interface WatermarkParam {
content: string;
container: HTMLElement;
width: number;
height: number;
textAlign: 'left' | 'right' | 'center' | 'start' | 'end';
textBaseline: 'top' | 'hanging' | 'middle' | 'alphabetic' | 'ideographic' | 'bottom';
fontSize: string;
fontFamily: string;
fillStyle: string;
rotate: number;
zIndex: number;
timestamp: string;
content?: string;
container?: HTMLElement;
width?: number;
height?: number;
textAlign?: 'center' | 'end' | 'left' | 'right' | 'start';
textBaseline?:
| 'alphabetic'
| 'bottom'
| 'hanging'
| 'ideographic'
| 'middle'
| 'top';
fontSize?: string;
fontFamily?: string;
fillStyle?: string;
rotate?: number;
zIndex?: number;
timestamp?: string | false;
watch?: boolean;
}
export function createWatermark(param: WatermarkParam): void;
export function destroyWatermark(): void;