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
640
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
3k
Parsing Javascript
brn
13
9.1k
JSON & Object Tips
brn
1
440
CA 1Day Youth Bootcamp for Frontend LT
brn
0
860
Modern TypeScript
brn
2
770
javascript - behind the scene
brn
3
710
tc39 proposals
brn
0
820
プロダクト開発とTypeScript
brn
8
2.8k
javascript internationalization API
brn
0
830
Other Decks in Programming
See All in Programming
Immutable ActiveRecord
megane42
0
130
[JAWS-UG横浜 #80] うわっ…今年のServerless アップデート、少なすぎ…?
maroon1st
1
170
Rubyでつくるパケットキャプチャツール
ydah
1
750
CNCF Project の作者が考えている OSS の運営
utam0k
5
670
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
430
Simple組み合わせ村から大都会Railsにやってきた俺は / Coming to Rails from the Simple
moznion
3
4.3k
2,500万ユーザーを支えるSREチームの6年間のスクラムのカイゼン
honmarkhunt
6
5k
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
230
Kanzawa.rbのLT大会を支える技術の裏側を変更する Ruby on Rails + Litestream 編
muryoimpl
0
190
『品質』という言葉が嫌いな理由
korimu
0
150
【PHP】破壊的バージョンアップと戦った話〜決断と説得
satoshi256kbyte
0
120
ErdMap: Thinking about a map for Rails applications
makicamel
1
1.4k
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
128
19k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
25k
Music & Morning Musume
bryan
46
6.3k
Become a Pro
speakerdeck
PRO
26
5.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Bash Introduction
62gerente
610
210k
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Ͱهड़ͨ͠΄͏͕ྑ͍