asciiblaster

- draw irc art in your web browser
git clone git://git.acid.vegas/asciiblaster.git
Log | Files | Refs | Archive | README

draw.js (6028B)

      1 
      2 var draw = (function(){
      3 
      4   var last_point = [0,0]
      5   
      6   function down (e, lex, point) {
      7     var w = canvas.w, h = canvas.h
      8     erasing = (e.which == "3" || e.ctrlKey)
      9     changed = true
     10     if (e.shiftKey) {
     11       line (lex, last_point, point, erasing)
     12       if (mirror_x) {
     13         line(lex, [w-last_point[0], last_point[1]], [w-point[0], point[1]], erasing)
     14       }
     15       if (mirror_y) {
     16         line(lex, [last_point[0], h-last_point[1]], [point[0], h-point[1]], erasing)
     17       }
     18       if (mirror_x && mirror_y) {
     19         line(lex, [w-last_point[0], h-last_point[1]], [w-point[0], h-point[1]], erasing)
     20       }
     21     }
     22     else {
     23       stamp (canvas, brush, point[0], point[1], erasing)
     24       if (mirror_x) {
     25         stamp (canvas, brush, w-point[0], point[1], erasing)
     26       }
     27       if (mirror_y) {
     28         stamp (canvas, brush, point[0], h-point[1], erasing)
     29       }
     30       if (mirror_x && mirror_y) {
     31         stamp (canvas, brush, w-point[0], h-point[1], erasing)
     32       }
     33     }
     34     last_point[0] = point[0]
     35     last_point[1] = point[1]
     36   }
     37   
     38   function set_last_point (e, point) {
     39     last_point[0] = point[0]
     40     last_point[1] = point[1]
     41   }
     42   
     43   function move (e, lex, point) {
     44     var w = canvas.w, h = canvas.h
     45     line(lex, last_point, point, erasing)
     46     if (mirror_x) {
     47       line(lex, [w-last_point[0], last_point[1]], [w-point[0], point[1]], erasing)
     48     }
     49     if (mirror_y) {
     50       line(lex, [last_point[0], h-last_point[1]], [point[0], h-point[1]], erasing)
     51     }
     52     if (mirror_x && mirror_y) {
     53       line(lex, [w-last_point[0], h-last_point[1]], [w-point[0], h-point[1]], erasing)
     54     }
     55 
     56     last_point[0] = point[0]
     57     last_point[1] = point[1]
     58   }
     59   
     60   function move_toroidal (e, lex, point) {
     61     var w = canvas.w, h = canvas.h
     62     var src_x_quantile = quantile( last_point[0], w )
     63     var src_y_quantile = quantile( last_point[1], h )
     64     var dst_x_quantile = quantile( point[0], w )
     65     var dst_y_quantile = quantile( point[1], h )
     66     var src_x_mod = mod( last_point[0], w )
     67     var src_y_mod = mod( last_point[1], h )
     68     var dst_x_mod = mod( point[0], w )
     69     var dst_y_mod = mod( point[1], h )
     70     // if we've moved across the edge of the board, draw two lines
     71     if (src_x_quantile != dst_x_quantile || src_y_quantile != dst_y_quantile) {
     72       var xa, ya
     73       if (src_x_quantile < dst_x_quantile) {
     74         xa = [
     75           [src_x_mod, dst_x_mod + w],
     76           [src_x_mod-w, dst_x_mod],
     77         ]
     78       }
     79       else if (src_x_quantile == dst_x_quantile) {
     80         xa = [
     81           [src_x_mod, dst_x_mod],
     82           [src_x_mod, dst_x_mod],
     83         ]
     84       }
     85       else {
     86         xa = [
     87           [src_x_mod, dst_x_mod-w],
     88           [src_x_mod+w, dst_x_mod],
     89         ]
     90       }
     91 
     92       if (src_y_quantile < dst_y_quantile) {
     93         ya = [
     94           [src_y_mod, dst_y_mod + h],
     95           [src_y_mod-h, dst_y_mod],
     96         ]
     97       }
     98       else if (src_y_quantile == dst_y_quantile) {
     99         ya = [
    100           [src_y_mod, dst_y_mod],
    101           [src_y_mod, dst_y_mod],
    102         ]
    103       }
    104       else {
    105         ya = [
    106           [src_y_mod, dst_y_mod-h],
    107           [src_y_mod+h, dst_y_mod],
    108         ]
    109       }
    110       line(lex, [ xa[0][0], ya[0][0] ], [ xa[0][1], ya[0][1] ], erasing)
    111       line(lex, [ xa[1][0], ya[1][0] ], [ xa[1][1], ya[1][1] ], erasing)
    112     }
    113     else {
    114       var x_a = mod( last_point[0], w )
    115       var y_a = mod( last_point[1], h )
    116       var x_b = mod( point[0], w )
    117       var y_b = mod( point[1], h )
    118       var last_point_mod = [x_b, y_b], point_mod = [x_a, y_a]
    119       line(lex, last_point_mod, point_mod, erasing)
    120       // if (mirror_x) {
    121       //   line(lex, [w-last_point_mod[0], last_point_mod[1]], [w-point_mod[0], point_mod[1]], erasing)
    122       // }
    123       // if (mirror_y) {
    124       //   line(lex, [last_point_mod[0], h-last_point_mod[1]], [point_mod[0], h-point_mod[1]], erasing)
    125       // }
    126     }
    127     last_point[0] = point[0]
    128     last_point[1] = point[1]
    129     // y = point.y
    130   }
    131   
    132   function point (lex, x, y, erasing) {
    133     stamp (canvas, brush, x, y, erasing)
    134   }
    135 
    136   function line (lex, a, b, erasing) {
    137     var len = dist(a[0], a[1], b[0], b[1])
    138     var bw = 1
    139     var x, y, i;
    140     for (var i = 0; i <= len; i += bw) {
    141       x = lerp(i / len, a[0], b[0])
    142       y = lerp(i / len, a[1], b[1])
    143       stamp (canvas, brush, x, y, erasing)
    144     }
    145   }
    146 
    147   function stamp (canvas, brush, x, y, erasing) {
    148     var hh = brush.w/2|0
    149     brush.forEach(function(lex, s, t){
    150       s = round( s + x-hh )
    151       t = round( t + y-hh )
    152       if (s >= 0 && s < canvas.w && t >= 0 && t < canvas.h) {
    153         if (lex.opacity === 0 && lex.char === ' ') return;
    154         var aa = canvas.aa[t][s]
    155         undo.save_lex(s, t, aa)
    156         if (erasing) {
    157           aa.erase(lex)
    158         }
    159         else {
    160           aa.stamp(lex, brush)
    161         }
    162       }
    163     })
    164   }
    165   
    166   function fill (lex, x, y) {
    167     var q = [ [x,y] ]
    168     var aa = canvas.aa
    169     var target = aa[y][x].clone()
    170     var n, w = 0, e = 0, j = 0
    171     var kk = 0
    172     // gets into a weird infinite loop if we don't break here.. :\
    173     if (target.eq(lex)) { return }
    174     LOOP: while (q.length) {
    175       n = q.shift()
    176       if (aa[n[1]][n[0]].ne(target)) {
    177         continue LOOP
    178       }
    179       w = e = n[0]
    180       j = n[1]
    181       WEST: while (w > 0) {
    182         if (aa[j][w-1].eq(target)) {
    183           w = w-1
    184         }
    185         else {
    186           break WEST
    187         }
    188       }
    189       EAST: while (e < canvas.w-1) {
    190         if (aa[j][e+1].eq(target)) {
    191           e = e+1
    192         }
    193         else {
    194           break EAST
    195         }
    196       }
    197       for (var i = w; i <= e; i++) {
    198         undo.save_lex(i, j, aa[j][i])
    199         aa[j][i].assign(lex)
    200         if (j > 0 && aa[j-1][i].eq(target)) {
    201           q.push([ i, j-1 ])
    202         }
    203         if (j < canvas.h-1 && aa[j+1][i].eq(target)) {
    204           q.push([ i, j+1 ])
    205         }
    206       }
    207     }
    208   }
    209 
    210   var draw = {}
    211   draw.down = down
    212   draw.set_last_point = set_last_point
    213   draw.move = move
    214   draw.move_toroidal = move_toroidal
    215   draw.stamp = stamp
    216   draw.line = line
    217   draw.point = point
    218   draw.fill = fill
    219   return draw
    220 
    221 })()