This commit is contained in:
2025-09-19 14:25:20 +08:00
parent 269893a435
commit fbf3f77229
24949 changed files with 2839404 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
import Watermark from './src/watermark.vue';
import type { SFCWithInstall } from 'element-plus/es/utils';
export declare const ElWatermark: SFCWithInstall<typeof Watermark>;
export default ElWatermark;
export * from './src/watermark';

View File

@@ -0,0 +1,14 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var watermark$1 = require('./src/watermark2.js');
var watermark = require('./src/watermark.js');
var install = require('../../utils/vue/install.js');
const ElWatermark = install.withInstall(watermark$1["default"]);
exports.watermarkProps = watermark.watermarkProps;
exports.ElWatermark = ElWatermark;
exports["default"] = ElWatermark;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../../packages/components/watermark/index.ts"],"sourcesContent":["import { withInstall } from '@element-plus/utils'\nimport Watermark from './src/watermark.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElWatermark: SFCWithInstall<typeof Watermark> =\n withInstall(Watermark)\nexport default ElWatermark\n\nexport * from './src/watermark'\n"],"names":["withInstall","Watermark"],"mappings":";;;;;;;;AAEY,MAAC,WAAW,GAAGA,mBAAW,CAACC,sBAAS;;;;;;"}

View File

@@ -0,0 +1,7 @@
import type { WatermarkProps } from './watermark';
export declare const FontGap = 3;
/**
* Get the clips of text content.
* This is a lazy hook function since SSR no need this
*/
export default function useClips(): (content: NonNullable<WatermarkProps["content"]> | HTMLImageElement, rotate: number, ratio: number, width: number, height: number, font: Required<NonNullable<WatermarkProps["font"]>>, gapX: number, gapY: number, space: number) => [dataURL: string, finalWidth: number, finalHeight: number];

View File

@@ -0,0 +1,105 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var shared = require('@vue/shared');
const FontGap = 3;
const TEXT_ALIGN_RATIO_MAP = {
left: [0, 0.5],
start: [0, 0.5],
center: [0.5, 0],
right: [1, -0.5],
end: [1, -0.5]
};
function prepareCanvas(width, height, ratio = 1) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const realWidth = width * ratio;
const realHeight = height * ratio;
canvas.setAttribute("width", `${realWidth}px`);
canvas.setAttribute("height", `${realHeight}px`);
ctx.save();
return [ctx, canvas, realWidth, realHeight];
}
function useClips() {
function getClips(content, rotate, ratio, width, height, font, gapX, gapY, space) {
const [ctx, canvas, contentWidth, contentHeight] = prepareCanvas(width, height, ratio);
if (content instanceof HTMLImageElement) {
ctx.drawImage(content, 0, 0, contentWidth, contentHeight);
} else {
const {
color,
fontSize,
fontStyle,
fontWeight,
fontFamily,
textAlign,
textBaseline
} = font;
const mergedFontSize = Number(fontSize) * ratio;
ctx.font = `${fontStyle} normal ${fontWeight} ${mergedFontSize}px/${height}px ${fontFamily}`;
ctx.fillStyle = color;
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
const contents = shared.isArray(content) ? content : [content];
contents == null ? void 0 : contents.forEach((item, index) => {
const [alignRatio, spaceRatio] = TEXT_ALIGN_RATIO_MAP[textAlign];
ctx.fillText(item != null ? item : "", contentWidth * alignRatio + space * spaceRatio, index * (mergedFontSize + FontGap * ratio));
});
}
const angle = Math.PI / 180 * Number(rotate);
const maxSize = Math.max(width, height);
const [rCtx, rCanvas, realMaxSize] = prepareCanvas(maxSize, maxSize, ratio);
rCtx.translate(realMaxSize / 2, realMaxSize / 2);
rCtx.rotate(angle);
if (contentWidth > 0 && contentHeight > 0) {
rCtx.drawImage(canvas, -contentWidth / 2, -contentHeight / 2);
}
function getRotatePos(x, y) {
const targetX = x * Math.cos(angle) - y * Math.sin(angle);
const targetY = x * Math.sin(angle) + y * Math.cos(angle);
return [targetX, targetY];
}
let left = 0;
let right = 0;
let top = 0;
let bottom = 0;
const halfWidth = contentWidth / 2;
const halfHeight = contentHeight / 2;
const points = [
[0 - halfWidth, 0 - halfHeight],
[0 + halfWidth, 0 - halfHeight],
[0 + halfWidth, 0 + halfHeight],
[0 - halfWidth, 0 + halfHeight]
];
points.forEach(([x, y]) => {
const [targetX, targetY] = getRotatePos(x, y);
left = Math.min(left, targetX);
right = Math.max(right, targetX);
top = Math.min(top, targetY);
bottom = Math.max(bottom, targetY);
});
const cutLeft = left + realMaxSize / 2;
const cutTop = top + realMaxSize / 2;
const cutWidth = right - left;
const cutHeight = bottom - top;
const realGapX = gapX * ratio;
const realGapY = gapY * ratio;
const filledWidth = (cutWidth + realGapX) * 2;
const filledHeight = cutHeight + realGapY;
const [fCtx, fCanvas] = prepareCanvas(filledWidth, filledHeight);
function drawImg(targetX = 0, targetY = 0) {
fCtx.drawImage(rCanvas, cutLeft, cutTop, cutWidth, cutHeight, targetX, targetY, cutWidth, cutHeight);
}
drawImg();
drawImg(cutWidth + realGapX, -cutHeight / 2 - realGapY / 2);
drawImg(cutWidth + realGapX, +cutHeight / 2 + realGapY / 2);
return [fCanvas.toDataURL(), filledWidth / ratio, filledHeight / ratio];
}
return getClips;
}
exports.FontGap = FontGap;
exports["default"] = useClips;
//# sourceMappingURL=useClips.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
import type { CSSProperties } from 'vue';
/** converting camel-cased strings to be lowercase and link it with Separator */
export declare function toLowercaseSeparator(key: string): string;
export declare function getStyleStr(style: CSSProperties): string;
/** Returns the ratio of the device's physical pixel resolution to the css pixel resolution */
export declare function getPixelRatio(): number;
/** Whether to re-render the watermark */
export declare const reRendering: (mutation: MutationRecord, watermarkElement?: HTMLElement) => boolean;

