choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
264 lines (233 loc) • 9.44 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { memo, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import isElement from 'lodash/isElement';
import classNames from 'classnames';
import ConfigContext from '../config-provider/ConfigContext';
/**
* 返回当前显示设备的物理像素分辨率与CSS像素分辨率之比
*
* @param context
*/
var getPixelRatio = function getPixelRatio(context) {
if (!context) {
return 1;
}
var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
var WaterMark = /*#__PURE__*/memo(function (props) {
var enable = props.enable,
removeable = props.removeable,
children = props.children,
className = props.className,
markClassName = props.markClassName,
zIndex = props.zIndex,
gapX = props.gapX,
gapY = props.gapY,
width = props.width,
height = props.height,
rotate = props.rotate,
image = props.image,
content = props.content,
offsetLeft = props.offsetLeft,
offsetTop = props.offsetTop,
markStyle = props.markStyle,
customizePrefixCls = props.prefixCls,
getContainer = props.getContainer;
var _useContext = useContext(ConfigContext),
getPrefixCls = _useContext.getPrefixCls;
var prefixCls = getPrefixCls('watermark', customizePrefixCls);
var wrapperCls = classNames("".concat(prefixCls, "-wrapper"), className);
var waterMakrCls = classNames(prefixCls, markClassName);
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
base64Url = _useState2[0],
setBase64Url = _useState2[1];
var wrapperRef = useRef(null);
useEffect(function () {
canvasWM(mutationObserver);
}, [enable, gapX, gapY, offsetLeft, offsetTop, rotate, width, height, image, content]);
useEffect(function () {
if (wrapperRef.current && !removeable && enable) {
var wrapperDom = getContainer && isElement(getContainer()) ? getContainer() : wrapperRef.current;
var appendChild = function appendChild(e) {
var event = e || window.event;
setTimeout(function () {
if (!wrapperDom.getElementsByClassName(prefixCls).length && event && event.target) {
wrapperDom.appendChild(event.target);
}
});
}; // 监听浏览器控制台强行移除节点
wrapperDom.addEventListener('DOMNodeRemoved', function (e) {
return appendChild(e);
});
return wrapperDom.removeEventListener('DOMNodeRemoved', function (e) {
return appendChild(e);
});
}
}, [wrapperRef, removeable, enable]);
var mutationObserver = function mutationObserver(imgSrc) {
if (wrapperRef.current && !removeable) {
var wrapperDom = getContainer && isElement(getContainer()) ? getContainer() : wrapperRef.current; // 监听浏览器控制台样式变化
var styleStr = "position: absolute !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;z-index:".concat(zIndex, " !important;pointer-events: none !important;background-repeat: repeat !important;background-size: ").concat(gapX + width, "px !important;background-image: url('").concat(imgSrc, "') !important;opacity:").concat(markStyle.opacity, " !important");
var MutationObserver = window.MutationObserver;
if (MutationObserver) {
var mo = new MutationObserver(function () {
var wmInstance = wrapperDom.querySelector(".".concat(prefixCls));
if (wmInstance && wmInstance.getAttribute('style') !== styleStr) {
wmInstance.setAttribute('style', styleStr); // 避免一直触发
mo.disconnect();
}
});
mo.observe(wrapperDom, {
attributes: true,
subtree: true,
childList: true
});
}
}
};
var canvasWM = function canvasWM(callback) {
if (enable) {
// 绘制水印
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var ratio = getPixelRatio(ctx);
var canvasWidth = "".concat((gapX + width) * ratio, "px");
var canvasHeight = "".concat((gapY + height) * ratio, "px");
var canvasOffsetLeft = offsetLeft || gapX / 2;
var canvasOffsetTop = offsetTop || gapY / 2;
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
if (ctx) {
// 旋转字符 rotate
var markWidth = width * ratio;
var markHeight = height * ratio; // 确定旋转中心
var centerX = markWidth / 2 + canvasOffsetLeft * ratio;
var centerY = markHeight / 2 + canvasOffsetTop * ratio;
ctx.translate(centerX, centerY);
ctx.rotate(Math.PI / 180 * Number(rotate));
if (image) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.src = image;
img.onload = function () {
ctx.drawImage(img, -markWidth / 2, -markHeight / 2, markWidth, markHeight);
setBase64Url(canvas.toDataURL());
callback(canvas.toDataURL());
};
} else if (content) {
var _markStyle$fontSize = markStyle.fontSize,
fontSize = _markStyle$fontSize === void 0 ? 16 : _markStyle$fontSize,
_markStyle$fontWeight = markStyle.fontWeight,
fontWeight = _markStyle$fontWeight === void 0 ? 'normal' : _markStyle$fontWeight,
_markStyle$fontFamily = markStyle.fontFamily,
fontFamily = _markStyle$fontFamily === void 0 ? 'sans-serif' : _markStyle$fontFamily,
_markStyle$color = markStyle.color,
color = _markStyle$color === void 0 ? 'rgba(0,0,0,.15)' : _markStyle$color,
_markStyle$fontStyle = markStyle.fontStyle,
fontStyle = _markStyle$fontStyle === void 0 ? 'normal' : _markStyle$fontStyle;
var markSize = Number(fontSize) * ratio;
ctx.font = "".concat(fontStyle, " normal ").concat(fontWeight, " ").concat(markSize, "px ").concat(fontFamily);
ctx.fillStyle = color; // 计算文本的长度
drawText({
content: content,
ctx: ctx,
canvasWidth: markWidth,
markHeight: markHeight,
fontHeight: markSize
});
setBase64Url(canvas.toDataURL());
callback(canvas.toDataURL());
}
} else {
console.error('当前环境不支持Canvas');
}
}
};
/**
*
* @param content 文本
* @param ctx 绘制上下文
* @param canvasWidth 绘制宽度
* @param markHeight 水印高度
* @param fontHeight 字体高度
*/
var drawText = function drawText(_ref) {
var content = _ref.content,
ctx = _ref.ctx,
canvasWidth = _ref.canvasWidth,
markHeight = _ref.markHeight,
fontHeight = _ref.fontHeight;
var lastSubStrIndex = 0;
var lineWidth = 0;
var initHeight = fontHeight;
for (var i = 0; i < content.length; i++) {
var _ctx$measureText = ctx.measureText(content[i]),
_width = _ctx$measureText.width;
lineWidth += _width;
if (lineWidth > canvasWidth - _width) {
ctx.fillText(content.substring(lastSubStrIndex, i), 0 - canvasWidth / 2, initHeight - markHeight / 2);
initHeight += fontHeight;
lineWidth = 0;
lastSubStrIndex = i;
}
if (i === content.length - 1) {
ctx.fillText(content.substring(lastSubStrIndex, i + 1), 0 - canvasWidth / 2, initHeight - markHeight / 2);
}
}
};
var renderCanvas = useMemo(function () {
return enable ? /*#__PURE__*/React.createElement('div', {
className: waterMakrCls,
style: {
position: 'absolute',
left: 0,
top: 0,
width: '100%',
height: '100%',
zIndex: zIndex,
pointerEvents: 'none',
backgroundRepeat: 'repeat',
backgroundSize: "".concat(gapX + width, "px"),
backgroundImage: "url('".concat(base64Url, "')"),
opacity: markStyle.opacity
}
}) : null;
}, [enable, waterMakrCls, gapX, width, base64Url, zIndex]);
var getWMContainer = useMemo(function () {
var container = getContainer && getContainer();
if (container && isElement(container)) {
container.style.setProperty('position', container.style.position || 'relative');
return /*#__PURE__*/createPortal(renderCanvas, container);
}
return renderCanvas;
}, [getContainer, renderCanvas]);
return /*#__PURE__*/React.createElement("div", {
className: wrapperCls,
ref: wrapperRef
}, children, getWMContainer);
});
WaterMark.displayName = 'WaterMark';
WaterMark.defaultProps = {
enable: true,
removeable: false,
zIndex: 9,
gapX: 212,
gapY: 222,
width: 120,
height: 64,
rotate: -22,
markStyle: {
fontStyle: 'normal',
fontWeight: 'normal',
color: 'rgba(0,0,0,.15)',
fontSize: 16,
fontFamily: 'sans-serif',
opacity: 0.8
}
};
export default WaterMark;
//# sourceMappingURL=WaterMark.js.map