@@ -4,6 +4,8 @@ export default class SourceCode extends React.Component {
4
4
5
5
constructor ( props ) {
6
6
super ( props ) ;
7
+ this . scrolledY = 0 ;
8
+ this . scrolledX = 0 ;
7
9
}
8
10
9
11
componentDidMount ( ) {
@@ -18,15 +20,55 @@ export default class SourceCode extends React.Component {
18
20
19
21
follow ( ) {
20
22
if ( this . props . isFinished ) { return ; }
21
- let box = React . findDOMNode ( this . refs . box ) ;
22
- let follow = React . findDOMNode ( this . refs . follow ) ;
23
+
24
+ // boxes
25
+ let box = React . findDOMNode ( this ) ;
26
+ let pre = React . findDOMNode ( this . refs . pre ) ;
27
+
28
+ // cursor
23
29
let cur = React . findDOMNode ( this . refs . cur ) ;
24
- let rectBox = box . getBoundingClientRect ( ) ;
25
- let rect = cur . getBoundingClientRect ( ) ;
26
- TweenMax . to ( follow , 0.15 , {
27
- scaleX : rect . width + 5 ,
28
- x : rect . left - rectBox . left - 2 ,
29
- y : rect . top - rectBox . top + 30
30
+ let letter = React . findDOMNode ( this . refs . letter ) ;
31
+
32
+ // follower
33
+ let follow = React . findDOMNode ( this . refs . follow ) ;
34
+
35
+ // get rectangles
36
+ let containerRect = box . getBoundingClientRect ( ) ;
37
+ let cursorRect = cur . getBoundingClientRect ( ) ;
38
+ let letterRect = letter . getBoundingClientRect ( ) ;
39
+
40
+ // create timeline
41
+ const t = new TimelineMax ( ) ;
42
+
43
+ // calc cursor offset
44
+ let offsetTop = cursorRect . top - containerRect . top ;
45
+ let offsetLeft = letterRect . left - containerRect . left ;
46
+
47
+ let scroll = { } ;
48
+
49
+ // vertical scroll
50
+ if ( offsetTop > containerRect . height / 2 ) {
51
+ this . scrolledY += offsetTop / 2 ;
52
+ scroll . y = this . scrolledY ;
53
+ }
54
+
55
+ // horizontal scroll
56
+ if ( offsetLeft > containerRect . width / 2 ) {
57
+ this . scrolledX += offsetLeft / 2 ;
58
+ scroll . x = this . scrolledX ;
59
+ }
60
+ if ( offsetLeft < 0 ) {
61
+ this . scrolledX = 0 ;
62
+ scroll . x = this . scrolledX ;
63
+ }
64
+
65
+ t . set ( pre , { scrollTo : scroll } ) ;
66
+
67
+ // update follow
68
+ t . to ( follow , 0.15 , {
69
+ scaleX : cursorRect . width + 5 ,
70
+ x : cursorRect . left - containerRect . left - 2 ,
71
+ y : cursorRect . top - containerRect . top + 30
30
72
} ) ;
31
73
}
32
74
@@ -79,7 +121,7 @@ export default class SourceCode extends React.Component {
79
121
< span style = { styleByType . no } key = { 1 } >
80
122
{ onCursor . substr ( 0 , typedWord . length ) }
81
123
</ span > ,
82
- < span style = { styleByType . cur } key = { 2 } >
124
+ < span style = { styleByType . cur } key = { 2 } ref = 'letter' >
83
125
{ onCursor . substr ( typedWord . length , 1 ) }
84
126
</ span > ,
85
127
< span style = { styleByType . no } key = { 3 } >
@@ -101,14 +143,14 @@ export default class SourceCode extends React.Component {
101
143
afterCursor = afterCursor . join ( '' ) ;
102
144
103
145
return (
104
- < div className = 'SourceCode' ref = 'box' >
146
+ < div className = 'SourceCode' >
105
147
{ ! this . props . isFinished && (
106
148
< div
107
149
style = { followStyle }
108
150
className = 'follow'
109
151
ref = 'follow' />
110
152
) }
111
- < pre >
153
+ < pre ref = 'pre' >
112
154
< span style = { { color : 'rgba(255, 255, 255, 0.6)' } } > { beforeCursor } </ span >
113
155
< span ref = 'cur' style = { { color : isBad ? 'red' : 'white' } } >
114
156
{ onCursor }
0 commit comments