View File

@@ -0,0 +1,29 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function toLowercaseSeparator(key) {
return key.replace(/([A-Z])/g, "-$1").toLowerCase();
}
function getStyleStr(style) {
return Object.keys(style).map((key) => `${toLowercaseSeparator(key)}: ${style[key]};`).join(" ");
}
function getPixelRatio() {
return window.devicePixelRatio || 1;
}
const reRendering = (mutation, watermarkElement) => {
let flag = false;
if (mutation.removedNodes.length && watermarkElement) {
flag = Array.from(mutation.removedNodes).includes(watermarkElement);
}
if (mutation.type === "attributes" && mutation.target === watermarkElement) {
flag = true;
}
return flag;
};
exports.getPixelRatio = getPixelRatio;
exports.getStyleStr = getStyleStr;
exports.reRendering = reRendering;
exports.toLowercaseSeparator = toLowercaseSeparator;
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sources":["../../../../../../packages/components/watermark/src/utils.ts"],"sourcesContent":["import type { CSSProperties } from 'vue'\n\n/** converting camel-cased strings to be lowercase and link it with Separator */\nexport function toLowercaseSeparator(key: string) {\n return key.replace(/([A-Z])/g, '-$1').toLowerCase()\n}\n\nexport function getStyleStr(style: CSSProperties): string {\n return Object.keys(style)\n .map(\n (key) =>\n `${toLowercaseSeparator(key)}: ${style[key as keyof CSSProperties]};`\n )\n .join(' ')\n}\n\n/** Returns the ratio of the device's physical pixel resolution to the css pixel resolution */\nexport function getPixelRatio() {\n return window.devicePixelRatio || 1\n}\n\n/** Whether to re-render the watermark */\nexport const reRendering = (\n mutation: MutationRecord,\n watermarkElement?: HTMLElement\n) => {\n let flag = false\n // Whether to delete the watermark node\n if (mutation.removedNodes.length && watermarkElement) {\n flag = Array.from(mutation.removedNodes).includes(watermarkElement)\n }\n // Whether the watermark dom property value has been modified\n if (mutation.type === 'attributes' && mutation.target === watermarkElement) {\n flag = true\n }\n return flag\n}\n"],"names":[],"mappings":";;;;AAAO,SAAS,oBAAoB,CAAC,GAAG,EAAE;AAC1C,EAAE,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;AACtD,CAAC;AACM,SAAS,WAAW,CAAC,KAAK,EAAE;AACnC,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnG,CAAC;AACM,SAAS,aAAa,GAAG;AAChC,EAAE,OAAO,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;AACtC,CAAC;AACW,MAAC,WAAW,GAAG,CAAC,QAAQ,EAAE,gBAAgB,KAAK;AAC3D,EAAE,IAAI,IAAI,GAAG,KAAK,CAAC;AACnB,EAAE,IAAI,QAAQ,CAAC,YAAY,CAAC,MAAM,IAAI,gBAAgB,EAAE;AACxD,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACxE,GAAG;AACH,EAAE,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,CAAC,MAAM,KAAK,gBAAgB,EAAE;AAC9E,IAAI,IAAI,GAAG,IAAI,CAAC;AAChB,GAAG;AACH,EAAE,OAAO,IAAI,CAAC;AACd;;;;;;;"}

View File

@@ -0,0 +1,35 @@
import type { ExtractPropTypes, __ExtractPublicPropTypes } from 'vue';
import type Watermark from './watermark.vue';
export interface WatermarkFontType {
color?: string;
fontSize?: number | string;
fontWeight?: 'normal' | 'light' | 'weight' | number;
fontStyle?: 'none' | 'normal' | 'italic' | 'oblique';
fontFamily?: string;
textAlign?: 'start' | 'end' | 'left' | 'right' | 'center';
textBaseline?: 'top' | 'hanging' | 'middle' | 'alphabetic' | 'ideographic' | 'bottom';
}
export declare const watermarkProps: {
readonly zIndex: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, 9, boolean>;
readonly rotate: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, -22, boolean>;
readonly width: NumberConstructor;
readonly height: NumberConstructor;
readonly image: StringConstructor;
readonly content: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => string | string[]) | (() => string | string[]) | ((new (...args: any[]) => string | string[]) | (() => string | string[]))[], unknown, unknown, "Element Plus", boolean>;
readonly font: {
readonly type: import("vue").PropType<WatermarkFontType>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly gap: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => [number, number]) | (() => [number, number]) | ((new (...args: any[]) => [number, number]) | (() => [number, number]))[], unknown, unknown, () => number[], boolean>;
readonly offset: {
readonly type: import("vue").PropType<[number, number]>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
};
export type WatermarkProps = ExtractPropTypes<typeof watermarkProps>;
export type WatermarkPropsPublic = __ExtractPublicPropTypes<typeof watermarkProps>;
export type WatermarkInstance = InstanceType<typeof Watermark> & unknown;

View File

@@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var runtime = require('../../../utils/vue/props/runtime.js');
const watermarkProps = runtime.buildProps({
zIndex: {
type: Number,
default: 9
},
rotate: {
type: Number,
default: -22
},
width: Number,
height: Number,
image: String,
content: {
type: runtime.definePropType([String, Array]),
default: "Element Plus"
},
font: {
type: runtime.definePropType(Object)
},
gap: {
type: runtime.definePropType(Array),
default: () => [100, 100]
},
offset: {
type: runtime.definePropType(Array)
}
});
exports.watermarkProps = watermarkProps;
//# sourceMappingURL=watermark.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"watermark.js","sources":["../../../../../../packages/components/watermark/src/watermark.ts"],"sourcesContent":["import { buildProps, definePropType } from '@element-plus/utils'\n\nimport type { ExtractPropTypes, __ExtractPublicPropTypes } from 'vue'\nimport type Watermark from './watermark.vue'\n\nexport interface WatermarkFontType {\n color?: string\n fontSize?: number | string\n fontWeight?: 'normal' | 'light' | 'weight' | number\n fontStyle?: 'none' | 'normal' | 'italic' | 'oblique'\n fontFamily?: string\n textAlign?: 'start' | 'end' | 'left' | 'right' | 'center'\n textBaseline?:\n | 'top'\n | 'hanging'\n | 'middle'\n | 'alphabetic'\n | 'ideographic'\n | 'bottom'\n}\n\nexport const watermarkProps = buildProps({\n /**\n * @description The z-index of the appended watermark element\n */\n zIndex: {\n type: Number,\n default: 9,\n },\n /**\n * @description The rotation angle of the watermark\n */\n rotate: {\n type: Number,\n default: -22,\n },\n /**\n * @description The width of the watermark\n */\n width: Number,\n /**\n * @description The height of the watermark\n */\n height: Number,\n /**\n * @description Image source, it is recommended to export 2x or 3x image, high priority (support base64 format)\n */\n image: String,\n /**\n * @description Watermark text content\n */\n content: {\n type: definePropType<string | string[]>([String, Array]),\n default: 'Element Plus',\n },\n /**\n * @description Text style\n */\n font: {\n type: definePropType<WatermarkFontType>(Object),\n },\n /**\n * @description The spacing between watermarks\n */\n gap: {\n type: definePropType<[number, number]>(Array),\n default: () => [100, 100],\n },\n /**\n * @description The offset of the watermark from the upper left corner of the container. The default is gap/2\n */\n offset: {\n type: definePropType<[number, number]>(Array),\n },\n} as const)\n\nexport type WatermarkProps = ExtractPropTypes<typeof watermarkProps>\nexport type WatermarkPropsPublic = __ExtractPublicPropTypes<\n typeof watermarkProps\n>\nexport type WatermarkInstance = InstanceType<typeof Watermark> & unknown\n"],"names":["buildProps","definePropType"],"mappings":";;;;;;AACY,MAAC,cAAc,GAAGA,kBAAU,CAAC;AACzC,EAAE,MAAM,EAAE;AACV,IAAI,IAAI,EAAE,MAAM;AAChB,IAAI,OAAO,EAAE,CAAC;AACd,GAAG;AACH,EAAE,MAAM,EAAE;AACV,IAAI,IAAI,EAAE,MAAM;AAChB,IAAI,OAAO,EAAE,CAAC,EAAE;AAChB,GAAG;AACH,EAAE,KAAK,EAAE,MAAM;AACf,EAAE,MAAM,EAAE,MAAM;AAChB,EAAE,KAAK,EAAE,MAAM;AACf,EAAE,OAAO,EAAE;AACX,IAAI,IAAI,EAAEC,sBAAc,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACzC,IAAI,OAAO,EAAE,cAAc;AAC3B,GAAG;AACH,EAAE,IAAI,EAAE;AACR,IAAI,IAAI,EAAEA,sBAAc,CAAC,MAAM,CAAC;AAChC,GAAG;AACH,EAAE,GAAG,EAAE;AACP,IAAI,IAAI,EAAEA,sBAAc,CAAC,KAAK,CAAC;AAC/B,IAAI,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC;AAC7B,GAAG;AACH,EAAE,MAAM,EAAE;AACV,IAAI,IAAI,EAAEA,sBAAc,CAAC,KAAK,CAAC;AAC/B,GAAG;AACH,CAAC;;;;"}

View File

@@ -0,0 +1,56 @@
declare function __VLS_template(): {
default?(_: {}): any;
};
declare const __VLS_component: import("vue").DefineComponent<{
readonly zIndex: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, 9, boolean>;
readonly rotate: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, -22, boolean>;
readonly width: NumberConstructor;
readonly height: NumberConstructor;
readonly image: StringConstructor;
readonly content: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => string | string[]) | (() => string | string[]) | ((new (...args: any[]) => string | string[]) | (() => string | string[]))[], unknown, unknown, "Element Plus", boolean>;
readonly font: {
readonly type: import("vue").PropType<import("./watermark").WatermarkFontType>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly gap: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => [number, number]) | (() => [number, number]) | ((new (...args: any[]) => [number, number]) | (() => [number, number]))[], unknown, unknown, () => number[], boolean>;
readonly offset: {
readonly type: import("vue").PropType<[number, number]>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
readonly zIndex: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, 9, boolean>;
readonly rotate: import("element-plus/es/utils").EpPropFinalized<NumberConstructor, unknown, unknown, -22, boolean>;
readonly width: NumberConstructor;
readonly height: NumberConstructor;
readonly image: StringConstructor;
readonly content: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => string | string[]) | (() => string | string[]) | ((new (...args: any[]) => string | string[]) | (() => string | string[]))[], unknown, unknown, "Element Plus", boolean>;
readonly font: {
readonly type: import("vue").PropType<import("./watermark").WatermarkFontType>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly gap: import("element-plus/es/utils").EpPropFinalized<(new (...args: any[]) => [number, number]) | (() => [number, number]) | ((new (...args: any[]) => [number, number]) | (() => [number, number]))[], unknown, unknown, () => number[], boolean>;
readonly offset: {
readonly type: import("vue").PropType<[number, number]>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
}>>, {
readonly content: import("element-plus/es/utils").EpPropMergeType<(new (...args: any[]) => string | string[]) | (() => string | string[]) | ((new (...args: any[]) => string | string[]) | (() => string | string[]))[], unknown, unknown>;
readonly rotate: number;
readonly zIndex: number;
readonly gap: [number, number];
}>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
};
};

