import { FunctionComponent , ReactElement , useState , useEffect , useContext , } from 'react' ; import { AppContext } from '@weco/common/views/components/AppContext/AppContext' ; import debounce from 'lodash.debounce' ; import { prefixedPropertyStyleObject } from '../../../utils/prefixed-property-style-object' ; import styled from 'styled-components' ; const Edge = styled . div < { background : string ; isRotated : boolean ; isEnhanced : boolean ; } > `
  height: 10vw;
  margin-top: -10vw;
  position: relative;
  top: 2px;
  z-index: 2;
  transition: -webkit-clip-path 2000ms ease-in-out, clip-path 2000ms ease-in-out;
  display: none;

  @media (min-width: ${ props => props . theme . sizes . large }px) {
    max-height: 60px;
    margin-top: -60px;
  }

  ${ props => props . isEnhanced && `
    @supports ((clip-path: polygon(0 0)) or (-webkit-clip-path: polygon(0 0))) {
      display: block;

      @media screen and (prefers-reduced-motion: reduce) {
        display: none;
      }
    }
  ` }

  background: ${ props => props . theme . color ( props . background ) };

  ${ props => props . isRotated && `
    transform: rotate(180deg);
    margin-top: 0;
    top: -2px;

    @media (min-width: ${ props . theme . sizes . large }px) {
      margin-top: 0;
      top: -2px;
    }
  ` }
` ; function randomIntFromInterval ( min , max ) { return Math . floor ( Math . random ( ) * ( max - min + 1 ) + min ) ; } type Props = { background : string ; isRotated ? : boolean ; intensity ? : number ; points ? : number ; isValley ? : boolean ; isStatic ? : boolean ; } ; const WobblyEdge = ( { background , isRotated , intensity = 50 , points = 5 , isValley , isStatic , } ) : ReactElement => { const [ isActive , setIsActive ] = useState ( false ) ; const [ styleObject , setStyleObject ] = useState ( prefixedPropertyStyleObject ( 'clipPath' , makePolygonPoints ( 0 , 0 ) ) ) ; let timer ; const { isEnhanced } = useContext ( AppContext ) ; function makePolygonPoints ( totalPoints , intensity ) { const first = isValley ? '0% 100%, 0% 0%,' : '0% 100%,' ; const last = isValley ? ',100% 0%, 100% 100%' : ',100% 100%' ; const innerPoints = [ ... Array ( totalPoints ) ] . reduce ( ( acc , curr , index ) => { const xMean = ( 100 / totalPoints ) * index ; const xShift = 100 / totalPoints / 2 ; if ( index === 0 ) return [ ] ; const x = randomIntFromInterval ( xMean - xShift , xMean + xShift - 1 ) ; const y = randomIntFromInterval ( 100 - intensity , 100 ) ; return acc . concat ( `${ x }% ${ y }%` ) ; } , [ ] ) ; return `polygon(${ first . concat ( innerPoints . join ( ',' ) , last ) })` ; } function updatePoints ( ) { if ( ! isActive ) { setStyleObject ( prefixedPropertyStyleObject ( 'clipPath' , makePolygonPoints ( points , intensity ) ) ) ; setIsActive ( true ) ; } if ( timer ) { clearTimeout ( timer ) ; } timer = setTimeout ( ( ) => { setStyleObject ( prefixedPropertyStyleObject ( 'clipPath' , makePolygonPoints ( points , intensity ) ) ) ; setIsActive ( false ) ; } , 150 ) ; } const debounceUpdatePoints = debounce ( updatePoints , 500 ) ; useEffect ( ( ) => { updatePoints ( ) ; if ( ! isStatic ) { window . addEventListener ( 'scroll' , debounceUpdatePoints ) ; } return ( ) => { window . removeEventListener ( 'scroll' , debounceUpdatePoints ) ; clearTimeout ( timer ) ; } ; } , [ ] ) ; return ( < Edge background = { background } isRotated = { isRotated || false } style = { styleObject } isEnhanced = { isEnhanced } / > ) ; } ; export default WobblyEdge ;