1- class Painter {
2- constructor ( ctx ) {
3- ctx . strokeStyle = '#BADA55' ;
4- ctx . lineJoin = 'round' ;
5- ctx . lineCap = 'round' ;
6- this . ctx = ctx ;
1+ class Notifier {
2+ constructor ( ) {
3+ this . handlers = [ ] ;
4+ }
75
8- this . MIN_LINE_WIDTH = 1 ;
9- this . MAX_LINE_WIDTH = 100 ;
6+ observe ( handler ) {
7+ this . handlers . push ( handler ) ;
8+ }
109
11- this . isDrawing = false ;
12- this . lastX = this . lastY = 0 ;
13- this . hue = 0 ;
14- this . direction = true ;
10+ fire ( ) {
11+ this . handlers . forEach ( handler => handler ( ) ) ;
1512 }
13+ }
1614
17- draw ( e ) {
18- if ( ! this . isDrawing ) { return ; }
15+ class Painting {
16+ constructor ( lineWidth ) {
17+ this . lineWidth = lineWidth ;
18+ this . lastX = this . lastY = this . hue = 0 ;
19+ this . direction = true ;
20+ this . notifier = new Notifier ( ) ;
21+ }
1922
20- const ctx = this . ctx ;
21- ctx . strokeStyle = `hsl(${ this . hue } , 100%, 50%)` ;
22- ctx . beginPath ( ) ;
23- ctx . moveTo ( this . lastX , this . lastY ) ;
24- ctx . lineTo ( e . offsetX , e . offsetY ) ;
25- ctx . stroke ( ) ;
23+ observe ( handler ) {
24+ this . notifier . observe ( handler ) ;
25+ }
2626
27- [ this . lastX , this . lastY ] = [ e . offsetX , e . offsetY ] ;
27+ draw ( e ) {
28+ this . lastX = e . offsetX ;
29+ this . lastY = e . offsetY ;
2830 this . hue < 360 ? this . hue ++ : this . hue = 0 ;
2931
30- if ( ctx . lineWidth <= this . MIN_LINE_WIDTH || ctx . lineWidth >= this . MAX_LINE_WIDTH ) {
32+ const minLineWidth = 1 ;
33+ const maxLineWidth = 100 ;
34+ if ( this . lineWidth < minLineWidth || this . lineWidth > maxLineWidth ) {
3135 this . direction = ! this . direction ;
3236 }
33- this . direction ? ctx . lineWidth ++ : ctx . lineWidth -- ;
37+ this . direction ? this . lineWidth ++ : this . lineWidth -- ;
38+
39+ this . notifier . fire ( ) ;
40+ }
41+
42+ startDrawing ( e ) {
43+ this . lastX = e . offsetX ;
44+ this . lastY = e . offsetY ;
45+
46+ this . notifier . fire ( ) ;
47+ }
48+ }
49+
50+ class CtxViewModel {
51+ constructor ( ctx ) {
52+ this . painting = new Painting ( ctx . lineWidth ) ;
53+
54+ this . isDrawing = false ;
55+ this . lastX = this . painting . lastX ;
56+ this . lastY = this . painting . lastY ;
57+ this . hue = this . painting . hue ;
58+
59+ this . ctx = ctx ;
60+ this . ctx . lineWidth = 1 ;
61+ this . ctx . lineJoin = 'round' ;
62+ this . ctx . lineCap = 'round' ;
63+ this . ctx . strokeStyle = '#BADA55' ;
64+
65+ // register handler to observer
66+ this . painting . observe ( ( ) => {
67+ this . lastX = this . painting . lastX ;
68+ this . lastY = this . painting . lastY ;
69+ this . ctx . lineWidth = this . painting . lineWidth ;
70+ this . ctx . strokeStyle = `hsl(${ this . painting . hue } , 100%, 50%)` ;
71+ } ) ;
72+ }
73+
74+ draw ( e ) {
75+ if ( ! this . isDrawing ) { return ; }
76+
77+ this . painting . draw ( e ) ;
78+
79+ this . ctx . beginPath ( ) ;
80+ this . ctx . moveTo ( this . lastX , this . lastY ) ;
81+ this . ctx . lineTo ( e . offsetX , e . offsetY ) ;
82+ this . ctx . stroke ( ) ;
3483 }
3584
3685 startDrawing ( e ) {
3786 this . isDrawing = true ;
38- [ this . lastX , this . lastY ] = [ e . offsetX , e . offsetY ] ;
87+ this . painting . startDrawing ( e ) ;
3988 }
4089
4190 stopDrawing ( ) {
@@ -46,10 +95,10 @@ class Painter {
4695const canvas = document . querySelector ( '#draw' ) ;
4796canvas . width = window . innerWidth ;
4897canvas . height = window . innerHeight ;
49- const painter = new Painter ( canvas . getContext ( '2d' ) ) ;
98+ const ctxVm = new CtxViewModel ( canvas . getContext ( '2d' ) ) ;
5099[
51- { eventType : 'mousemove' , callback : e => painter . draw ( e ) } ,
52- { eventType : 'mousedown' , callback : e => painter . startDrawing ( e ) } ,
53- { eventType : 'mouseup' , callback : ( ) => painter . stopDrawing ( ) } ,
54- { eventType : 'mouseout' , callback : ( ) => painter . stopDrawing ( ) }
100+ { eventType : 'mousemove' , callback : e => ctxVm . draw ( e ) } ,
101+ { eventType : 'mousedown' , callback : e => ctxVm . startDrawing ( e ) } ,
102+ { eventType : 'mouseup' , callback : ( ) => ctxVm . stopDrawing ( ) } ,
103+ { eventType : 'mouseout' , callback : ( ) => ctxVm . stopDrawing ( ) }
55104] . forEach ( ( { eventType, callback} ) => canvas . addEventListener ( eventType , callback ) ) ;
0 commit comments