roundedArrow.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. export const roundedArrow = (width, innerRadius, outerRadius, bgColor, boxShadow) => {
  2. const unitWidth = width / 2;
  3. const ax = 0;
  4. const ay = unitWidth;
  5. const bx = outerRadius * 1 / Math.sqrt(2);
  6. const by = unitWidth - outerRadius * (1 - 1 / Math.sqrt(2));
  7. const cx = unitWidth - innerRadius * (1 / Math.sqrt(2));
  8. const cy = outerRadius * (Math.sqrt(2) - 1) + innerRadius * (1 / Math.sqrt(2));
  9. const dx = 2 * unitWidth - cx;
  10. const dy = cy;
  11. const ex = 2 * unitWidth - bx;
  12. const ey = by;
  13. const fx = 2 * unitWidth - ax;
  14. const fy = ay;
  15. const shadowWidth = unitWidth * Math.sqrt(2) + outerRadius * (Math.sqrt(2) - 2);
  16. const polygonOffset = outerRadius * (Math.sqrt(2) - 1);
  17. return {
  18. pointerEvents: 'none',
  19. width,
  20. height: width,
  21. overflow: 'hidden',
  22. '&::after': {
  23. content: '""',
  24. position: 'absolute',
  25. width: shadowWidth,
  26. height: shadowWidth,
  27. bottom: 0,
  28. insetInline: 0,
  29. margin: 'auto',
  30. borderRadius: {
  31. _skip_check_: true,
  32. value: `0 0 ${innerRadius}px 0`
  33. },
  34. transform: 'translateY(50%) rotate(-135deg)',
  35. boxShadow,
  36. zIndex: 0,
  37. background: 'transparent'
  38. },
  39. '&::before': {
  40. position: 'absolute',
  41. bottom: 0,
  42. insetInlineStart: 0,
  43. width,
  44. height: width / 2,
  45. background: bgColor,
  46. clipPath: {
  47. _multi_value_: true,
  48. value: [`polygon(${polygonOffset}px 100%, 50% ${polygonOffset}px, ${2 * unitWidth - polygonOffset}px 100%, ${polygonOffset}px 100%)`, `path('M ${ax} ${ay} A ${outerRadius} ${outerRadius} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${innerRadius} ${innerRadius} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${outerRadius} ${outerRadius} 0 0 0 ${fx} ${fy} Z')`]
  49. },
  50. content: '""'
  51. }
  52. };
  53. };