UNPKG

@ant-design/happy-work-theme

Version:
192 lines (182 loc) 6.11 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 = DotEffect; var _fastColor = require("@ant-design/fast-color"); var _clsx = require("clsx"); var _motion = require("@rc-component/motion"); var _raf = _interopRequireDefault(require("@rc-component/util/lib/raf")); var React = _interopRequireWildcard(require("react")); var _style = _interopRequireWildcard(require("./style")); const DOT_COUNT = 7; const DOT_COUNT_LG = 10; function inRange(x, y, left, top, right, bottom) { return x >= left && x <= right && y >= top && y <= bottom; } function DotEffect({ hashId, target, token, onFinish }) { const prefixCls = 'happy-wave'; const dotPrefixCls = `${prefixCls}-dot`; const [dots, setDots] = React.useState(null); const [left, setLeft] = React.useState(0); const [top, setTop] = React.useState(0); (0, _style.default)(prefixCls, hashId, token); const targetAttrName = `${_style.TARGET_ATTR}-${hashId}`; // ========================= Dots ========================= React.useEffect(() => { const id = (0, _raf.default)(() => { if (['-dangerous', '-error'].some(skipCls => target.className.includes(skipCls))) { return; } const rect = target.getBoundingClientRect(); const { width, height } = rect; setLeft(rect.left + width / 2); setTop(rect.top + height / 2); setDots([]); const minSize = Math.min(width, height); const maxSize = Math.max(width, height); const halfMinSize = minSize / 2; const halfMaxSize = maxSize / 2; const halfWidth = width / 2; const halfHeight = height / 2; const OFFSET_MIN = 15; const OFFSET_MAX = 30; const halfOffsetMinWidth = halfWidth + OFFSET_MIN; const halfOffsetMinHeight = halfHeight + OFFSET_MIN; const halfOffsetMaxWidth = halfWidth + OFFSET_MAX; const halfOffsetMaxHeight = halfHeight + OFFSET_MAX; const dotCount = minSize >= 20 ? DOT_COUNT_LG : DOT_COUNT; // Delay to start dot motion setTimeout(() => { const offsetAngle = Math.random() * 360; // Color const { colorPrimary } = token; const colorHsv = new _fastColor.FastColor(colorPrimary).toHsv(); colorHsv.h -= 30; const colorPrimaryWeak = new _fastColor.FastColor(colorHsv).toHexString(); setDots(new Array(dotCount).fill(null).map((_, index) => { const rotate = 360 / dotCount; const randomAngle = offsetAngle + rotate * index; // Get start XY (Which should align the rect edge) let startX = 0; let startY = 0; for (let startDist = halfMinSize - 1; startDist <= halfMaxSize; startDist += 1) { const x = Math.cos(randomAngle * Math.PI / 180) * startDist; const y = Math.sin(randomAngle * Math.PI / 180) * startDist; if (!inRange(x, y, -halfWidth, -halfHeight, halfWidth, halfHeight)) { break; } startX = x; startY = y; } // Get end XY let endX = startX; let endY = startY; let endDist = halfMinSize; const endHalfWidth = Math.random() * (halfOffsetMaxWidth - halfOffsetMinWidth) + halfOffsetMinWidth; const endHalfHeight = Math.random() * (halfOffsetMaxHeight - halfOffsetMinHeight) + halfOffsetMinHeight; do { endX = Math.cos(randomAngle * Math.PI / 180) * endDist; endY = Math.sin(randomAngle * Math.PI / 180) * endDist; endDist += 1; } while (inRange(endX, endY, -endHalfWidth, -endHalfHeight, endHalfWidth, endHalfHeight)); let size = Math.random() * 3 + 3; if (height >= 20) { size = Math.random() * 4 + 6; } return { key: index + 1, startX: `${startX}px`, startY: `${startY}px`, endX: `${endX}px`, endY: `${endY}px`, startSize: `${size}px`, endSize: `${Math.random() > 0.75 ? size : 0}px`, type: Math.random() > 0.6 ? 'outlined' : 'fill', color: Math.random() > 0.5 ? colorPrimary : colorPrimaryWeak }; })); }, 50); target.setAttribute(targetAttrName, 'true'); }); return () => { _raf.default.cancel(id); }; }, []); // ======================== Clean ========================= React.useEffect(() => { const id = setTimeout(() => { target.removeAttribute(targetAttrName); onFinish(); }, 600); return () => { clearTimeout(id); }; }, []); // ======================== Render ======================== if (!dots) { return null; } return /*#__PURE__*/React.createElement("div", { className: (0, _clsx.clsx)(prefixCls, hashId), style: { left, top } }, /*#__PURE__*/React.createElement(_motion.CSSMotionList, { component: false, keys: dots, motionAppear: true, motionName: "happy-in-out" }, ({ className: motionCls, style: motionStyle, key, startX, startY, endX, endY, startSize, endSize, type, color }) => { const name = `${dotPrefixCls}-${key}`; const dotCls = (0, _clsx.clsx)(dotPrefixCls, motionCls, name); // if (dotCls.includes('active')) { // debugger; // } const dotStyle = { [`--start-x`]: startX, [`--start-y`]: startY, [`--end-x`]: endX, [`--end-y`]: endY, [`--start-size`]: startSize, [`--end-size`]: endSize }; if (type === 'fill') { dotStyle['--background'] = color; } else { dotStyle['--border'] = `1px solid ${color}`; } return /*#__PURE__*/React.createElement("div", { className: dotCls, style: { ...motionStyle, ...dotStyle } }); })); }