Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React-Springでリッチなアニメーション
Search
Taketoshi Aono(青野健利 a.k.a brn)
September 30, 2019
Programming
1
540
React-Springでリッチなアニメーション
react-springでリッチなアニメーションを実現した記録です。
リッチとは...
Taketoshi Aono(青野健利 a.k.a brn)
September 30, 2019
Tweet
Share
More Decks by Taketoshi Aono(青野健利 a.k.a brn)
See All by Taketoshi Aono(青野健利 a.k.a brn)
document.write再考
brn
6
2.7k
Parsing Javascript
brn
12
8k
JSON & Object Tips
brn
1
330
CA 1Day Youth Bootcamp for Frontend LT
brn
0
720
Modern TypeScript
brn
2
700
javascript - behind the scene
brn
3
640
tc39 proposals
brn
0
720
プロダクト開発とTypeScript
brn
8
2.7k
javascript internationalization API
brn
0
730
Other Decks in Programming
See All in Programming
AWS初心者ってどうやってAWSを学ぶ?〜アプリエンジニアがやってよかったアーキテクチャ学習方法〜
yamanashi_ren01
0
190
CSC307 Lecture 09
javiergs
PRO
1
500
Temporalを取り巻く仕様を整理する
sajikix
0
110
CSC307 Lecture 10
javiergs
PRO
0
310
CSC307 Lecture 11
javiergs
PRO
0
240
AHC035解説
terryu16
0
710
はしめてのプログラミングとロボット制御
watawatavoltage
0
290
リハビリmruby
kishima
1
160
社内 LT 会を発足し、アウトプット文化を醸成させるために考えたこと・やったこと / Starting internal LT meetings and fostering an output culture
mackey0225
3
120
ぼっちを避けて楽しむためのアノテコノテ / Various Tips and Tricks to Avoid Loneliness and Have Fun
nrslib
3
1.7k
Mastering Developer Experience: A Roadmap for Success 【開発生産性Conference 2024】
findyinc
1
380
スクラムマスターって孤独じゃないですか?
yoshitaroyoyo
1
140
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1362
200k
Building an army of robots
kneath
301
42k
Docker and Python
trallard
37
2.9k
4 Signs Your Business is Dying
shpigford
178
21k
GraphQLの誤解/rethinking-graphql
sonatard
59
9.6k
Fantastic passwords and where to find them - at NoRuKo
philnash
42
2.7k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
13
430
ReactJS: Keep Simple. Everything can be a component!
pedronauck
662
120k
Speed Design
sergeychernyshev
9
270
Done Done
chrislema
179
15k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
29
2.5k
How STYLIGHT went responsive
nonsquared
93
5k
Transcript
React-SpringͰϦονΞχϝʔγϣϯ
Name !CSO 5BLFUPTIJ"POP੨݈ར Occupation 'SPOUFOE%FWFMPQFS1SPEVDU0XOFS Company $ZCFSBHFOU"EUFDI4UVEJP"*.FTTFOHFS OSS $POUSJCVUPSPG7
About IUUQJOGPCODI
3FBDU4QSJOH 3FBDU͚ͷ"OJNBUJPOϥΠϒϥϦ IUUQTHJUIVCDPNSFBDUTQSJOHSFBDUTQSJOH
3FBDU "OJNBUJPO 3FBDUͱΞχϝʔγϣϯதʑ૬ੑ͕ѱ͍ $445SBOTJUJPOͬͨΓɺ$445SBOTJUJPOؤுͬͯͬͨΓ ͚ͩͲෳࡶͳΞχϝʔγϣϯ͔ͳΓݫ͍͠
3FBDU4QSJOH
3FBDU4QSJOH ෳࡶͳΞχϝʔγϣϯΛએݴతʹ࣮ߦͰ͖Δ ঃʑʹΛ૿ͨ͠Γɾॱ൪ʹ࣮ߦͨ͠Γ ߋʹΞχϝʔγϣϯͷಈ͖୯७ͳ&BTJOH͡Όͳ͍ͷͰ໘ന͍
4QSJOHCBTFE ௨ৗͷ࣌ؒϕʔεͷΞχϝʔγϣϯͱҧͬͯ NBTT UFOTJPO GSJDUJPO QSFDJTJPO WFMPDJUZ ͷύϥϝʔλͰߏ͞ΕΔεϓϦϯάͷΑ͏ͳཧಛੑͷΞχϝʔγϣϯ Λ࣮ݱͰ͖Δɻ
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> ) }
https://codesandbox.io/embed/01yl7knw70
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> ) }
https://codesandbox.io/embed/r5x34869vq
"1*
3FBDUIPPLT ͯ͢ͷ"1*͕3FBDU)PPLTʹରԠ͍ͯ͠ΔͷͰͦͬͪΛ͍·͠ΐ͏
const props = useSpring({opacity: toggle ? 1 : 0}) return
<animated.div style={props}>i will fade</animated.div> useSpring
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
const trail = useTrail(3, {opacity: 1}) return trail.map(props => <animated.div
style={props} />) useTrail https://codesandbox.io/embed/8zx4ppk01l
ύϑΥʔϚϯε 3FBDU4QSJOH)PPLTOBUJWFϑϥά͖ͷίϯϙʔωϯτΛར༻͢Δͱɺ ίϯϙʔωϯτ෦Ͱ%0.ϊʔυʹରͯ͠ελΠϧͷॻ͖͑Λߦ͏ 5SFFશମͷԾ%0.ͷߋ৽ΛαϘ͍ͬͯΔͷͰߴ
(16$16 $44ͷMFGUNBSHJOͳͲͷϓϩύςΟ௨ৗ$16ʹΑͬͯܭࢉ͞ΕΔɻ ͔͠͠USBOTMBUFEͷ%USBOTGPSNܥͷϓϩύςΟ(16ʹΑͬͯॲཧ͞ ΕΔ (16ॲཧ௨ৗઐ༻ϋʔυΣΞͰͷॲཧͷͨΊɺͦͷଞͷॲཧ͕ڬ·Δ $16ΑΓߴʹඳը͕Մೳɻ
ύϑΥʔϚϯε ͨͩ͠ɺSFBDUTQSJOHΛߋ৽͠ͳ͕ΒΞχϝʔγϣϯ͢ΔͨΊɺ (16Λ͏·͑͘ͳ͍͜ͱ͕ଟ͍ɻ XJMMDIBOHFϓϩύςΟͷΑ͏ͳͷΛ͏͔ EܥΛར༻ͯ͠(16ʹඳը ͤ͞ΔΑ͏ʹͨ͠΄͏͕Α͍ɻ
$BOWBT 3FBDUͰDBOWBTΛૢ࡞͢Δ3FBDU,POWBͱ͍͏ϥΠϒϥϦ͕͋Δ͕ɺ ,POWBΛαϙʔτ͓ͯ͠Γ$BOWBT্ͰෳࡶͳΞχϝʔγϣϯΛߏஙͰ͖ Δ
,POWBͰؾΛ͚ͭΔ͜ͱ ,POWBͰ3FBDU)PPLTΛར༻͢Δͱඍົʹಈ࡞͕͘ͳΔͷͰɺ ʠSFBDUTQSJOHSFOEFSQSPQTLPOWBʡΛར༻ͯ͠+49Ͱهड़ͨ͠΄͏͕ྑ͍