asciiblaster- draw irc art in your web browser |
| git clone git://git.acid.vegas/asciiblaster.git |
| Log | Files | Refs | Archive | README |
matrix.js (7932B)
1 function Matrix (w,h,f){ 2 this.x = 0 3 this.y = 0 4 this.w = w 5 this.h = h 6 this.f = f 7 this.focus_x = 0 8 this.focus_y = 0 9 this.initialize() 10 } 11 Matrix.prototype.initialize = function(f){ 12 var w = this.w || 1, h = this.h || 1, f = f || this.f 13 var aa = new Array (h) 14 for (var y = 0; y < h; y++) { 15 aa[y] = new Array (w) 16 for (var x = 0; x < w; x++) { 17 aa[y][x] = f(x,y) 18 } 19 } 20 this.aa = aa 21 } 22 Matrix.prototype.rebuild = function (){ 23 this.demolish() 24 this.initialize() 25 this.append() 26 this.bind() 27 this.generate && this.generate() 28 this.focus_clamp() 29 check_if_lost_focus() 30 } 31 Matrix.prototype.clone = function () { 32 var base = this 33 var clone = new Matrix(this.w, this.h, function(x,y){ 34 return base.getCell(x,y).clone() 35 }) 36 clone.f = this.f 37 return clone 38 } 39 Matrix.prototype.assign = function (mat) { 40 var base = this 41 this.demolish() 42 this.w = mat.w 43 this.h = mat.h 44 // this.f = function(){} 45 this.initialize(function(x,y){ 46 var el = mat.getCell(x,y).clone() 47 el.build() 48 return el 49 }) 50 this.append() 51 this.bind() 52 check_if_lost_focus() 53 return this 54 } 55 56 Matrix.prototype.bind = function () {} 57 Matrix.prototype.demolish = function (){ 58 this.forEach(function(lex){ 59 lex.demolish() 60 }) 61 while (this.rapper && this.rapper.firstChild) { 62 this.rapper.removeChild(this.rapper.firstChild); 63 } 64 this.aa.forEach(function(row){ 65 row.length = 0 66 }) 67 this.aa.length = 0 68 } 69 Matrix.prototype.forEach = function(f){ 70 this.aa.forEach(function(row, y){ 71 row.forEach(function(lex, x){ 72 f(lex, x, y) 73 }) 74 }) 75 } 76 Matrix.prototype.focus_clamp = function(){ 77 this.focus_x = clamp(this.focus_x, 0, this.w - 1) 78 this.focus_y = clamp(this.focus_y, 0, this.h - 1) 79 } 80 Matrix.prototype.focus_add = function(x, y){ 81 this.focus(this.focus_x + x, this.focus_y + y) 82 } 83 Matrix.prototype.focus = function(x, y){ 84 if (x === undefined) x = this.focus_x 85 if (y === undefined) y = this.focus_y 86 x = mod(x, this.w) 87 y = mod(y, this.h) 88 this.focus_x = x 89 this.focus_y = y 90 91 //focused_input = this 92 this.aa[y][x].focus() 93 } 94 Matrix.prototype.focusLex = function(y,x){ 95 if (x < 0) { 96 y -= 1 97 } 98 if (x > this.aa[0].length) { 99 y += 1 100 } 101 this.aa[mod(y,this.h)][mod(x,this.w)].focus() 102 } 103 Matrix.prototype.clear = function(){ 104 this.forEach(function(lex,x,y){ lex.clear() }) 105 } 106 Matrix.prototype.erase = function(){ 107 this.forEach(function(lex,x,y){ lex.erase() }) 108 } 109 Matrix.prototype.fill = function(lex){ 110 this.fg = lex.fg 111 this.bg = lex.bg 112 this.char = lex.char 113 this.opacity = lex.opacity 114 this.forEach(function(el,x,y){ 115 el.assign(lex) 116 el.build() 117 }) 118 } 119 120 Matrix.prototype.build = function(){ 121 this.forEach(function(lex,x,y){ 122 lex.build() 123 }) 124 } 125 Matrix.prototype.append = function(rapper){ 126 rapper = this.rapper = rapper || this.rapper 127 if (! this.rapper) return 128 this.aa.forEach(function(row, y){ 129 var div = document.createElement("div") 130 row.forEach(function(lex, x) { 131 div.appendChild(lex.span) 132 }) 133 rapper.appendChild( div ) 134 }) 135 } 136 Matrix.prototype.region = function(w,h,x,y) { 137 w = w || 1 138 h = h || 1 139 x = x || 0 140 y = y || 0 141 var parent = this 142 var mat = new Matrix(w, h, function(x,y){ 143 return parent.aa[y][x] 144 }) 145 mat.f = this.f 146 return mat 147 } 148 Matrix.prototype.setCell = function(lex,x,y){ 149 this.aa[y] && this.aa[y][x] && this.aa[y][x].assign(lex) 150 } 151 Matrix.prototype.getCell = function(x,y){ 152 if (this.aa[y] && this.aa[y][x]) return this.aa[y][x] 153 else return null 154 } 155 Matrix.prototype.get = function(x,y){ 156 y = floor(mod(y || 0, this.h)) 157 x = floor(mod(x || 0, this.w)) 158 if (this.aa[y] && this.aa[y][x]) return this.aa[y][x] 159 else return null 160 } 161 162 Matrix.prototype.resize = function(w,h){ 163 w = w || canvas.w 164 h = h || canvas.h 165 var div, row, lex 166 var f = this.f, old_h = this.aa.length, old_w = this.aa[0].length 167 var rapper = this.rapper 168 w = max(w, 1) 169 h = max(h, 1) 170 if (h < old_h) { 171 for (var y = old_h; y > h; y--) { 172 row = this.aa.pop() 173 div = row[0].span.parentNode 174 row.forEach(function(lex, x){ 175 lex.demolish() 176 }) 177 div.parentNode.removeChild(div) 178 } 179 } 180 else if (h > old_h) { 181 for (var y = old_h; y < h; y++) { 182 div = document.createElement("div") 183 rapper.appendChild( div ) 184 this.aa[y] = new Array (w) 185 for (var x = 0; x < w; x++) { 186 lex = this.aa[y][x] = f(x,y) 187 div.appendChild(lex.span) 188 } 189 } 190 } 191 192 if (w < old_w) { 193 this.aa.forEach(function(row, y){ 194 while (row.length > w) { 195 lex = row.pop() 196 lex.demolish() 197 } 198 }) 199 } 200 else if (w > old_w) { 201 this.aa.forEach(function(row, y){ 202 div = row[0].span.parentNode 203 for (var x = row.length; x < w; x++) { 204 lex = row[x] = f(x,y) 205 div.appendChild(lex.span) 206 } 207 }) 208 } 209 210 this.w = w 211 this.h = h 212 this.bind && this.bind() 213 this.focus_clamp() 214 if (this.rapper && this.rapper.parentNode != document.body) { 215 this.resize_rapper() 216 } 217 } 218 Matrix.prototype.resize_rapper = function(){ 219 var cell = canvas.aa[0][0].span 220 var cw = cell.offsetWidth 221 var ch = cell.offsetHeight 222 // if (canvas.grid) { ch++ } 223 var width = cw * this.aa[0].length 224 var height = ch * this.aa.length 225 if (canvas.grid) { width++; height++ } 226 if (this.rotated) { 227 this.rapper.parentNode.classList.add("rotated") 228 this.rapper.parentNode.style.height = (width) + "px" 229 this.rapper.parentNode.style.width = (height) + "px" 230 this.rapper.style.top = (width/2) + "px" 231 // this.rapper.style.left = ((canvas_rapper.offsetHeight+20)/2) + "px" 232 } 233 else { 234 this.rapper.parentNode.classList.remove("rotated") 235 this.rapper.parentNode.style.height = "" 236 this.rapper.style.width = 237 this.rapper.parentNode.style.width = (width) + "px" 238 this.rapper.style.top = "" 239 // canvas_rapper.style.left = "auto" 240 } 241 } 242 Matrix.prototype.ascii = function () { 243 var lines = this.aa.map(function(row, y){ 244 var last, line = "" 245 row.forEach(function(lex, x) { 246 line += lex.ascii() 247 }) 248 return line // .replace(/\s+$/,"") 249 }) 250 var txt = lines.join("\n") 251 return txt 252 } 253 Matrix.prototype.ansi = function (opts) { 254 var lines = this.aa.map(function(row, y){ 255 var last, line = "" 256 row.forEach(function(lex, x) { 257 if (lex.eqColor(last)) { 258 line += lex.sanitize() 259 } 260 else { 261 line += lex.ansi() 262 last = lex 263 } 264 }) 265 return line 266 }) 267 var txt = lines.filter(function(line){ return line.length > 0 }).join('\\e[0m\\n') + "\\e[0m" 268 return 'echo -e "' + txt + '"' 269 } 270 Matrix.prototype.mirc = function (opts) { 271 var cutoff = false 272 var lines = this.aa.map(function(row, y){ 273 var last, line = "" 274 row.forEach(function(lex, x) { 275 if (lex.eqColor(last)) { 276 line += lex.sanitize() 277 } 278 else { 279 line += lex.mirc() 280 last = lex 281 } 282 }) 283 if (opts && opts.cutoff && line.length > opts.cutoff) { 284 cutoff = true 285 return line.substr(0, opts.cutoff) 286 } 287 return line 288 }) 289 290 var txt = lines.filter(function(line){ return line.length > 0 }).join('\n') 291 292 if (cutoff) { 293 txt = new String(txt) 294 txt.cutoff = true 295 } 296 return txt 297 } 298 Matrix.prototype.irssi = function(opts){ 299 var mirc = this.mirc(opts) 300 var txt = mirc 301 // .replace(/\%/g, '%%') 302 .replace(/\\/g, '\\x5C') 303 .replace(/\"/g, '\\\"') 304 // .replace(/\'/g, '\\\'') 305 .replace(/\`/g, '\\\`') 306 .replace(/\$/g, '\\$') 307 // .replace(/\n\s+/g, '\n') 308 // .replace(/\s+$/g, '\n') 309 // .replace(/^\n+/, '') 310 .replace(/\n/g, '\\n') 311 .replace(/\x02/g, '\\x02') 312 .replace(/\x03/g, '\\x03') 313 314 txt = unicode.escapeToEscapedBytes(txt) 315 txt = '/exec -out printf "%b" "' + txt + '"\n' 316 if (mirc.cutoff){ 317 txt = new String(txt) 318 txt.cutoff = true 319 } 320 return txt 321 }

