var contentType = 'text/plain;charset=utf-8' var cols = 80 var rows = 24 var dragging = false var drawing = true var erasing = false var focused var canvas, tools, palette, brush, mode, current_tool var color_names = ("white black dark-blue green red dark-red purple orange" + "yellow lime dark-cyan cyan blue magenta dark-gray light-gray").split(" "); var letters = "abcdefghijklmnop"; var colors = {}, controls = {} color_names.forEach(function(name, i){ colors[name] = i }) // var tools = "square circle rectangle" function init () { build() bind() } function build () { canvas = new Matrix (cols, rows, function(x,y){ var lex = new Lex (x,y) if (x > y || y > x + 20 || x > y / 4 + 10) { lex.clear() } else { lex.bg = x+y*y lex.fg = (x+y)%2 lex.char = ":" } lex.build() return lex }) brush = new Matrix (5, 5, function(x,y){ var lex = new Lex (x,y) lex.build() return lex }) palette = new Matrix (32, 2, function(x,y){ var lex = new Lex (x,y) lex.bg = y>>1 lex.build() return lex }) canvas.append(canvas_rapper) brush.append(brush_rapper) palette.append(palette_rapper) controls.circle = new Tool (circle_el) controls.circle.use = function(){ brush.generate = controls.circle.generate brush.generate() drawing = true } controls.circle.generate = function(){ var fg = brush.fg, bg = brush.bg var hw = brush.w/2|0, hh = brush.h/2|0 brush.forEach(function(lex,x,y) { var len = Math.sqrt(Math.pow(x-hw,2)+Math.pow(y-hh,2)) if (len > Math.abs(hw)) { lex.clear() } else { lex.fill(fg,bg) } }) } controls.square = new Tool (square_el) controls.square.use = function(){ brush.generate = controls.square.generate brush.generate() drawing = true } controls.square.generate = function(){ var fg = brush.fg, bg = brush.bg brush.fill(fg,bg) } controls.text = new Tool (text_el) controls.text.use = function(){ brush.generate = controls.text.generate brush.generate() drawing = false } controls.text.generate = function(){ } controls.width = new Lex (width_el) controls.height = new Lex (height_el) controls.circle.focus() brush.bg = colors.red brush.generate() brush.build() } function bind () { canvas.forEach(function(lex, x, y){ lex.span.addEventListener('mousedown', function(e){ e.preventDefault() dragging = true if (drawing) { erasing = e.which == "3" draw(lex, x, y, erasing) } else { lex.focus() } }) lex.span.addEventListener("mousemove", function(){ if (! dragging) return if (drawing) { draw(lex, x, y, erasing) } else { lex.focus() } }) }) palette.forEach(function(lex, x, y){ lex.span.addEventListener('mousedown', function(e){ e.preventDefault() dragging = true erasing = e.which == "3" brush.fg = lex.fg brush.bg = lex.bg brush.generate() }) }) brush.forEach(function(lex, x, y){ lex.span.addEventListener('mousedown', function(e){ e.preventDefault() dragging = true // lex.fill(lex.fg, lex.bg) }) }) window.addEventListener('mouseup', function(){ dragging = erasing = false }); [controls.width, controls.height].forEach(function(lex){ lex.span.addEventListener('mousedown', function(e){ lex.focus() }) }); [controls.square, controls.circle, controls.text].forEach(function(tool){ tool.span.addEventListener('mousedown', function(e){ tool.focus() }) }) controls.width.key = int_key(function(n, keyCode){ controls.width.blur() controls.width.char = ""+n controls.width.build() brush.w = n brush.rebuild() }) controls.height.key = int_key(function(n, keyCode){ controls.height.blur() controls.height.char = ""+n controls.height.build() brush.h = n brush.rebuild() }) window.addEventListener('keydown', function(e){ if (! e.metaKey && ! e.ctrlKey && ! e.altKey) { e.preventDefault() } switch (e.keyCode) { case 27: // esc if (focused) focused.blur() break default: if (focused) focused.key(String.fromCharCode(e.keyCode), e.keyCode) break } }) } function int_key (f) { return function (key, keyCode) { var n = parseInt(key) n && f(n) } } function draw (lex, x, y, erasing) { stamp (canvas, brush, x, y, erasing) } function stamp (canvas, brush, x, y, erasing) { hh = brush.w/2|0 brush.forEach(function(lex, s, t){ s += x-hh t += y-hh if (s >= 0 && s < canvas.w && t >= 0 && t < canvas.h) { canvas.aa[t][s].clone(lex) } }) } function mod (i,n) { return i - n * Math.floor(i / n) } document.body.addEventListener('copy', function (e) { if (e.clipboardData) { e.preventDefault(); e.clipboardData.setData(contentType, canvas.ascii()); } if (window.clipboardData) { e.returnValue = false; window.clipboardData.setData(contentType, canvas.ascii()); } }, false); init()