Slide 1

Slide 1 text

$BOWBTͰϐΞϊϩʔϧΛ࡞Δ $BOWBTͰεΫϩʔϧΛѻ͏ࡍͷ
 ࠲ඪܭࢉͱۤ࿑ +BO OHLZPUP"OHVMBS.FFUVQ !PLVOPLFOUBSP

Slide 2

Slide 2 text

୭ w Ԟ໺ݡଠ࿠!PLVOPLFOUBSP w ΫϨε΢ΣΞ୅ද w ΞϓϦέʔγϣϯ ɾ ΤϯδχΞ

Slide 3

Slide 3 text

࠷ۙ΍ͬͨ͜ͱ w 8FC.VTJDͰ͸Կ͕Ͱ͖Δͷ͔
 '30/5&/%$0/'&3&/$& w ೔ͷ τϥΠΤϥʔ͔Βੜ·Εͨେن໛ઃܭϊ΢ϋ΢
 'SPOUFOE$POGFSFODF'VLVPLB w ࣍ੈ୅8FCΧϯϑΝϨϯε8FC.VTJDηογϣϯ
 ࣍ੈ୅8FCΧϯϑΝϨϯε

Slide 4

Slide 4 text

ࠓ೔࿩͢͜ͱ w $BOWBTͰϐΞϊϩʔϧΛ࣮૷͢Δ w 3FBDU)PPLTͱ͸Կ͔ w $BOWBTΛѻ͏্Ͱͷۤ࿑

Slide 5

Slide 5 text

ϐΞϊϩʔϧͱ͸

Slide 6

Slide 6 text

ϐΞϊϩʔϧ ͍͍ͩͨͲͷԻ੍ָ࡞༻ͷιϑ τ΢ΣΞʹ΋࣮૷͞Ε͍ͯΔ
 ϝϩσΟ Λೖྗ͢ΔͨΊͷΤσΟ λը໘

Slide 7

Slide 7 text

%FNP

Slide 8

Slide 8 text

Ͱ͖Δ͜ͱ Ϋ Ϧ οΫͰͷԻූͷೖྗ
 υϥ οάͰͷԻූ௕ͷมߋ
 ϐΞϊϩʔϧදࣔͷ9ํ޲ɺ :ํ޲ͷ֦େॖখɺ εΫϩʔϧ
 ʢσϞͯ͠ͳ͍͚Ͳɺ Իූͷίϐϖ΍࡟আ΋౰ͨΓલʹͰ͖Δʣ

Slide 9

Slide 9 text

ͳʹ͛ʹߴػೳ w Ի੍ָ࡞༻ιϑ τ %"8 ͸ઐ໳ੑ͕ߴ͍ͨΊಛԽͨ͠ػೳ͕ଟ͍ w ςΩε τΤσΟ λʹൺ΂Δͱང͔ʹಛघͳ࣮૷ w (6*࣮૷Λੜۀͱ͢Δϑϩϯ τΤϯ υ ɾ ΤϯδχΞͱͯ͠
 ͜ΕΛͪΌΜͱ࣮૷Ͱ͖ΔͱεΩϧΞοϓ͢ΔͷͰ͸

Slide 10

Slide 10 text

΍ͬͯΈͨ

Slide 11

Slide 11 text

3FBDU$BOWBT w OHLZPUP"OHVMBS.FFUVQͰൃදͯ͠Δ͚Ͳ3FBDUΛ࢖ͬͨ w $BOWBTΛ࢖͏͚ͩͳͷͰ7BOJMMB+4Ͱ΋͍͍͕3FBDUΛ࢖ͬͨ w )PPLTͷ࿅श΋͔ͨͬͨ͠ͷͰ3FBDUΛ࢖ͬͨ

Slide 12

Slide 12 text

