6 */ |
6 */ |
7 |
7 |
8 'use strict'; |
8 'use strict'; |
9 |
9 |
10 var PIXI = require('pixi'); |
10 var PIXI = require('pixi'); |
11 var randomColor = require('randomColor'); |
11 var _ = require('lodash'); |
12 |
12 |
13 function AnnotsRoll(parentContainer, xInit, yInit, width, height, widthRoll, pixelsPerSecond, annotColors, lineInterval){ |
13 // |
|
14 // |
|
15 // |
|
16 // options = { |
|
17 // parentContainer:, |
|
18 // externalRefresh: true/false |
|
19 // ws:, |
|
20 // xInit:, |
|
21 // yInit:, |
|
22 // width:, |
|
23 // height:, |
|
24 // widthRoll:, |
|
25 // pixelsPerSecond:, |
|
26 // framerate:, |
|
27 // annotColors: [{ts: , colors: {code1 : '#dshdsj', code2: 'sdasd', 'default': 'dsadas'}}], |
|
28 // defaultColor: default, |
|
29 // annotStyles: { |
|
30 // 'label': {font:, fill:}, |
|
31 // 'text':{font:, fill:}, |
|
32 // 'user':{font:, fill:}, |
|
33 // } |
|
34 // } |
|
35 var DEFAULT_ANNOT_COLOR = '#bababa'; |
|
36 |
|
37 var defaultAnnotStyles = { |
|
38 'label': { font: '26pt Arial Bold', fill: '#65A954' }, |
|
39 'text' : { font: '20pt Arial Regular', fill: '#444444' }, |
|
40 'user' : { font: '22pt Arial regular', fill: '#444444' }, |
|
41 }; |
|
42 |
|
43 var defaultOptions = { |
|
44 externalRefresh: false, |
|
45 defaultColor: DEFAULT_ANNOT_COLOR, |
|
46 annotStyles: defaultAnnotStyles |
|
47 }; |
|
48 |
|
49 function AnnotsRoll(options) { |
|
50 |
|
51 //parentContainer, xInit, yInit, width, height, widthRoll, pixelsPerSecond, annotColors |
14 var _this = this; |
52 var _this = this; |
|
53 var opts = _(options).defaults(defaultOptions).value(); |
|
54 |
|
55 |
15 this.container = new PIXI.DisplayObjectContainer(); |
56 this.container = new PIXI.DisplayObjectContainer(); |
16 this.container.position.x = xInit; |
57 this.container.x = opts.xInit; |
17 this.container.position.y = yInit; |
58 this.container.y = opts.yInit; |
18 this.container.width = width; |
59 this.container.width = opts.width; |
19 parentContainer.addChild(this.container); |
60 opts.parentContainer.addChild(this.container); |
20 |
61 |
21 this.height = height; |
62 this.height = opts.height; |
22 this.width = width; |
63 this.width = opts.width; |
23 this.widthRoll = widthRoll; |
64 this.widthRoll = opts.widthRoll; |
24 this.pixelsPerSecond = pixelsPerSecond; |
65 this.pixelsPerSecond = opts.pixelsPerSecond; |
25 this.lineInterval = lineInterval; |
66 this.annotColors = opts.annotColors; |
26 |
67 this.startTs = options.startTs || Date.now(); |
27 this.addAnnot = function(category, user, catColor){ |
68 |
28 var graphics = new PIXI.Graphics(); |
69 var yInit = opts.yInit; |
29 var color = catColor; |
70 var annotStyles = _(opts.annotStyles).defaults(defaultAnnotStyles).value(); |
30 var x = 0; |
71 var started = false; |
31 var y = -this.container.y; |
72 var ws = opts.ws; |
32 graphics.beginFill(color); |
73 var externalRefresh = opts.externalRefresh; |
33 graphics.drawRect(x, y, 10, 3); |
74 |
34 graphics.endFill(); |
75 |
35 |
76 var isHidden = function(child) { |
|
77 // TODO: the origin point is an approximation. Should refine this |
|
78 var globalPos = child.toGlobal(new PIXI.Point(0,0)); |
|
79 return ((globalPos.x + child.width) < 0) || ((globalPos.y + child.height) < 0) ; |
|
80 }; |
|
81 |
|
82 this.addAnnots = function(data) { |
|
83 |
|
84 //var title = data.content.category.label; |
|
85 //var user = data.content.user; |
|
86 //Test cat and color |
|
87 //var colorAnnot = 0x65A954; |
|
88 var category = data.content.category.label, |
|
89 text = data.content.text, |
|
90 user = data.content.user, |
|
91 ts = Date.parse(data.ts), |
|
92 color = this.getColor(ts, data.content.category.code); |
|
93 |
|
94 this.addAnnot(category, text, user, color, ts); |
|
95 }; |
|
96 |
|
97 this.getColor = function(ts, code) { |
|
98 var colorsDef; |
|
99 _(this.annotColors).eachRight(function(cdef) { |
|
100 console.log("cDef", cdef); |
|
101 console.log("cDef ts", cdef.ts, ts); |
|
102 if(cdef.ts < ts) { |
|
103 colorsDef = cdef.colors; |
|
104 return false; |
|
105 } |
|
106 }); |
|
107 var resColor; |
|
108 console.log("colorsDef", colorsDef); |
|
109 if(colorsDef) { |
|
110 resColor = colorsDef[code]; |
|
111 } |
|
112 if(!resColor) { |
|
113 resColor = DEFAULT_ANNOT_COLOR; |
|
114 } |
|
115 return resColor; |
|
116 } |
|
117 |
|
118 this.addAnnot = function(category, text, user, catColor, ts){ |
|
119 |
|
120 var color = catColor ? catColor : DEFAULT_ANNOT_COLOR; |
|
121 var x = 0; |
|
122 var y = (ts-this.startTs) * this.pixelsPerSecond / 1000 + yInit; |
|
123 |
|
124 var colorHex = parseInt(color.replace(/^#/, ''), 16); |
|
125 |
|
126 var graphics = new PIXI.Graphics() |
|
127 .beginFill(colorHex) |
|
128 .drawRect(x, y, 10, 3) |
|
129 .endFill(); |
|
130 |
36 this.container.addChild(graphics); |
131 this.container.addChild(graphics); |
37 |
132 |
38 var catText = new PIXI.Text(category, { font: '16pt Arial', fill: '#65A954' }); |
133 var catLabel = new PIXI.Text( |
39 catText.x = x + 20; |
134 category, |
40 catText.y = y - 23; |
135 _(annotStyles.label).extend({fill: color}).value() |
41 this.container.addChild(catText); |
136 ); |
42 |
137 catLabel.x = x + 20; |
43 var userText = new PIXI.Text(user, { font: '10pt Arial', fill: '#444444' }); |
138 catLabel.y = y - 23; |
44 userText.x = x + 20; |
139 this.container.addChild(catLabel); |
45 userText.y = y + 2; |
140 |
46 this.container.addChild(userText); |
141 var textHeight = 0; |
47 |
142 if(text) { |
48 this.addAnnotLine(color) |
143 var catText = new PIXI.Text(text, annotStyles.text); |
49 }; |
144 catText.x = x + 20; |
50 |
145 catText.y = y + 2; |
51 this.addAnnotLine = function(color){ |
146 this.container.addChild(catText); |
52 var x = this.widthRoll; |
147 textHeight += (catText.height + 2); |
53 var y = -this.container.y; |
148 } |
54 |
149 |
55 var graphics = new PIXI.Graphics(); |
150 var catUser = new PIXI.Text(user, annotStyles.user); |
56 |
151 catUser.x = x + 20; |
57 graphics.beginFill(color); |
152 catUser.y = y + 2 + textHeight; |
58 graphics.drawRect(x, y, this.width - x, 3); |
153 this.container.addChild(catUser); |
59 graphics.endFill(); |
154 |
60 |
155 this.addAnnotLine(colorHex, y); |
|
156 }; |
|
157 |
|
158 this.addAnnotLine = function(color, y) { |
|
159 var x = this.widthRoll; |
|
160 |
|
161 |
|
162 var graphics = new PIXI.Graphics() |
|
163 .beginFill(color) |
|
164 .drawRect(x, y, this.width - x, 3) |
|
165 .endFill(); |
|
166 |
61 this.container.addChild(graphics); |
167 this.container.addChild(graphics); |
62 }; |
168 }; |
63 |
169 |
64 this.moveTo = function(diffTime){ |
170 this.moveTo = function(diffTime){ |
65 this.container.y = Math.floor(diffTime*this.pixelsPerSecond); |
171 this.container.y = Math.floor(diffTime*this.pixelsPerSecond); |
66 }; |
172 }; |
67 |
173 |
|
174 this.move = this.refresh = function() { |
|
175 var diff = (this.startTs - Date.now())/1000; |
|
176 this.moveTo(diff); |
|
177 }; |
|
178 |
68 this.removePassedObjets = function(){ |
179 this.removePassedObjets = function(){ |
69 var nbChilds = _this.container.children.length; |
180 var childrenToRemove = []; |
70 var i = 0, childIsNowDisplayed = false, childrenToRemove = []; |
181 _(_this.container.children).forEach(function(child) { |
71 while(i<nbChilds && !childIsNowDisplayed){ |
182 return typeof(child) === 'undefined' || |
72 var child = _this.container.children[i++]; |
183 (isHidden(child) && childrenToRemove.push(child)); |
73 |
184 }); |
74 if(typeof(child) == 'undefined') { |
|
75 continue; |
|
76 } |
|
77 if((child.y + child.height) < (Math.abs(_this.container.y) - _this.height)){ |
|
78 childrenToRemove.push(child); |
|
79 } |
|
80 else { |
|
81 childIsNowDisplayed = true; |
|
82 } |
|
83 } |
|
84 childrenToRemove.forEach(function(child) { |
185 childrenToRemove.forEach(function(child) { |
85 _this.container.removeChild(child); |
186 _this.container.removeChild(child); |
86 }); |
187 }); |
87 }; |
188 }; |
88 |
189 |
89 window.setInterval(this.removePassedObjets, 1000 * this.height / this.pixelsPerSecond ); |
190 this.init = function() { |
|
191 |
|
192 ws.message(function(data) { |
|
193 _this.addAnnots(data); |
|
194 }); |
|
195 |
|
196 }; |
|
197 |
|
198 |
|
199 this.start = function() { |
|
200 if(!started) { |
|
201 this.startTs = Date.now(); |
|
202 started = true; |
|
203 } |
|
204 this.cleanInterval = setInterval(function () { _this.removePassedObjets(); }, 1000 * this.height / this.pixelsPerSecond ); |
|
205 if(!externalRefresh) { |
|
206 this.refreshInterval = setInterval(function() {_this.move();}, 1000/this.framerate); |
|
207 } |
|
208 }; |
|
209 |
|
210 this.stop = function() { |
|
211 clearInterval(this.cleanInterval); |
|
212 if(!externalRefresh) { |
|
213 clearInterval(this.refreshInterval); |
|
214 } |
|
215 }; |
90 |
216 |
91 } |
217 } |
92 |
218 |
93 module.exports = AnnotsRoll; |
219 module.exports = { |
|
220 AnnotsRoll: AnnotsRoll, |
|
221 }; |