UNPKG

acud

Version:

acg react 组件库

257 lines (255 loc) • 11.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _context = _interopRequireDefault(require("./context")); var _useClips = _interopRequireDefault(require("./useClips")); var _useRafDebounce = _interopRequireDefault(require("./useRafDebounce")); var _useWatermark3 = _interopRequireDefault(require("./useWatermark")); var _utils = require("./utils"); var _useMutateObserver = _interopRequireDefault(require("./hooks/useMutateObserver")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } /* eslint-disable no-undef */ /** * Only return `next` when size changed. * This is only used for elements compare, not a shallow equal! */ function getSizeDiff(prev, next) { return prev.size === next.size ? prev : next; } var DEFAULT_GAP_X = 100; var DEFAULT_GAP_Y = 100; var Watermark = function Watermark(props, ref) { var _a, _b; var _props$zIndex = props.zIndex, zIndex = _props$zIndex === void 0 ? 9 : _props$zIndex, _props$rotate = props.rotate, rotate = _props$rotate === void 0 ? -22 : _props$rotate, width = props.width, height = props.height, image = props.image, content = props.content, _props$font = props.font, font = _props$font === void 0 ? {} : _props$font, style = props.style, className = props.className, rootClassName = props.rootClassName, _props$gap = props.gap, gap = _props$gap === void 0 ? [DEFAULT_GAP_X, DEFAULT_GAP_Y] : _props$gap, offset = props.offset, children = props.children, propsContainer = props.container, _props$inherit = props.inherit, inherit = _props$inherit === void 0 ? true : _props$inherit; var _font$color = font.color, color = _font$color === void 0 ? '#ccc' : _font$color, _font$fontSize = font.fontSize, fontSize = _font$fontSize === void 0 ? 14 : _font$fontSize, _font$fontGap = font.fontGap, fontGap = _font$fontGap === void 0 ? 3 : _font$fontGap, _font$alpha = font.alpha, alpha = _font$alpha === void 0 ? 1 : _font$alpha, _font$fontWeight = font.fontWeight, fontWeight = _font$fontWeight === void 0 ? 'normal' : _font$fontWeight, _font$fontStyle = font.fontStyle, fontStyle = _font$fontStyle === void 0 ? 'normal' : _font$fontStyle, _font$fontFamily = font.fontFamily, fontFamily = _font$fontFamily === void 0 ? 'sans-serif' : _font$fontFamily, _font$textAlign = font.textAlign, textAlign = _font$textAlign === void 0 ? 'center' : _font$textAlign; var _gap = (0, _slicedToArray2["default"])(gap, 2), _gap$ = _gap[0], gapX = _gap$ === void 0 ? DEFAULT_GAP_X : _gap$, _gap$2 = _gap[1], gapY = _gap$2 === void 0 ? DEFAULT_GAP_Y : _gap$2; var gapXCenter = gapX / 2; var gapYCenter = gapY / 2; var offsetLeft = (_a = offset === null || offset === void 0 ? void 0 : offset[0]) !== null && _a !== void 0 ? _a : gapXCenter; var offsetTop = (_b = offset === null || offset === void 0 ? void 0 : offset[1]) !== null && _b !== void 0 ? _b : gapYCenter; var markStyle = _react["default"].useMemo(function () { var mergedStyle = { zIndex: zIndex, position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', pointerEvents: 'none', backgroundRepeat: 'repeat' }; /** Calculate the style of the offset */ var positionLeft = offsetLeft - gapXCenter; var positionTop = offsetTop - gapYCenter; if (positionLeft > 0) { mergedStyle.left = "".concat(positionLeft, "px"); mergedStyle.width = "calc(100% - ".concat(positionLeft, "px)"); positionLeft = 0; } if (positionTop > 0) { mergedStyle.top = "".concat(positionTop, "px"); mergedStyle.height = "calc(100% - ".concat(positionTop, "px)"); positionTop = 0; } mergedStyle.backgroundPosition = "".concat(positionLeft, "px ").concat(positionTop, "px"); return mergedStyle; }, [zIndex, offsetLeft, gapXCenter, offsetTop, gapYCenter]); var _React$useState = _react["default"].useState(propsContainer), _React$useState2 = (0, _slicedToArray2["default"])(_React$useState, 2), container = _React$useState2[0], setContainer = _React$useState2[1]; // Used for nest case like Modal, Drawer var _React$useState3 = _react["default"].useState(new Set()), _React$useState4 = (0, _slicedToArray2["default"])(_React$useState3, 2), subElements = _React$useState4[0], setSubElements = _React$useState4[1]; // Nest elements should also support watermark var targetElements = _react["default"].useMemo(function () { var list = container ? [container] : []; return [].concat(list, (0, _toConsumableArray2["default"])(Array.from(subElements))); }, [container, subElements]); // ============================ Content ============================= /** * Get the width and height of the watermark. The default values are as follows * Image: [120, 64]; Content: It's calculated by content; */ var getMarkSize = function getMarkSize(ctx) { var defaultWidth = 120; var defaultHeight = 64; if (!image && ctx.measureText) { ctx.font = "".concat(Number(fontSize), "px ").concat(fontFamily); var contents = Array.isArray(content) ? content : [content]; var sizes = contents.map(function (item) { var metrics = ctx.measureText(item); return [metrics.width, metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent]; }); defaultWidth = Math.ceil(Math.max.apply(Math, (0, _toConsumableArray2["default"])(sizes.map(function (size) { return size[0]; })))); defaultHeight = Math.ceil(Math.max.apply(Math, (0, _toConsumableArray2["default"])(sizes.map(function (size) { return size[1]; })))) * contents.length + (contents.length - 1) * fontGap; } return [width !== null && width !== void 0 ? width : defaultWidth, height !== null && height !== void 0 ? height : defaultHeight]; }; var getClips = (0, _useClips["default"])(); var _React$useState5 = _react["default"].useState(null), _React$useState6 = (0, _slicedToArray2["default"])(_React$useState5, 2), watermarkInfo = _React$useState6[0], setWatermarkInfo = _React$useState6[1]; // Generate new Watermark content var renderWatermark = function renderWatermark() { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); if (ctx) { var ratio = (0, _utils.getPixelRatio)(); var _getMarkSize = getMarkSize(ctx), _getMarkSize2 = (0, _slicedToArray2["default"])(_getMarkSize, 2), markWidth = _getMarkSize2[0], markHeight = _getMarkSize2[1]; var drawCanvas = function drawCanvas(drawContent) { var _getClips = getClips(drawContent || '', rotate, ratio, markWidth, markHeight, { color: color, fontSize: fontSize, fontGap: fontGap, alpha: alpha, fontStyle: fontStyle, fontWeight: fontWeight, fontFamily: fontFamily, textAlign: textAlign }, gapX, gapY), _getClips2 = (0, _slicedToArray2["default"])(_getClips, 2), nextClips = _getClips2[0], clipWidth = _getClips2[1]; setWatermarkInfo([nextClips, clipWidth]); }; if (image) { var img = new Image(); img.onload = function () { drawCanvas(img); }; img.onerror = function () { drawCanvas(content); }; img.crossOrigin = 'anonymous'; img.referrerPolicy = 'no-referrer'; img.src = image; } else { drawCanvas(content); } } }; var syncWatermark = (0, _useRafDebounce["default"])(renderWatermark); // ============================= Effect ============================= // Append watermark to the container var _useWatermark = (0, _useWatermark3["default"])(markStyle), _useWatermark2 = (0, _slicedToArray2["default"])(_useWatermark, 3), appendWatermark = _useWatermark2[0], removeWatermark = _useWatermark2[1], isWatermarkEle = _useWatermark2[2]; (0, _react.useEffect)(function () { if (watermarkInfo) { targetElements.forEach(function (holder) { appendWatermark(watermarkInfo[0], watermarkInfo[1], holder); }); } }, [watermarkInfo, targetElements]); // ============================ Observe ============================= var onMutate = function onMutate(mutations) { mutations.forEach(function (mutation) { if ((0, _utils.reRendering)(mutation, isWatermarkEle)) { syncWatermark(); } }); }; (0, _useMutateObserver["default"])(targetElements, onMutate); (0, _react.useEffect)(syncWatermark, [rotate, zIndex, width, height, image, content, color, fontSize, fontGap, alpha, fontWeight, fontStyle, fontFamily, textAlign, gapX, gapY, offsetLeft, offsetTop]); // ============================ Context ============================= var watermarkContext = _react["default"].useMemo(function () { return { add: function add(ele) { setSubElements(function (prev) { var clone = new Set(prev); clone.add(ele); return getSizeDiff(prev, clone); }); }, remove: function remove(ele) { removeWatermark(ele); setSubElements(function (prev) { var clone = new Set(prev); clone["delete"](ele); return getSizeDiff(prev, clone); }); } }; }, []); // ============================= Render ============================= var childNode = inherit ? /*#__PURE__*/_react["default"].createElement(_context["default"].Provider, { value: watermarkContext }, children) : children; (0, _react.useImperativeHandle)(ref, function () { return watermarkContext; }); if (propsContainer) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null); } return /*#__PURE__*/_react["default"].createElement("div", { ref: setContainer, className: (0, _classnames["default"])(className, rootClassName), style: (0, _extends2["default"])({ position: 'relative' }, style) }, childNode); }; if (process.env.NODE_ENV !== 'production') { Watermark.displayName = 'Watermark'; } var _default = exports["default"] = /*#__PURE__*/(0, _react.forwardRef)(Watermark);