3FBDU)PPLT w ೥݄ɺ 3FBDU$POGʹͯൃද͞Εͨ3FBDUͷ৽͍͠"1*܈ w 4UBCMFͰ͸࢖͏ ͜ͱ͕Ͱ͖ͣnpm i react@next͢Δ͜ͱͰ
 ࣮૷ࡁΈϦ ϦʔεΛΠϯε τʔϧͰ͖Δ

Slide 13

Slide 13 text

3FBDU)PPLT w ͔ͭͯ3FBDUͷίϯϙʔωϯ τ͸
 class Something extends React.Component
 ͷΑ ͏ʹΫϥεͱ ͯ͠هड़͢Δ͔
 SFDPNQPTFΛ࢖ͬͯ)JHIFSPSEFS$PNQPOFOU )0$ ͱͯ͠هड़ͨ͠ w )0$ͱ͸ίϯϙʔωϯ τΛҾ਺ͱ ͯ͠ίϯϙʔωϯ τΛฦؔ͢਺ͷ͜ͱ w ͭ· Γ Ϋϥεͱͯ͠Ͱ͸ͳ͘ɺ ؔ਺ͱ ͯ͠هड़͢Δͱ͍͏ ͜ͱ

Slide 14

Slide 14 text

3FBDU)PPLT w SFDPNQPTFͷ࡞ऀ͕'BDFCPPLʹࢀՃͨ͠ w SFDPNQPTF͕ղܾ͠Α ͏ ͱ ͍ͯͨ͠໰୊Λ
 3FBDUຊମͰ׬݁ͯ͠վળͰ͖ΔΑ ͏ʹͳͬͨ w ͦ͏΍ͬͯੜ·Εͨͷ͕)PPLT w SFDPNQPTF͸σΟ είϯͱͳͬͨ

Slide 15

Slide 15 text

ͳͥΫϥεͰ͸μϝ͔ w Ϋϥε͸UIJTʹঢ়ଶΛ࣋ͨͤΔ͜ͱ͕Ͱ͖Δ ʢεςʔ τϑϧɺ ෭࡞༻ʣ w componentDidMount componentDidUpdateͱ͍ͬͨ
 ϥΠ ϑαΠΫϧϝ ιο υʹΑͬͯUIJT಺͕ॻ͖׵͑ΒΕ֎෦͔Βͷςε τ͕ࠔ೉ w ϥΠ ϑαΠΫϧϝ ιο υʹɺ ίϯϙʔωϯ τͷ ʮ஋Λඳը͢Δʯ ͱ͍͏੹຿Λ௒͑ͨ ෳࡶͳॲཧ͕ॻ͔Ε͕ͪ ʢGFUDIॲཧͱ͔ʣ w ෳࡶੑ͕૿͢ͱݕূ͕ࠔ೉ʹͳΓόά͕૿͑Δ 3FBDUυΩϡϝϯ τͷϞνϕʔγϣϯͷทΑ Γҙ༁ͯ͠Ҿ༻

Slide 16

Slide 16 text

'VODUJPOBM$PNQPOFOU w 3FBDU)PPLTΛ࢖͏ ͜ͱͰίϯϙʔωϯ τΛؔ਺ͱͯ͠هड़ͭͭ͠
 ͞Βʹঢ়ଶΛѻ͏ ͜ͱ͕Ͱ͖ΔΑ ͏ʹͳΔ w 3FBDUIPPLTOPUNBHJD KVTUBSSBZT
 https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e w ैདྷͷϥΠ ϑαΠΫϧϝ ιο υ΋useEffect() ͱ͍͏
 3FBDU)PPLTͷҰछΛ࢖͍ɺ ؔ਺ͱ ͯ͠هड़͢Δ

Slide 17

Slide 17 text

%FNP

Slide 18

Slide 18 text

