pageCorners.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import {HTMLAttributes} from 'react';
  2. import styled from '@emotion/styled';
  3. import {AnimationControls, motion} from 'framer-motion';
  4. import testableTransition from 'sentry/utils/testableTransition';
  5. type Props = {
  6. animateVariant: AnimationControls;
  7. } & HTMLAttributes<HTMLDivElement>;
  8. function PageCorners({animateVariant, ...rest}: Props) {
  9. return (
  10. <Container {...rest}>
  11. <TopRight
  12. key="tr"
  13. width="874"
  14. height="203"
  15. viewBox="0 0 874 203"
  16. fill="none"
  17. xmlns="http://www.w3.org/2000/svg"
  18. animate={animateVariant}
  19. >
  20. <path
  21. d="M36.5 0H874v203l-288.7-10-7-114-180.2-4.8-3.6-35.2-351.1 2.5L36.5 0z"
  22. fill="currentColor"
  23. />
  24. <path
  25. d="M535.5 111.5v-22l31.8 1 .7 21.5-32.5-.5zM4 43.5L0 21.6 28.5 18l4.2 24.7-28.7.8z"
  26. fill="currentColor"
  27. />
  28. </TopRight>
  29. <BottomLeft
  30. key="bl"
  31. width="494"
  32. height="141"
  33. viewBox="0 0 494 141"
  34. fill="none"
  35. xmlns="http://www.w3.org/2000/svg"
  36. animate={animateVariant}
  37. >
  38. <path d="M494 141H-1V7l140-7v19h33l5 82 308 4 9 36z" fill="currentColor" />
  39. <path d="M219 88h-30l-1-19 31 3v16z" fill="currentColor" />
  40. </BottomLeft>
  41. <TopLeft
  42. key="tl"
  43. width="414"
  44. height="118"
  45. fill="none"
  46. xmlns="http://www.w3.org/2000/svg"
  47. animate={animateVariant}
  48. >
  49. <path
  50. fillRule="evenodd"
  51. clipRule="evenodd"
  52. d="M414 0H0v102h144l5-69 257-3 8-30zM0 112v-10h117v16L0 112z"
  53. fill="currentColor"
  54. />
  55. <path d="M184 44h-25l-1 16 26-2V44z" fill="currentColor" />
  56. </TopLeft>
  57. <BottomRight
  58. key="br"
  59. width="650"
  60. height="151"
  61. fill="none"
  62. xmlns="http://www.w3.org/2000/svg"
  63. animate={animateVariant}
  64. >
  65. <path
  66. fillRule="evenodd"
  67. clipRule="evenodd"
  68. d="M27 151h623V0L435 7l-5 85-134 4-3 26-261-2-5 31z"
  69. fill="currentColor"
  70. />
  71. <path d="M398 68v16h24l1-16h-25zM3 119l-3 16 21 3 3-19H3z" fill="currentColor" />
  72. </BottomRight>
  73. </Container>
  74. );
  75. }
  76. export default PageCorners;
  77. const transition = testableTransition({
  78. type: 'spring',
  79. duration: 0.8,
  80. });
  81. const TopLeft = styled(motion.svg)`
  82. position: absolute;
  83. top: 0;
  84. left: 0;
  85. `;
  86. TopLeft.defaultProps = {
  87. initial: {x: '-40px', opacity: 0, originX: 0, originY: 0, scale: 'var(--corner-scale)'},
  88. variants: {
  89. none: {x: '-40px', opacity: 0},
  90. 'top-right': {x: '-40px', opacity: 0},
  91. 'top-left': {x: 0, opacity: 1},
  92. },
  93. transition,
  94. };
  95. const TopRight = styled(motion.svg)`
  96. position: absolute;
  97. top: 0;
  98. right: 0;
  99. `;
  100. TopRight.defaultProps = {
  101. initial: {
  102. x: '40px',
  103. opacity: 0,
  104. originX: '100%',
  105. originY: 0,
  106. scale: 'var(--corner-scale)',
  107. },
  108. variants: {
  109. none: {x: '40px', opacity: 0},
  110. 'top-left': {x: '40px', opacity: 0},
  111. 'top-right': {x: 0, opacity: 1},
  112. },
  113. transition,
  114. };
  115. const BottomLeft = styled(motion.svg)`
  116. position: absolute;
  117. bottom: 0;
  118. left: 0;
  119. `;
  120. BottomLeft.defaultProps = {
  121. initial: {
  122. x: '-40px',
  123. opacity: 0,
  124. originX: 0,
  125. originY: '100%',
  126. scale: 'var(--corner-scale)',
  127. },
  128. variants: {
  129. none: {x: '-40px', opacity: 0},
  130. 'top-left': {x: '-40px', opacity: 0},
  131. 'top-right': {x: 0, opacity: 1},
  132. },
  133. transition,
  134. };
  135. const BottomRight = styled(motion.svg)`
  136. position: absolute;
  137. bottom: 0;
  138. right: 0;
  139. `;
  140. BottomRight.defaultProps = {
  141. initial: {
  142. x: '40px',
  143. opacity: 0,
  144. originX: '100%',
  145. originY: '100%',
  146. scale: 'var(--corner-scale)',
  147. },
  148. variants: {
  149. none: {x: '40px', opacity: 0},
  150. 'top-right': {x: '40px', opacity: 0},
  151. 'top-left': {x: 0, opacity: 1},
  152. },
  153. transition,
  154. };
  155. const Container = styled('div')`
  156. pointer-events: none;
  157. position: absolute;
  158. top: 0;
  159. left: 0;
  160. right: 0;
  161. bottom: 0;
  162. color: ${p => p.theme.purple200};
  163. opacity: 0.4;
  164. `;