@ant-design/happy-work-theme
Version:
Ant Design happy work theme
182 lines (173 loc) • 6.68 kB
JavaScript
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)
});
}));
}