UNPKG

@ant-design/happy-work-theme

Version:
182 lines (173 loc) 6.68 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import { TinyColor } from '@ctrl/tinycolor'; import classNames from 'classnames'; import { CSSMotionList } from 'rc-motion'; import raf from "rc-util/es/raf"; import * as React from 'react'; import useStyle, { TARGET_ATTR } from "./style"; var DOT_COUNT = 7; var DOT_COUNT_LG = 10; function inRange(x, y, left, top, right, bottom) { return x >= left && x <= right && y >= top && y <= bottom; } export default function DotEffect(_ref) { var hashId = _ref.hashId, target = _ref.target, token = _ref.token, onFinish = _ref.onFinish; var prefixCls = 'happy-wave'; var dotPrefixCls = "".concat(prefixCls, "-dot"); var _React$useState = React.useState(null), _React$useState2 = _slicedToArray(_React$useState, 2), dots = _React$useState2[0], setDots = _React$useState2[1]; var _React$useState3 = React.useState(0), _React$useState4 = _slicedToArray(_React$useState3, 2), left = _React$useState4[0], setLeft = _React$useState4[1]; var _React$useState5 = React.useState(0), _React$useState6 = _slicedToArray(_React$useState5, 2), top = _React$useState6[0], setTop = _React$useState6[1]; useStyle(prefixCls, hashId, token); var targetAttrName = "".concat(TARGET_ATTR, "-").concat(hashId); // ========================= Dots ========================= React.useEffect(function () { var id = raf(function () { if (['-dangerous', '-error'].some(function (skipCls) { return target.className.includes(skipCls); })) { return; } var rect = target.getBoundingClientRect(); var width = rect.width, height = rect.height; setLeft(rect.left + width / 2); setTop(rect.top + height / 2); setDots([]); var minSize = Math.min(width, height); var maxSize = Math.max(width, height); var halfMinSize = minSize / 2; var halfMaxSize = maxSize / 2; var halfWidth = width / 2; var halfHeight = height / 2; var OFFSET_MIN = 15; var OFFSET_MAX = 30; var halfOffsetMinWidth = halfWidth + OFFSET_MIN; var halfOffsetMinHeight = halfHeight + OFFSET_MIN; var halfOffsetMaxWidth = halfWidth + OFFSET_MAX; var halfOffsetMaxHeight = halfHeight + OFFSET_MAX; var dotCount = minSize >= 20 ? DOT_COUNT_LG : DOT_COUNT; // Delay to start dot motion setTimeout(function () { var offsetAngle = Math.random() * 360; // Color var colorPrimary = token.colorPrimary; var colorHsv = new TinyColor(colorPrimary).toHsv(); colorHsv.h -= 30; var colorPrimaryWeak = new TinyColor(colorHsv).toHexString(); setDots(new Array(dotCount).fill(null).map(function (_, index) { var rotate = 360 / dotCount; var randomAngle = offsetAngle + rotate * index; // Get start XY (Which should align the rect edge) var startX = 0; var startY = 0; for (var startDist = halfMinSize - 1; startDist <= halfMaxSize; startDist += 1) { var x = Math.cos(randomAngle * Math.PI / 180) * startDist; var y = Math.sin(randomAngle * Math.PI / 180) * startDist; if (!inRange(x, y, -halfWidth, -halfHeight, halfWidth, halfHeight)) { break; } startX = x; startY = y; } // Get end XY var endX = startX; var endY = startY; var endDist = halfMinSize; var endHalfWidth = Math.random() * (halfOffsetMaxWidth - halfOffsetMinWidth) + halfOffsetMinWidth; var 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)); var size = Math.random() * 3 + 3; if (height >= 20) { size = Math.random() * 4 + 6; } return { key: index + 1, startX: "".concat(startX, "px"), startY: "".concat(startY, "px"), endX: "".concat(endX, "px"), endY: "".concat(endY, "px"), startSize: "".concat(size, "px"), endSize: "".concat(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 function () { raf.cancel(id); }; }, []); // ======================== Clean ========================= React.useEffect(function () { var id = setTimeout(function () { target.removeAttribute(targetAttrName); onFinish(); }, 600); return function () { clearTimeout(id); }; }, []); // ======================== Render ======================== if (!dots) { return null; } return /*#__PURE__*/React.createElement("div", { className: classNames(prefixCls, hashId), style: { left: left, top: top } }, /*#__PURE__*/React.createElement(CSSMotionList, { component: false, keys: dots, motionAppear: true, motionName: "happy-in-out" }, function (_ref2) { var motionCls = _ref2.className, motionStyle = _ref2.style, key = _ref2.key, startX = _ref2.startX, startY = _ref2.startY, endX = _ref2.endX, endY = _ref2.endY, startSize = _ref2.startSize, endSize = _ref2.endSize, type = _ref2.type, color = _ref2.color; var name = "".concat(dotPrefixCls, "-").concat(key); var dotCls = classNames(dotPrefixCls, motionCls, name); // if (dotCls.includes('active')) { // debugger; // } var dotStyle = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "--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 ".concat(color); } return /*#__PURE__*/React.createElement("div", { className: dotCls, style: _objectSpread(_objectSpread({}, motionStyle), dotStyle) }); })); }