Ripple Button
code: github/
$ yarn 1203

컴포넌트의 사용감은 다음과 같습니다.
<RippleButton
width={'160px'}
heihgt={'64px'}
borderRadius={'5px'}
backgroundColor={'#7089b9'}
effectSize={160}
>
<span className="children">
<SVGInline svg={UP1} />
UPLOAD
</span>
</RippleButton>
보시다시피, 스타일 설정을 props로 받아들입니다. 또한 버튼 내부는 자유롭게 콘텐츠를 배포할 수 있도록 props.children을 render합니다.
Custom Hooks 잘라내기
View와 로직을 구분하기 위해 useRippleEffect라는 Custom Hooks를 정의합니다. 반환값에는, 컴퍼넌트에 필요한 계산 프로퍼티과 갱신 핸들러를 포함합니다 (여기에서는, 적용하는 style, 마우스 다운 핸들러, 마우스 업 핸들러). 각 Hooks API에 바인딩된 처리 세부사항은 설명적으로 생략합니다.
function useRippleEffect(props: Props) {
const [state, update] = useState<State>(...)
const tx = useMemo(...)
const ty = useMemo(...)
const ts = useMemo(...)
const effectSytle = useMemo(...)
const handleMouseDown = useCallback(...)
const handleMouseUp = useCallback(...)
return {
effectSytle,
handleMouseDown,
handleMouseUp
}
}
Ref Injection
이전에 ref는 Statefull Component에서만 사용할 수 있었지만 useRef를 사용하여 FC에서 ref를 사용할 수 있습니다. ref 는 Custom Hooks 에 포함하지 않고 「useRippleEffect」를 이용하는 Component 상에서 정의해, 주입합니다. 이는 ref가 여러 Custom Hooks의 관심 대상이 될 수 있기 때문입니다.
const View = (props: Props) => {
const ref = useRef({} as HTMLButtonElement)
const {
handleMouseDown,
handleMouseUp,
effectSytle
} = useRippleEffect({
ref,
effectDuration: props.effectDuration
})
return (
<button
ref={ref}
className={props.className}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onClick={props.onClick}
>
<span className="effect" style={effectSytle} />
{props.children}
</button>
)
}
위치 계산
리플은 DOM을 사용하여 표현합니다. 버튼을 누르면 요소의 상대 위치와 버튼 좌표에서 파문 DOM의 중앙 위치를 식별합니다. 이 때, 애니메이션 동력이 되는 「transitionDuration」을 0 으로 지정합니다.
const handleMouseDown = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => {
if (props.ref.current === null) return _state
const clickX = event.pageX
const clickY = event.pageY
const clientRect = props.ref.current.getBoundingClientRect()
const positionX = clientRect.left + window.pageXOffset
const positionY = clientRect.top + window.pageYOffset
const transformX = clickX - positionX
const transformY = clickY - positionY
return {
..._state,
opacity: 0.5,
transformX,
transformY,
transformScale: 0,
transitionDuration: 0
}
})
},
[]
)
이번 샘플집에서는, useState 로 취급하는 상태는 적극적으로 object 에 정리하고 있습니다. 요 전날의 게시에 의한 의도 도 물론 있습니다만, 이와 같이 정리해 상태를 갱신할 필요가 있는 경우, state 마다 useState 하는 것보다 편리합니다.
CSS 애니메이션 발화
마우스 업시, 움직이고 싶은 프로퍼티와 함께, transitionDuration 를 부여하면 애니메이션이 발화합니다.
const handleMouseUp = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => ({
..._state,
opacity: 0,
transformScale: 1,
transitionDuration: _state.effectDuration
}))
},
[]
)
Reference
이 문제에 관하여(Ripple Button), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Takepepe/items/0d1df7b22360a00f566a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
function useRippleEffect(props: Props) {
const [state, update] = useState<State>(...)
const tx = useMemo(...)
const ty = useMemo(...)
const ts = useMemo(...)
const effectSytle = useMemo(...)
const handleMouseDown = useCallback(...)
const handleMouseUp = useCallback(...)
return {
effectSytle,
handleMouseDown,
handleMouseUp
}
}
이전에 ref는 Statefull Component에서만 사용할 수 있었지만 useRef를 사용하여 FC에서 ref를 사용할 수 있습니다. ref 는 Custom Hooks 에 포함하지 않고 「useRippleEffect」를 이용하는 Component 상에서 정의해, 주입합니다. 이는 ref가 여러 Custom Hooks의 관심 대상이 될 수 있기 때문입니다.
const View = (props: Props) => {
const ref = useRef({} as HTMLButtonElement)
const {
handleMouseDown,
handleMouseUp,
effectSytle
} = useRippleEffect({
ref,
effectDuration: props.effectDuration
})
return (
<button
ref={ref}
className={props.className}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onClick={props.onClick}
>
<span className="effect" style={effectSytle} />
{props.children}
</button>
)
}
위치 계산
리플은 DOM을 사용하여 표현합니다. 버튼을 누르면 요소의 상대 위치와 버튼 좌표에서 파문 DOM의 중앙 위치를 식별합니다. 이 때, 애니메이션 동력이 되는 「transitionDuration」을 0 으로 지정합니다.
const handleMouseDown = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => {
if (props.ref.current === null) return _state
const clickX = event.pageX
const clickY = event.pageY
const clientRect = props.ref.current.getBoundingClientRect()
const positionX = clientRect.left + window.pageXOffset
const positionY = clientRect.top + window.pageYOffset
const transformX = clickX - positionX
const transformY = clickY - positionY
return {
..._state,
opacity: 0.5,
transformX,
transformY,
transformScale: 0,
transitionDuration: 0
}
})
},
[]
)
이번 샘플집에서는, useState 로 취급하는 상태는 적극적으로 object 에 정리하고 있습니다. 요 전날의 게시에 의한 의도 도 물론 있습니다만, 이와 같이 정리해 상태를 갱신할 필요가 있는 경우, state 마다 useState 하는 것보다 편리합니다.
CSS 애니메이션 발화
마우스 업시, 움직이고 싶은 프로퍼티와 함께, transitionDuration 를 부여하면 애니메이션이 발화합니다.
const handleMouseUp = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => ({
..._state,
opacity: 0,
transformScale: 1,
transitionDuration: _state.effectDuration
}))
},
[]
)
Reference
이 문제에 관하여(Ripple Button), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Takepepe/items/0d1df7b22360a00f566a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const handleMouseDown = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => {
if (props.ref.current === null) return _state
const clickX = event.pageX
const clickY = event.pageY
const clientRect = props.ref.current.getBoundingClientRect()
const positionX = clientRect.left + window.pageXOffset
const positionY = clientRect.top + window.pageYOffset
const transformX = clickX - positionX
const transformY = clickY - positionY
return {
..._state,
opacity: 0.5,
transformX,
transformY,
transformScale: 0,
transitionDuration: 0
}
})
},
[]
)
마우스 업시, 움직이고 싶은 프로퍼티와 함께, transitionDuration 를 부여하면 애니메이션이 발화합니다.
const handleMouseUp = useCallback(
(event: MouseEvent<HTMLButtonElement>) => {
event.persist()
update(_state => ({
..._state,
opacity: 0,
transformScale: 1,
transitionDuration: _state.effectDuration
}))
},
[]
)
Reference
이 문제에 관하여(Ripple Button), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Takepepe/items/0d1df7b22360a00f566a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)