UNPKG

zarm

Version:

基于 React 的移动端UI库

216 lines (178 loc) 8.47 kB
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _regeneratorRuntime from "@babel/runtime/regenerator"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { createBEM } from '@zarm-design/bem'; import { useMutationObserverRef } from '../utils/hooks'; import { ConfigContext } from '../config-provider'; import { WATERMARK_DEFAULT_STYLES, TEXT_STYLE_DEFAULT, IMAGE_STYLE_DEFAULT, MARK_STYLE_DEFAULT } from './defaults'; import { draw, isContainNode, getUUID, compareUUID, plainStyle } from './utils'; import { noop } from '../utils'; var MUTATION_OBSERVER_CONFIG = { childList: true, subtree: true, attributeFilter: ['class', 'style', 'data-watermark'], attributeOldValue: true }; var WaterMark = function WaterMark(props) { var uuid = React.useRef(getUUID()); var className = props.className, text = props.text, image = props.image, mode = props.mode, monitor = props.monitor, children = props.children; var watermark = React.useRef(null); var _React$useState = React.useState(WATERMARK_DEFAULT_STYLES), _React$useState2 = _slicedToArray(_React$useState, 2), styles = _React$useState2[0], setStyels = _React$useState2[1]; var _React$useContext = React.useContext(ConfigContext), prefixCls = _React$useContext.prefixCls; var bem = createBEM('water-mark', { prefixCls: prefixCls }); var textStyle = _objectSpread(_objectSpread({}, TEXT_STYLE_DEFAULT), props.textStyle); var imageStyle = _objectSpread(_objectSpread({}, IMAGE_STYLE_DEFAULT), props.imageStyle); var markStyle = _objectSpread(_objectSpread({}, MARK_STYLE_DEFAULT), props.markStyle); var rerender = noop; var _useMutationObserverR = useMutationObserverRef(function (records, observer) { // 重置监听状态 var reset = function reset(target, cb) { if (!target) return; observer.disconnect(); cb === null || cb === void 0 ? void 0 : cb(); observer.observe(target, MUTATION_OBSERVER_CONFIG); }; records.forEach(function (record) { var type = record.type, target = record.target, attributeName = record.attributeName, addedNodes = record.addedNodes, removedNodes = record.removedNodes; var source = watermark.current; if (!source) return; // style 发生变化 // style 发生变化 if (type === 'attributes' && target.contains(source)) { var _watermark$current; attributeName === 'class' && (source === null || source === void 0 ? void 0 : source.removeAttribute('class')); attributeName === 'style' && rerender(); attributeName === 'data-watermark' && reset((_watermark$current = watermark.current) === null || _watermark$current === void 0 ? void 0 : _watermark$current.parentNode, function () { return source === null || source === void 0 ? void 0 : source.setAttribute('data-watermark', String(uuid.current)); }); } // 篡改节点标签名 // 篡改节点标签名 if (type === 'childList' && addedNodes.length) { var _element = Array.from(addedNodes).find(function (node) { return compareUUID(node, source); }); _element && target.removeChild(_element); } // 移除节点 // 移除节点 if (type === 'childList' && isContainNode(removedNodes, source)) { reset(target, function () { ReactDOM.unmountComponentAtNode(source); target.appendChild(source); }); } }); }, MUTATION_OBSERVER_CONFIG), _useMutationObserverR2 = _slicedToArray(_useMutationObserverR, 2), setNode = _useMutationObserverR2[1]; // 渲染水印 rerender = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var style, _watermark$current2, rest, _yield$draw, url, ratio, width, height; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: style = _objectSpread({}, WATERMARK_DEFAULT_STYLES); _context.prev = 1; rest = { text: text, image: image, textStyle: textStyle, imageStyle: imageStyle, markStyle: markStyle }; _context.next = 5; return draw(rest); case 5: _yield$draw = _context.sent; url = _yield$draw.url; ratio = _yield$draw.ratio; width = _yield$draw.width; height = _yield$draw.height; if (url) { _context.next = 12; break; } return _context.abrupt("return"); case 12: if (mode === 'repeat') { style.backgroundImage = "url(".concat(url, ")"); } else { style.backgroundImage = "url(".concat(url, "), url(").concat(url, ")"); style.backgroundRepeat = 'repeat, repeat'; style.backgroundPosition = "".concat(width / 2, "px ").concat(height / 2, "px, 0 0"); } style.backgroundSize = "".concat(width / ratio, "px"); setStyels(style); setNode(monitor ? (_watermark$current2 = watermark.current) === null || _watermark$current2 === void 0 ? void 0 : _watermark$current2.parentElement : null); _context.next = 21; break; case 18: _context.prev = 18; _context.t0 = _context["catch"](1); console.error(_context.t0.message); case 21: case "end": return _context.stop(); } } }, _callee, null, [[1, 18]]); })); return function rerender() { return _ref.apply(this, arguments); }; }(); var isContains = /*#__PURE__*/React.isValidElement(children); React.useEffect(function () { rerender(); }, [textStyle.color, textStyle.fontStyle, textStyle.fontWeight, textStyle.fontSize, textStyle.fontFamily, textStyle.fontVariant, textStyle.textAlign, textStyle.textBaseline, imageStyle.width, imageStyle.height, markStyle.width, markStyle.height, markStyle.rotate, markStyle.opacity, markStyle.gapX, markStyle.gapY, markStyle.offsetLeft, markStyle.offsetTop, text, image, mode, monitor, isContains]); var style = React.useMemo(function () { var properties = _objectSpread(_objectSpread({ zIndex: markStyle.zIndex }, styles), props.style); if (isContains) { properties.position = 'absolute'; } // 监视模式写入样式到节点 if (monitor && watermark.current) { var _watermark$current3; (_watermark$current3 = watermark.current) === null || _watermark$current3 === void 0 ? void 0 : _watermark$current3.setAttribute('style', plainStyle(properties)); } return properties; }, [markStyle.zIndex, monitor, styles, props.style, isContains]); var element = /*#__PURE__*/React.createElement("div", { ref: watermark, "data-watermark": uuid.current, style: style }); if (isContains) return /*#__PURE__*/React.createElement("div", { className: bem([className]) }, children, element); return element; }; WaterMark.displayName = 'WaterMark'; WaterMark.defaultProps = { textStyle: TEXT_STYLE_DEFAULT, imageStyle: IMAGE_STYLE_DEFAULT, markStyle: MARK_STYLE_DEFAULT, mode: 'interval', monitor: true }; export default WaterMark;