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 }) function init () { build() bind() } function build () { canvas = new Matrix (cols, rows, function(x,y){ var lex = new Lex (x,y) // shader(lex, x, y) // 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.canvas_width = new Lex (canvas_width_el) controls.canvas_height = new Lex (canvas_height_el) controls.circle.focus() brush.bg = colors.red brush.generate() brush.build() } function bind () { canvas.forEach(function(lex, x, y){ lex.span.addEventListener('contextmenu', function(e){ e.preventDefault() }) lex.span.addEventListener('mousedown', function(e){ e.preventDefault() dragging = true if (drawing) { erasing = (e.which == "3" || e.ctrlKey) 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, controls.canvas_width, controls.canvas_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() }) controls.canvas_width.key = int_key(function(n, keyCode){ controls.canvas_width.blur() controls.canvas_width.char = ""+n controls.canvas_width.build() brush.w = n brush.rebuild() }) controls.canvas_height.key = int_key(function(n, keyCode){ controls.canvas_height.blur() controls.canvas_height.char = ""+n controls.canvas_height.build() brush.h = n brush.rebuild() }) window.addEventListener('keydown', function(e){ if (! e.metaKey && ! e.ctrlKey && ! e.altKey) { e.preventDefault() } console.log(e.keyCode) switch (e.keyCode) { case 27: // esc if (focused) focused.blur() break case 219: // [ if (! focused && current_tool.name != "text") { brush.contract(1) break } case 221: // ] if (! focused && current_tool.name != "text") { brush.expand(1) 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) { if (erasing) { canvas.aa[t][s].erase(lex) } else { canvas.aa[t][s].clone(lex) } } }) } function clamp (n,a,b){ return n < a ? a : n < b ? n : b } 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()