var evolver = (function(){ setTimeout(init, 10) var opt = { src: "img/test/quad.gif", w: 30, h: 0, population: 10, strokes: 1, randomize: false, mode: 'all', } var hash = window.location.search || window.location.hash if (hash) { hash.substr(1).split("&").forEach(function(s){ var kv = s.split("="), key = kv[0], val = kv[1] switch (key) { case 'w': case 'h': case 'population': case 'strokes': opt[key] = parseInt(val) break case 'randomize': opt.randomize = (val == "true" || val == "1") break case 'src': opt[key] = val break default: if (opt.hasOwnProperty(key)) { opt[key] = val } } }) } var modes = {} modes.gray = 'gray' modes.color = 'solid hue erase random' modes.letter = 'letter random-letter' modes.brush = [modes.gray, modes.color, 'smear clone'].join(" ") modes.magic = 'letter random-letter fill-letter translate scale rotate cycle smear clone' if (opt.mode && opt.mode in modes){ nopaint.disable_all_tools() nopaint.enable_tools( modes[opt.mode].split(" ") ) if (opt.mode == 'magic') { nopaint.tools.translate.opt.weight *= 2 nopaint.tools.cycle.opt.weight *= 3 nopaint.tools.rotate.opt.weight *= 3 nopaint.tools.scale.opt.weight *= 3 } nopaint.regenerate_weights() } console.log(opt) var step = 0 var target, last_score = 0 var clones = [], clone_count = opt.population, strokes_per_iteration = opt.strokes var clone_index = 0 var main_canvas var compare_w = 64, compare_h = 64 var target = document.createElement('canvas') target.width = compare_w target.height = compare_h var t_ctx = target.getContext('2d') var compare = document.createElement('canvas') compare.width = compare_w compare.height = compare_h var c_ctx = compare.getContext('2d') brush.rebuild = function(){ this.initialize() } function init () { nopaint.debug = false load(opt.src, go) } function load(src, fn){ var img = new Image () img.onload = function(){ target = drawImage(t_ctx, img) if (opt.h == 0) { opt.h = Math.round(opt.w * 8/15 * img.naturalHeight/img.naturalWidth) } last_score = 0 ready() } if (src.match(/^http/)) { src = "http://asdf.us/cgi-bin/proxy?" + src } img.src = src } function drawImage (ctx, img) { ctx.drawImage(img, 0, 0, compare_w, compare_h) return { width: compare_w, height: compare_h, data: ctx.getImageData(0,0,compare_w,compare_h).data, channels: 4 } } function ready () { main_canvas = canvas canvas.resize(opt.w, opt.h) for (var i = 0; i < clone_count; i++) { clones[i] = { el: document.createElement("div"), canvas: canvas.clone(), score: 0, hash: -1, } clones[i].canvas.forEach(function(lex){ lex.build = noop }) if (opt.randomize) { clones[i].canvas.forEach(function(lex,x,y){ lex.bg = randint(16) }) } } controls.fg.update = noop controls.bg.update = noop controls.char.update = noop controls.brush_w.build = noop controls.brush_h.build = noop go() } function go () { if (evolver.paused) return step_el.innerHTML = step++ clone_index = 0 paint_next() } function paint_next () { canvas = clones[clone_index].canvas for (var i = 0; i < strokes_per_iteration; i++) { nopaint.paint() } render(canvas, function(c){ compare = drawImage(c_ctx, c) clones[clone_index].score = ImageSSIM.compare(target, compare).ssim if (++clone_index == clone_count) { fitness() changed = false requestAnimationFrame(go) } else { paint_next() } }) } function fitness () { clones.sort(function(a,b){ return b.score - a.score }) var best_clone, next_best_clone, third_best_clone var clones_to_keep var max_score = clones[0].score // console.log(clones.filter(function(c,i){ return i < 10 }).map(function(c){ return c.score.toFixed(2) }).join(" ")) if (max_score < last_score) { console.log("no improvement [%s] [%s]", max_score.toFixed(3), last_score.toFixed(3)) clones_to_keep = 2 best_clone = main_canvas next_best_clone = clones[0].canvas third_best_clone = clones[1].canvas } else { last_score = max_score clones_to_keep = 3 best_clone = clones[0].canvas next_best_clone = clones[1].canvas third_best_clone = clones[2].canvas fitness_el.innerHTML = max_score.toFixed(3) console.log("top clone [%s]", max_score.toFixed(5)) main_canvas.forEach(function(lex,x,y){ lex.assign( best_clone.getCell(x,y) ) }) } var best_clone = clones[0].canvas clones.forEach(function(clone, i){ if (i < clones_to_keep) return var clone_to_copy if (i-clones_to_keep > (clones.length-clones_to_keep) * 0.45) { clone_to_copy = best_clone } else if (i-clones_to_keep > (clones.length-clones_to_keep) * 0.25) { clone_to_copy = next_best_clone } else if (i-clones_to_keep > (clones.length-clones_to_keep) * 0.1) { clone_to_copy = third_best_clone } else { // keep some of the stronger mutants return } clone.canvas.forEach(function(lex,x,y) { lex.assign( clone_to_copy.getCell(x,y) ) }) }) } /* function check () { clipboard.export_canvas(function(canvas){ var hash = simi.hash(canvas) var score = simi.compare(hash, target) if (score > last_score) { last_score = score console.log(score.toFixed(3), "PAINT") nopaint.paint() } else { console.log(score.toFixed(3), "NO") nopaint.no() } requestAnimationFrame(check) }) } */ var buffer_canvas = document.createElement('canvas') function render (canvas, done_fn) { var opts = { palette: 'mirc', font: 'fixedsys_8x15', fg: 0, bg: 1, canvas: buffer_canvas } opts.done = function(c){ done_fn(c) } colorcode.to_canvas(canvas.mirc(), opts) } return { paused: false, pause: function(){ evolver.paused = ! evolver.paused } } })()