roundedArrow.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { unit } from '@ant-design/cssinjs';
  2. export function getArrowToken(token) {
  3. const {
  4. sizePopupArrow,
  5. borderRadiusXS,
  6. borderRadiusOuter
  7. } = token;
  8. const unitWidth = sizePopupArrow / 2;
  9. const ax = 0;
  10. const ay = unitWidth;
  11. const bx = borderRadiusOuter * 1 / Math.sqrt(2);
  12. const by = unitWidth - borderRadiusOuter * (1 - 1 / Math.sqrt(2));
  13. const cx = unitWidth - borderRadiusXS * (1 / Math.sqrt(2));
  14. const cy = borderRadiusOuter * (Math.sqrt(2) - 1) + borderRadiusXS * (1 / Math.sqrt(2));
  15. const dx = 2 * unitWidth - cx;
  16. const dy = cy;
  17. const ex = 2 * unitWidth - bx;
  18. const ey = by;
  19. const fx = 2 * unitWidth - ax;
  20. const fy = ay;
  21. const shadowWidth = unitWidth * Math.sqrt(2) + borderRadiusOuter * (Math.sqrt(2) - 2);
  22. const polygonOffset = borderRadiusOuter * (Math.sqrt(2) - 1);
  23. const arrowPolygon = `polygon(${polygonOffset}px 100%, 50% ${polygonOffset}px, ${2 * unitWidth - polygonOffset}px 100%, ${polygonOffset}px 100%)`;
  24. const arrowPath = `path('M ${ax} ${ay} A ${borderRadiusOuter} ${borderRadiusOuter} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${borderRadiusXS} ${borderRadiusXS} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${borderRadiusOuter} ${borderRadiusOuter} 0 0 0 ${fx} ${fy} Z')`;
  25. return {
  26. arrowShadowWidth: shadowWidth,
  27. arrowPath,
  28. arrowPolygon
  29. };
  30. }
  31. export const genRoundedArrow = (token, bgColor, boxShadow) => {
  32. const {
  33. sizePopupArrow,
  34. arrowPolygon,
  35. arrowPath,
  36. arrowShadowWidth,
  37. borderRadiusXS,
  38. calc
  39. } = token;
  40. return {
  41. pointerEvents: 'none',
  42. width: sizePopupArrow,
  43. height: sizePopupArrow,
  44. overflow: 'hidden',
  45. '&::before': {
  46. position: 'absolute',
  47. bottom: 0,
  48. insetInlineStart: 0,
  49. width: sizePopupArrow,
  50. height: calc(sizePopupArrow).div(2).equal(),
  51. background: bgColor,
  52. clipPath: {
  53. _multi_value_: true,
  54. value: [arrowPolygon, arrowPath]
  55. },
  56. content: '""'
  57. },
  58. '&::after': {
  59. content: '""',
  60. position: 'absolute',
  61. width: arrowShadowWidth,
  62. height: arrowShadowWidth,
  63. bottom: 0,
  64. insetInline: 0,
  65. margin: 'auto',
  66. borderRadius: {
  67. _skip_check_: true,
  68. value: `0 0 ${unit(borderRadiusXS)} 0`
  69. },
  70. transform: 'translateY(50%) rotate(-135deg)',
  71. boxShadow,
  72. zIndex: 0,
  73. background: 'transparent'
  74. }
  75. };
  76. };