pageCorners.tsx 4.2 KB

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