View File

@@ -0,0 +1,230 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var core = require('@vueuse/core');
var watermark = require('./watermark.js');
var utils = require('./utils.js');
var useClips = require('./useClips.js');
var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js');
var shared = require('@vue/shared');
var types = require('../../../utils/types.js');
const __default__ = vue.defineComponent({
name: "ElWatermark"
});
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
...__default__,
props: watermark.watermarkProps,
setup(__props) {
const props = __props;
const style = {
position: "relative"
};
const color = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.color) != null ? _b : "rgba(0,0,0,.15)";
});
const fontSize = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.fontSize) != null ? _b : 16;
});
const fontWeight = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.fontWeight) != null ? _b : "normal";
});
const fontStyle = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.fontStyle) != null ? _b : "normal";
});
const fontFamily = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.fontFamily) != null ? _b : "sans-serif";
});
const textAlign = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.textAlign) != null ? _b : "center";
});
const textBaseline = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.font) == null ? void 0 : _a.textBaseline) != null ? _b : "hanging";
});
const gapX = vue.computed(() => props.gap[0]);
const gapY = vue.computed(() => props.gap[1]);
const gapXCenter = vue.computed(() => gapX.value / 2);
const gapYCenter = vue.computed(() => gapY.value / 2);
const offsetLeft = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.offset) == null ? void 0 : _a[0]) != null ? _b : gapXCenter.value;
});
const offsetTop = vue.computed(() => {
var _a, _b;
return (_b = (_a = props.offset) == null ? void 0 : _a[1]) != null ? _b : gapYCenter.value;
});
const getMarkStyle = () => {
const markStyle = {
zIndex: props.zIndex,
position: "absolute",
left: 0,
top: 0,
width: "100%",
height: "100%",
pointerEvents: "none",
backgroundRepeat: "repeat"
};
let positionLeft = offsetLeft.value - gapXCenter.value;
let positionTop = offsetTop.value - gapYCenter.value;
if (positionLeft > 0) {
markStyle.left = `${positionLeft}px`;
markStyle.width = `calc(100% - ${positionLeft}px)`;
positionLeft = 0;
}
if (positionTop > 0) {
markStyle.top = `${positionTop}px`;
markStyle.height = `calc(100% - ${positionTop}px)`;
positionTop = 0;
}
markStyle.backgroundPosition = `${positionLeft}px ${positionTop}px`;
return markStyle;
};
const containerRef = vue.shallowRef(null);
const watermarkRef = vue.shallowRef();
const stopObservation = vue.ref(false);
const destroyWatermark = () => {
if (watermarkRef.value) {
watermarkRef.value.remove();
watermarkRef.value = void 0;
}
};
const appendWatermark = (base64Url, markWidth) => {
var _a;
if (containerRef.value && watermarkRef.value) {
stopObservation.value = true;
watermarkRef.value.setAttribute("style", utils.getStyleStr({
...getMarkStyle(),
backgroundImage: `url('${base64Url}')`,
backgroundSize: `${Math.floor(markWidth)}px`
}));
(_a = containerRef.value) == null ? void 0 : _a.append(watermarkRef.value);
setTimeout(() => {
stopObservation.value = false;
});
}
};
const getMarkSize = (ctx) => {
let defaultWidth = 120;
let defaultHeight = 64;
let space = 0;
const { image, content, width, height, rotate } = props;
if (!image && ctx.measureText) {
ctx.font = `${Number(fontSize.value)}px ${fontFamily.value}`;
const contents = shared.isArray(content) ? content : [content];
let maxWidth = 0;
let maxHeight = 0;
contents.forEach((item) => {
const {
width: width2,
fontBoundingBoxAscent,
fontBoundingBoxDescent,
actualBoundingBoxAscent,
actualBoundingBoxDescent
} = ctx.measureText(item);
const height2 = types.isUndefined(fontBoundingBoxAscent) ? actualBoundingBoxAscent + actualBoundingBoxDescent : fontBoundingBoxAscent + fontBoundingBoxDescent;
if (width2 > maxWidth)
maxWidth = Math.ceil(width2);
if (height2 > maxHeight)
maxHeight = Math.ceil(height2);
});
defaultWidth = maxWidth;
defaultHeight = maxHeight * contents.length + (contents.length - 1) * useClips.FontGap;
const angle = Math.PI / 180 * Number(rotate);
space = Math.ceil(Math.abs(Math.sin(angle) * defaultHeight) / 2);
defaultWidth += space;
}
return [width != null ? width : defaultWidth, height != null ? height : defaultHeight, space];
};
const getClips = useClips["default"]();
const renderWatermark = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const image = props.image;
const content = props.content;
const rotate = props.rotate;
if (ctx) {
if (!watermarkRef.value) {
watermarkRef.value = document.createElement("div");
}
const ratio = utils.getPixelRatio();
const [markWidth, markHeight, space] = getMarkSize(ctx);
const drawCanvas = (drawContent) => {
const [textClips, clipWidth] = getClips(drawContent || "", rotate, ratio, markWidth, markHeight, {
color: color.value,
fontSize: fontSize.value,
fontStyle: fontStyle.value,
fontWeight: fontWeight.value,
fontFamily: fontFamily.value,
textAlign: textAlign.value,
textBaseline: textBaseline.value
}, gapX.value, gapY.value, space);
appendWatermark(textClips, clipWidth);
};
if (image) {
const img = new Image();
img.onload = () => {
drawCanvas(img);
};
img.onerror = () => {
drawCanvas(content);
};
img.crossOrigin = "anonymous";
img.referrerPolicy = "no-referrer";
img.src = image;
} else {
drawCanvas(content);
}
}
};
vue.onMounted(() => {
renderWatermark();
});
vue.watch(() => props, () => {
renderWatermark();
}, {
deep: true,
flush: "post"
});
vue.onBeforeUnmount(() => {
destroyWatermark();
});
const onMutate = (mutations) => {
if (stopObservation.value) {
return;
}
mutations.forEach((mutation) => {
if (utils.reRendering(mutation, watermarkRef.value)) {
destroyWatermark();
renderWatermark();
}
});
};
core.useMutationObserver(containerRef, onMutate, {
attributes: true,
subtree: true,
childList: true
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
ref_key: "containerRef",
ref: containerRef,
style: vue.normalizeStyle([style])
}, [
vue.renderSlot(_ctx.$slots, "default")
], 4);
};
}
});
var Watermark = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["__file", "watermark.vue"]]);
exports["default"] = Watermark;
//# sourceMappingURL=watermark2.js.map

File diff suppressed because one or more lines are too long

View File

View File

@@ -0,0 +1,3 @@
'use strict';
//# sourceMappingURL=css.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}

View File

View File

@@ -0,0 +1,3 @@
'use strict';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}