ίʔ υͷߏ଄ export default function App() { // ͻͨ͢Β useState() const canvasRef = useRef < HTMLCanvasElement > null; useEffect(() => { // ॳظඳը࣌ॲཧ }, []); useEffect(() => { // Իූ௥Ճ࣌ͷॲཧ }, [notes]); useEffect(() => { // εΫϩʔϧҐஔมߋ࣌ͷॲཧ }, [scrollLeft, scrollTop]); const onDragHorizontalScrollBarKnob = useCallback((ev: React.MouseEvent) => { // ਫฏεΫϩʔϧόʔυϥοά࣌ͷϋϯυϦϯά }, [originXY, mediator]); const onDragVerticalScrollBarKnob = useCallback((ev: React.MouseEvent) => { // ਨ௚εΫϩʔϧόʔυϥοά࣌ͷϋϯυϦϯά }, [originXY, mediator]); const onDragScreen = useCallback((ev: React.MouseEvent) => { // Canvas಺υϥοά࣌ͷૢ࡞ʢԻූ௕ͷมߋʣ }, [scrollBarCoord, currentUuid, originXY, notes]); const onMouseDown = useCallback((ev: React.MouseEvent) => { // Canvas಺ͰͷmousedownϋϯυϦϯά }, [ currentUuid, originXY, notes, scrollBarCoord, isDraggingHorizontalScrollBarKnob, isDraggingVerticalScrollBarKnob ]); const onMouseMove = useCallback((ev: React.MouseEvent) => { // canvas಺ͰͷmousemoveϋϯυϦϯά }, [ currentUuid, originXY, notes, isDraggingHorizontalScrollBarKnob, isDraggingVerticalScrollBarKnob ]); return (
onMouseDown(ev)} onMouseMove={ev => onMouseMove(ev)} ref={canvasRef} width="600" height="400" />
); }

Slide 19

Slide 19 text

υϥοάϋϯ υ Ϧ ϯάͷ࣮ݱ w Ϛ΢εΫ Ϧ οΫΛͯͦ͠ͷ··཭ͣ͞υϥ οάͱ͍͏࣮૷͕஍ຯʹ೉͍͠ w ondrag͸ͦ͏͍࣮ͬͨ૷ͷͨΊͷΠϕϯ τͰ͸ͳ͍ w onmousemoveͰev.button === 1ͷͱ͖ υϥοάͱ൑அ͢ΔΑ ͏ʹ෼ذ

Slide 20

Slide 20 text

εΫϩʔϧόʔͷϋϯ υ Ϧ ϯά w εΫϩʔϧόʔ͕Ϋ Ϧ οΫ͞Ε͍ͯΔ͔Ͳ͏͔͸ɺ શͯࣗྗͰ࠲ඪܭࢉ
 ͠ͳ͚Ε͹ͳΒͳ͍ w ϊ ϒͷࠨ্࠲ඪͱӈԼ࠲ඪΛuseState()Ͱ
 ֨ೲ͓͖ͯ͠onmousedownͰ
 ຖճɺ ྖҬ಺͔൑ఆ͢Δ

Slide 21

Slide 21 text

ԻූͷઃஔͱԻූ௕ͷมߋ w Ϛ΢εͷ࠲ඪ͔Βx - 5, y - 10ͷҐஔΛج఺ʹۣܗ ʢԻූʣ Λඳը w Ϛ΢ε࠲ඪΛج఺ʹ͢ΔͱԻූ͕ΧʔιϧͰӅΕͯ͠·͍ඇ௚ײత w ຖճ66*%Λൃߦͯ͠Իූʹ෇༩ w mousedown࣌ʹهԱͨ͠66*%͕mousemove࣌ʹ༗ޮͳΒ͹
 Իූ௕มߋͱ൑ఆ͢Δ w Ϣʔβʹ͸ී௨ʹΫ Ϧ οΫͯ͠ υϥ οάͯ͠Δײ֮

Slide 22

Slide 22 text

