@ant-design/happy-work-theme
Version:
Ant Design happy work theme
190 lines (180 loc) • 7.38 kB
JavaScript
"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 _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _tinycolor = require("@ctrl/tinycolor");
var _classnames = _interopRequireDefault(require("classnames"));
var _rcMotion = require("rc-motion");
var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
var React = _interopRequireWildcard(require("react"));
var _style = _interopRequireWildcard(require("./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;
}
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 = (0, _slicedToArray2.default)(_React$useState, 2),
dots = _React$useState2[0],
setDots = _React$useState2[1];
var _React$useState3 = React.useState(0),
_React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
left = _React$useState4[0],
setLeft = _React$useState4[1];
var _React$useState5 = React.useState(0),
_React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2),
top = _React$useState6[0],
setTop = _React$useState6[1];
(0, _style.default)(prefixCls, hashId, token);
var targetAttrName = "".concat(_style.TARGET_ATTR, "-").concat(hashId);
// ========================= Dots =========================
React.useEffect(function () {
var id = (0, _raf.default)(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.TinyColor(colorPrimary).toHsv();
colorHsv.h -= 30;
var colorPrimaryWeak = new _tinycolor.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.default.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: (0, _classnames.default)(prefixCls, hashId),
style: {
left: left,
top: top
}
}, /*#__PURE__*/React.createElement(_rcMotion.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 = (0, _classnames.default)(dotPrefixCls, motionCls, name);
// if (dotCls.includes('active')) {
// debugger;
// }
var dotStyle = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, "--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: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, motionStyle), dotStyle)
});
}));
}