UNPKG

yuang-framework-ui-pc

Version:

yuang-framework-ui-pc Library

203 lines (202 loc) 7.34 kB
"use strict"; const vue = require("vue"); const util = require("./util"); const props = require("./props"); const SIZE = 2; const _sfc_main = vue.defineComponent({ name: "EleWatermark", props: props.watermarkProps, setup(props2) { const { observe, disconnect } = util.useMutation({ getRoot: () => rootRef.value, getEl: () => imgRef.value, onDeleted: () => { disconnect(); rootKey.value = rootKey.value + 1; vue.nextTick(() => { render(); }); }, onDalsified: () => { render(); } }); const rootKey = vue.ref(1); const rootRef = vue.ref(null); const imgRef = vue.ref(null); const imgStyle = vue.ref({ display: "none" }); const updateStyle = (base64, size) => { const position = props2.fixed ? "fixed" : "absolute"; const width = props2.fixed ? "100vw" : "100%"; const height = props2.fixed ? "100vh" : "100%"; const style = { position: `${position} !important`, top: "0 !important", left: "0 !important", right: "auto !important", bottom: "auto !important", width: `${width} !important`, height: `${height} !important`, pointerEvents: "none !important", backgroundRepeat: "repeat !important", opacity: "1 !important", transform: "none !important", filter: "none !important", visibility: "visible !important", transition: "none !important", maxWidth: "none !important", maxHeight: "none !important", zoom: "1 !important", mask: "none !important", clipPath: "none !important", display: "block !important", ...props2.customStyle || {} }; if (!base64) { style.display = "none !important"; } else { style.backgroundImage = `url('${base64}') !important`; if (size) { style.backgroundSize = `${size} !important`; } style.zIndex = `${props2.zIndex ?? 2147483647} !important`; } disconnect(); if (imgRef.value && imgRef.value.style && imgRef.value.style.cssText) { imgRef.value.style.cssText = util.joinStyle(style); observe(); } else { imgStyle.value = style; vue.nextTick(() => { observe(); }); } }; const getDefaultWidth = (ctx) => { if (props2.image || !ctx.measureText) { return 120; } const content = props2.content; const contents = Array.isArray(content) ? content : [content]; const widths = contents.map((item) => ctx.measureText(item).width); return Math.ceil(Math.max(...widths)); }; const getDefaultHeight = (ctx) => { if (props2.image || !ctx.measureText) { return 64; } const lines = Array.isArray(props2.content) ? props2.content.length : 1; const { fontSize } = util.getFont(props2.font); return fontSize * lines + (lines - 1) * props2.lineGap; }; const getMarkSize = (ctx) => { const width = props2.width; const height = props2.height; return [width ?? getDefaultWidth(ctx), height ?? getDefaultHeight(ctx)]; }; const fillTexts = (ctx, drawX, drawY, drawWidth, drawHeight) => { const ratio = util.getPixelRatio(); const { color, fontSize, fontStyle, fontWeight, fontFamily } = util.getFont(props2.font); const mergedFontSize = fontSize * ratio; ctx.font = `${fontStyle} normal ${fontWeight} ${mergedFontSize}px/${drawHeight}px ${fontFamily}`; ctx.fillStyle = color; ctx.textAlign = "center"; ctx.textBaseline = "top"; ctx.translate(drawWidth / 2, 0); const content = props2.content; const contents = Array.isArray(content) ? content : [content]; contents.forEach((item, index2) => { ctx.fillText(item ?? "", drawX, drawY + index2 * (mergedFontSize + props2.lineGap * ratio)); }); }; const render = () => { if (props2.disabled) { disconnect(); imgStyle.value = { display: "none" }; return; } const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); if (!ctx) { return; } const rotate = props2.rotate ?? -22; if (!props2.image && ctx.measureText != null) { const { fontSize, fontFamily } = util.getFont(props2.font); ctx.font = `${fontSize}px ${fontFamily}`; } const [markWidth, markHeight] = getMarkSize(ctx); const ratio = util.getPixelRatio(); const [gapX, gapY] = util.getGap(props2.gap); const canvasWidth = (gapX + markWidth) * ratio; const canvasHeight = (gapY + markHeight) * ratio; canvas.setAttribute("width", `${canvasWidth * SIZE}px`); canvas.setAttribute("height", `${canvasHeight * SIZE}px`); const drawWidth = markWidth * ratio; const drawHeight = markHeight * ratio; const rotateX = (drawWidth + gapX * ratio) / 2; const rotateY = (drawHeight + gapY * ratio) / 2; ctx.save(); util.rotateWatermark(ctx, rotateX, rotateY, rotate); const drawX = gapX * ratio / 2; const drawY = gapY * ratio / 2; const alternateDrawX = drawX + canvasWidth; const alternateDrawY = drawY + canvasHeight; const alternateRotateX = rotateX + canvasWidth; const alternateRotateY = rotateY + canvasHeight; if (props2.image) { const img = new Image(); img.onload = () => { ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight); ctx.restore(); util.rotateWatermark(ctx, alternateRotateX, alternateRotateY, rotate); ctx.drawImage(img, alternateDrawX, alternateDrawY, drawWidth, drawHeight); updateStyle(canvas.toDataURL(), `${(gapX + markWidth) * SIZE}px`); }; img.crossOrigin = "anonymous"; img.referrerPolicy = "no-referrer"; img.src = props2.image; } else { fillTexts(ctx, drawX, drawY, drawWidth, drawHeight); ctx.restore(); util.rotateWatermark(ctx, alternateRotateX, alternateRotateY, rotate); fillTexts(ctx, alternateDrawX, alternateDrawY, drawWidth, drawHeight); updateStyle(canvas.toDataURL(), `${(gapX + markWidth) * SIZE}px`); } }; vue.onMounted(() => { render(); }); vue.watch( () => props2, () => { render(); }, { deep: true } ); return { rootKey, rootRef, imgRef, imgStyle }; } }); const _export_sfc = (sfc, props2) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props2) { target[key] = val; } return target; }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("div", { ref: "rootRef", key: _ctx.rootKey, style: vue.normalizeStyle(!_ctx.wrapPosition || _ctx.fixed ? void 0 : { position: "relative" }) }, [ vue.renderSlot(_ctx.$slots, "default"), !_ctx.disabled ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, ref: "imgRef", style: vue.normalizeStyle(_ctx.imgStyle) }, null, 4)) : vue.createCommentVNode("", true) ], 4); } const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); module.exports = index;