ॳظඳը w 3FBDU)PPLTʹuseRef()͕͋ΔͷͰͦΕΛ࢖ͬͯ$BOWBT3FGΛऔಘ w CanvasRef.currentͰωΠςΟ ϒͳ$BOWBTཁૉͷࢀরΛಘΔ w canvasEl.getContext('2d')ͰίϯςΩε τΛಘ͔ͯΒ͸$BOWBT"1* ௨ΓʹਐΊΕ͹0,

Slide 23

Slide 23 text

3FUJOBରԠ w window.devicePixelRatioͰ3FUJOBͳͲͷഒ཰ΛऔಘՄೳ w canvasCtx.scale(dpr, dpr)Ͱഒ཰ઃఆ͕Մೳ w fillRect(x * dpr, y * dpr, width * dpr, height * dpr)
 ͱ͔ຖճॻ͔ͳ͘ ͯࡁΉ w ߴEQSදࣔ࣌ʹδϟΪʔ͕ग़ͳ͍Α ͏ʹɺ ຐ๏ͷߦΛ௥Ճ canvasEl.width *= dpr; canvasEl.height *= dpr; canvasEl.style.width = `${canvasEl.width / dpr}px`; canvasEl.style.height = `${canvasEl.height / dpr}px`;

Slide 24

Slide 24 text

εΫϩʔϧରԠ w Ϋ Ϧ οΫͰͷԻූඳը࣌ʹ
 ͋Β͔͡ΊxʹscrollLeftΛɺ yʹscrollTopΛ଍͢ w εΫϩʔϧόʔͷ υϥ οά࣌ʹ࠶ඳըॲཧͰ
 ͢΂ͯͷԻූ࠲ඪ͔ΒscrollLeftͱscrollTopΛҾ͍ͯ࠶ඳը w ͨͿΜݱࡏͷ࣮૷ͷ··Ͱ͸·ͣ͘ ͯ
 ཧ૝తʹ͸Ϋ Ϧ οΫ͞Ε࣮ͨࡍͷ࠲ඪͱϐΞϊϩʔϧશମ͔ΒΈͨԾ૝࠲ඪΛ
 ܥ౷؅ཧ͠ͳ͍ͱɺ ॎԣ֦େॖখͳͲͰࢮ͵

Slide 25

Slide 25 text

ۤ࿑ͨ͠఺ ʢ3FBDUฤʣ w useEffect()͕૿͑Δ๲ΒΉ w Πϕϯ τϋϯ υ Ϧ ϯάʹԠͨ͡࠶ඳըͷछྨ͕ଟ͍͍ͤ΋͋Δ͚Ͳ
 ෳ਺ͷuseEffect()ʹΑͬͯίϯϙʔωϯ τؔ਺͕ංେԽͨ͠ w Իූυϥ οά࣌ͱεΫϩʔϧόʔ ɾ υϥ οά࣌Ͱ࠶ඳըॲཧ͕ҧ͏ w useEffect(cb, [])ͷୈೋҾ਺ʹࢀরΛྻڍ͢Δ͜ͱͰ
 ͦͷࢀর͕มԽͨ͠ͱ͖ͷΈuseEffectΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ
 ʢuseEffect(() => {}, [scrollLeft]) ͳͲʣ

Slide 26

Slide 26 text

ۤ࿑ͨ͠఺ ʢ3FBDUฤʣ w 3FBDUͷϚ΢εૢ࡞࣌ͷϋϯ υ Ϧ ϯάҾ਺͸MouseEventܕͰ͸ͳ͍ w 3FBDUख़࿅ऀʹ͸౰ͨΓલͷ࿩͔΋ w SyntheticEventͱ͍͏ܗࣜͰ౉ΔͷͰnativeEventऔಘͷͨΊʹ͸
 ev.persist();
 const nativeEv = ev.nativeEvent;
 ͷΑ ͏ʹҰ୴persist͢Δඞཁ͕͋Δ w ͜͏ ͠ͳ͍ͱoffsetX offsetY͕औΕͳ͍ͷͰ஫ҙ

