choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
294 lines (254 loc) • 10.8 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = require("react-dom");
var _isElement = _interopRequireDefault(require("lodash/isElement"));
var _classnames = _interopRequireDefault(require("classnames"));
var _ConfigContext = _interopRequireDefault(require("../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__*/(0, _react.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 _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,
_markStyle$opacity = markStyle.opacity,
opacity = _markStyle$opacity === void 0 ? 0.8 : _markStyle$opacity;
var _useContext = (0, _react.useContext)(_ConfigContext["default"]),
getPrefixCls = _useContext.getPrefixCls;
var prefixCls = getPrefixCls('watermark', customizePrefixCls);
var wrapperCls = (0, _classnames["default"])("".concat(prefixCls, "-wrapper"), className);
var waterMakrCls = (0, _classnames["default"])(prefixCls, markClassName);
var _useState = (0, _react.useState)(''),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
base64Url = _useState2[0],
setBase64Url = _useState2[1];
var wrapperRef = (0, _react.useRef)(null);
var waterMarkRef = (0, _react.useRef)();
var mutation = (0, _react.useRef)(null);
(0, _react.useEffect)(function () {
canvasWM(mutationObserver);
}, [enable, gapX, gapY, offsetLeft, offsetTop, rotate, width, height, image, content]);
(0, _react.useEffect)(function () {
if (wrapperRef.current && !removeable && enable) {
var wrapperDom = getContainer && (0, _isElement["default"])(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 && (0, _isElement["default"])(getContainer()) ? getContainer() : wrapperRef.current; // 监听浏览器控制台样式变化
var styleStr = "position: absolute !important; left: 0px !important; top: 0px !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(opacity, " !important; visibility: visible !important; display: block !important; transform: scale(1) !important;");
var MutationObserver = window.MutationObserver;
if (mutation.current) {
mutation.current.disconnect();
mutation.current = null;
}
if (MutationObserver && !mutation.current) {
mutation.current = new MutationObserver(function (mutationsList) {
var wmInstance = wrapperDom.querySelector(".".concat(prefixCls));
var newStyle = wmInstance && wmInstance.getAttribute('style');
var observe = mutationsList.find(function (_ref) {
var target = _ref.target;
return target && target.contains(wmInstance) || target.contains(wrapperDom);
});
if (observe && wmInstance && newStyle !== styleStr) {
wmInstance.setAttribute('style', styleStr);
}
});
mutation.current.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);
callback(canvas.toDataURL());
setBase64Url(canvas.toDataURL());
};
} else if (content) {
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(_ref2) {
var content = _ref2.content,
ctx = _ref2.ctx,
canvasWidth = _ref2.canvasWidth,
markHeight = _ref2.markHeight,
fontHeight = _ref2.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 = (0, _react.useMemo)(function () {
return enable ? /*#__PURE__*/_react["default"].createElement('div', {
className: waterMakrCls,
ref: waterMarkRef.current ? waterMarkRef : undefined,
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: opacity
}
}) : null;
}, [enable, waterMakrCls, gapX, width, base64Url, zIndex]);
var getWMContainer = (0, _react.useMemo)(function () {
var container = getContainer && getContainer();
if (container && (0, _isElement["default"])(container)) {
container.style.setProperty('position', container.style.position || 'relative');
return /*#__PURE__*/(0, _reactDom.createPortal)(renderCanvas, container);
}
return renderCanvas;
}, [getContainer, renderCanvas]);
return /*#__PURE__*/_react["default"].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
}
};
var _default = WaterMark;
exports["default"] = _default;
//# sourceMappingURL=WaterMark.js.map