UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

294 lines (254 loc) 10.8 kB
"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