Slide 27

Slide 27 text

ۤ࿑ͨ͠఺ ʢ$BOWBTฤʣ w ͻͨ͢Β࠲ඪܭࢉͱͷઓ͍ͱͳΔ w fillRect()ͳͲ͢΂ͯͷඳըॲཧ͸ޙউͪͳͷͰίʔϧॱͰ݁Ռ͕มΘΔ w ։ൃத͸Իූ͕εΫϩʔϧόʔΛಥ͖ൈ͚Δͱ͔βϥ w ϨΠϠʔͳΜͯ֓೦͸ແ͍ ʢؤு࣮ͬͯ૷͢Δ͔$BOWBTϥούʔϥΠ ϒϥ ϦʹཔΔʣ w ͻͨ͢ΒԚ͍ίʔ υͱ ϒϥ΢β্ͷखಈσόοάΛ܁Γฦͯ͠
 ͧ͜͜ͱ͍͏ ͱ͜ΖͰϦ ϑΝΫλ Ϧ ϯά

Slide 28

Slide 28 text

ۤ࿑ͨ͠఺ ʢ$BOWBTฤʣ w 3FBDUͷίϯϙʔωϯ τؔ਺͔Β$BOWBTʹؔ͢Δॲཧ͸͢΂ͯ௥͍ग़ͨ͠ w CanvasMediatorͱ͍͏தؒҕৡ༻ͷγϯάϧ τϯΛ࡞ͬͯ
 ඳըܥͱ࠲ඪऔಘܥ͸͢΂ͯͦͬͪʹ࣮૷͢ΔΑ ͏ Ϧ ϑΝΫλ Ϧ ϯά w Իූ͚ͩͳΒ؆୯ͩͬͨ w εΫϩʔϧόʔͷ࣮૷Λ࢝ΊͨลΓ͔Βࠞಱͱ ࢝͠Ίͯ
 ϒϥ΢βͷ΢Πϯ υ΢࣮૷ͷ࢓༷ͱ͔ړΓ࢝Ίͨ w 04ͷ΢Πϯ υ΢γεςϜΛ࣮૷ͨ͠ਓ͸ϚδͰҒେͩͱࢥ͏

Slide 29

Slide 29 text

ࠓޙ΍͍͖͍ͬͯͨػೳ w Ϋ Ϧ οΫͯ͠ஔ͍ͨԻූͷҠಈ ɾ ࡟আ w Ͳͷۣܗ͕Ϋ Ϧ οΫ͞Ε͔͕ͨऔΕͦ͏ʹͳ͍ͷͰ
 εΫϩʔϧόʔͱಉ͡Ͱɺ ͢΂ͯྖҬܭࢉͰදݱ͢Δ͔͠ͳ͍͔΋ wυϥοάͨ͠··$BOWBT֎ʹϚ΢εΛಈ͔ͨ͠ΒࣗಈͰεΫϩʔϧ w ࠲ඪ͸औΕΔͬΆ͍ɺ ࠶ඳըܭࢉ͕΍ͨΒ໘౗ͬΆ͍ w ࣮ࡍʹ࠶ੜϘλϯΛ෇͚ͯԻΛ໐Β͢ w ເͷ·ͨເ

Slide 30

Slide 30 text

͜͜·Ͱۤ࿑ͯ͠ࢥͬͨ͜ͱ w "OHVMBSͰେن໛ΞϓϦΛ࡞Εͯ΋$BOWBTશવ࡞Εͳ͍ w 3FBDU͡Όͳ͘ ͍͍ͯ w $VTUPN&MFNFOUTͱ૬ੑΑͦ͞͏

Slide 31

Slide 31 text

5IBOLZPV %0.ʹײँ͠ͳ͕Β$BOWBTͰ(6*ͷԞਂ͞ʹ৮ΕΑ ͏ ʂ