React-Springでリッチなアニメーション

 React-Springでリッチなアニメーション

react-springでリッチなアニメーションを実現した記録です。
リッチとは...

Transcript

  1. React-SpringͰϦονΞχϝʔγϣϯ

  2. Name !CSO 5BLFUPTIJ"POP੨໺݈ར  Occupation 'SPOUFOE%FWFMPQFS1SPEVDU0XOFS Company $ZCFSBHFOU"EUFDI4UVEJP"*.FTTFOHFS OSS $POUSJCVUPSPG7

    About IUUQJOGPCODI
  3. 3FBDU4QSJOH 3FBDU޲͚ͷ"OJNBUJPOϥΠϒϥϦ IUUQTHJUIVCDPNSFBDUTQSJOHSFBDUTQSJOH

  4. 3FBDU "OJNBUJPO 3FBDUͱΞχϝʔγϣϯ͸தʑ૬ੑ͕ѱ͍ $445SBOTJUJPO࢖ͬͨΓɺ$445SBOTJUJPOؤுͬͯ࢖ͬͨΓ ͚ͩͲෳࡶͳΞχϝʔγϣϯ͸͔ͳΓݫ͍͠

  5. 3FBDU4QSJOH

  6. 3FBDU4QSJOH ෳࡶͳΞχϝʔγϣϯΛએݴతʹ࣮ߦͰ͖Δ ঃʑʹ஋Λ૿΍ͨ͠Γɾॱ൪ʹ࣮ߦͨ͠Γ ߋʹΞχϝʔγϣϯͷಈ͖΋୯७ͳ&BTJOH͡Όͳ͍ͷͰ໘ന͍

  7. 4QSJOHCBTFE ௨ৗͷ࣌ؒϕʔεͷΞχϝʔγϣϯͱҧͬͯ NBTT UFOTJPO GSJDUJPO QSFDJTJPO WFMPDJUZ ౳ͷύϥϝʔλͰߏ੒͞ΕΔεϓϦϯάͷΑ͏ͳ෺ཧಛੑͷΞχϝʔγϣϯ Λ࣮ݱͰ͖Δɻ

  8. import { render } from 'react-dom' import React, { useState

    } from 'react' import { useSpring, animated as a } from 'react-spring' import './styles.css' function Card() { const [flipped, set] = useState(false) const { transform, opacity } = useSpring({ opacity: flipped ? 1 : 0, transform: `perspective(600px) rotateX(${flipped ? 180 : 0}deg)`, config: { mass: 5, tension: 500, friction: 80 } }) return ( <div onClick={() => set(state => !state)}> <a.div class="c back" style={{ opacity: opacity.interpolate(o => 1 - o), transform }} /> <a.div class="c front" style={{ opacity, transform: transform.interpolate(t => `${t} rotateX(180deg)`) }} /> </div> ) }
  9. https://codesandbox.io/embed/01yl7knw70

  10. import React from 'react' import ReactDOM from 'react-dom' import {

    useSpring, animated } from 'react-spring' import './styles.css' // // Icons made by Freepik from www.flaticon.com const calc = (x, y) => [x - window.innerWidth / 2, y - window.innerHeight / 2] const trans1 = (x, y) => `translate3d(${x / 10}px,${y / 10}px,0)` const trans2 = (x, y) => `translate3d(${x / 8 + 35}px,${y / 8 - 230}px,0)` const trans3 = (x, y) => `translate3d(${x / 6 - 250}px,${y / 6 - 200}px,0)` const trans4 = (x, y) => `translate3d(${x / 3.5}px,${y / 3.5}px,0)` function Card() { const [props, set] = useSpring(() => ({ xy: [0, 0], config: { mass: 10, tension: 550, friction: 140 } })) return ( <div class="container" onMouseMove={({ clientX: x, clientY: y }) => set({ xy: calc(x, y) })}> <animated.div class="card1" style={{ transform: props.xy.interpolate(trans1) }} /> <animated.div class="card2" style={{ transform: props.xy.interpolate(trans2) }} /> <animated.div class="card3" style={{ transform: props.xy.interpolate(trans3) }} /> <animated.div class="card4" style={{ transform: props.xy.interpolate(trans4) }} /> </div> ) }
  11. https://codesandbox.io/embed/r5x34869vq

  12. "1*

  13. 3FBDUIPPLT ͢΂ͯͷ"1*͕3FBDU)PPLTʹରԠ͍ͯ͠ΔͷͰͦͬͪΛ࢖͍·͠ΐ͏

  14. const props = useSpring({opacity: toggle ? 1 : 0}) return

    <animated.div style={props}>i will fade</animated.div> useSpring
  15. const [show, set] = useState(false) const transitions = useTransition(show, null,

    { from: { position: 'absolute', opacity: 0 }, enter: { opacity: 1 }, leave: { opacity: 0 }, }) return transitions.map(({ item, key, props }) => item && <animated.div key={key} style={props}>✌</animated.div> ) useTransition
  16. const trail = useTrail(3, {opacity: 1}) return trail.map(props => <animated.div

    style={props} />) useTrail https://codesandbox.io/embed/8zx4ppk01l
  17. ύϑΥʔϚϯε 3FBDU4QSJOH͸)PPLT΍OBUJWFϑϥά෇͖ͷίϯϙʔωϯτΛར༻͢Δͱɺ ίϯϙʔωϯτ಺෦Ͱ௚઀%0.ϊʔυʹରͯ͠ελΠϧͷॻ͖׵͑Λߦ͏ 5SFFશମͷԾ૝%0.ͷߋ৽ΛαϘ͍ͬͯΔͷͰߴ଎

  18. (16$16 $44ͷMFGUNBSHJOͳͲͷϓϩύςΟ͸௨ৗ$16ʹΑͬͯܭࢉ͞ΕΔɻ ͔͠͠USBOTMBUFE౳ͷ%USBOTGPSNܥͷϓϩύςΟ͸(16ʹΑͬͯॲཧ͞ ΕΔ (16ॲཧ͸௨ৗઐ༻ϋʔυ΢ΣΞͰͷॲཧͷͨΊɺͦͷଞͷॲཧ͕ڬ·Δ $16ΑΓ΋ߴ଎ʹඳը͕Մೳɻ

  19. ύϑΥʔϚϯε ͨͩ͠ɺSFBDUTQSJOH͸஋Λ௚઀ߋ৽͠ͳ͕ΒΞχϝʔγϣϯ͢ΔͨΊɺ (16Λ͏·͘࢖͑ͳ͍͜ͱ͕ଟ͍ɻ XJMMDIBOHFϓϩύςΟͷΑ͏ͳ΋ͷΛ࢖͏͔ EܥΛར༻ͯ͠(16ʹඳը ͤ͞ΔΑ͏ʹͨ͠΄͏͕Α͍ɻ

  20. $BOWBT 3FBDUͰDBOWBTΛૢ࡞͢Δ3FBDU,POWBͱ͍͏ϥΠϒϥϦ͕͋Δ͕ɺ ,POWBΛαϙʔτ͓ͯ͠Γ$BOWBT্Ͱ΋ෳࡶͳΞχϝʔγϣϯΛߏஙͰ͖ Δ

  21. ,POWBͰؾΛ͚ͭΔ͜ͱ ,POWBͰ3FBDU)PPLTΛར༻͢Δͱඍົʹಈ࡞͕஗͘ͳΔͷͰɺ ʠSFBDUTQSJOHSFOEFSQSPQTLPOWBʡΛར༻ͯ͠+49Ͱهड़ͨ͠΄͏͕ྑ͍